20210103のUnityに関する記事は6件です。

【Unity 物理エンジン】リジッドボディ(Rigidbody)とは【超訳 Unity チュートリアル】

概要

この記事は、

Unity Learn の公開している英語のチュートリアルを、日本の学習者のために超訳する」

というシリーズものです。

今回の記事は他の記事を読んでいなくても問題ありません)


今回は、

Unity 物理エンジンのリジッドボディIntro to the Unity Physics Engine - Unity Learn

についてです。


Unityバージョン:Unity 2019.4.14f1
使用言語:C#

本論

Rigidbody コンポーネント(図04)を使うと、ゲームオブジェクトが重力などの物理プロパティの影響を受けるようになります。

物理プロパティには、重力の他に Mass (質量)や Velocity (速度)、 Drag (抗力(空気抵抗))も含まれています。

質量の大きいゲームオブジェクトは、質量の小さいゲームオブジェクトの影響を受けにくく、その逆もまた然りです。

Drag (抗力)は時間の経過とともに速度を減衰させ、Angular Drag (回転抗力)は角速度を減衰させます。
rigidbody_1.png


Is Kinematic を有効にすることで、Rigidbody が Unity 物理エンジンで他のゲームオブジェクトに影響を与えるようになりますが、その Rigidbody 自身は影響を受けなくなります。

例えば、VR ゲームのハンドアバター(VR 空間上にある手のアバター)は、ゲームオブジェクトに対して物理的な働きかけができますが、ハンドアバター自体に物理的な影響はありません。


Is Kinematic はアニメーションエンジンによって制御されるゲームオブジェクトにも影響があります。

Is Kinematic が有効のとき、アニメーションエンジンはゲームオブジェクトに影響を及ぼすようになるのです。

Is Kinematic が有効でないときは、ゲームオブジェクトはアニメーションエンジンから影響を受けず、物理エンジンに制御されます。


Interpolate (補間)は衝突のチェック方法を検出します。

ドロップダウンメニューからInterpolateまたはExtrapolateを選びます。

  • None: デフォルト
  • Interpolate: アニメーションのタイムラインの前のフレーム情報を元に、ゲームオブジェクトのスムーズな動きを表現する
  • Extrapolate: アニメーションのタイムラインの次のフレームを推測することで、ゲームオブジェクトのスムーズな動きを表現する

Collision Detectionのドロップダウンメニューでは、衝突をチェックする割合を設定することができます。

  • Discrete: デフォルト
  • Continuous: 静的なゲームオブジェクトと相互作用する高速なオブジェクト
  • Continuous Dymanic: 他の高速なゲームオブジェクトと相互作用する高速なオブジェクト
  • Continuous Speculative: 衝突を予測する

X、YおよびZ軸の Constraints では、どの軸に対してオブジェクトの移動を制限するかを指定できます。


さらに、ドロップダウンメニューから Unity 物理エンジンの値の要素を変更することもできます: Edit > Project Setting > Physics (図05)
rigidbody_2.png

補足

  • Rigidbody のゲームオブジェクトをカメラで追っていると、カクツキを感じることがあります。こんなとき、Rigidbody の Interpolate を使うことで、このカクツキを解消することができるのです。詳しい内容はこちらを参照してみてください。
  • 調べたら「一発で適切な Collision Detection を選べる」という「Collision Detection 早見表」というフローチャートがあったので、ぜひこちらから参照してみてください。

原文

The Rigidbody Component (Figure 04), allows GameObjects to be affected by Physics properties, such as Gravity.

It also includes properties for Mass, Velocity, and Drag (air resistance).

Objects of larger mass are less affected by objects with lower mass and vice versa.

Drag affects the dampening of velocity over time. Angular Drag affects angular velocity.
rigidbody_1.png


The Is Kinematic checkbox allows the Rigidbody to affect other objects via the Unity Physics Engine, but will not be affected themselves.

For example, a Hand Avatar in a VR game can interact with objects via Physics, but we don't want Physics to act on the hand.


The Is Kinematic checkbox also affects objects controlled by the Animation Engine.

If the Is Kinematic checkbox is selected (on), the Animation Engine affects objects.

If deselected (off), the Physics Engine retains control.


The interpolate setting detects how collisions are checked.

From the dropdown, select either Interpolate or Extrapolate.

  • Interpolate: Smooth movements of objects are based on information from the previous frame in an animation's timeline.
  • Extrapolate: Smooth movements of objects are based on a guess of the next frame.

The Collision Detection dropdown menu sets the rate at which collisions are checked.

  • Discrete: Default.
  • Continuous: Fast Objects that interact with static objects.
  • Continuous Dynamic: Fast Objects that interact with other fast objects.
  • Continuous Speculative: Predictive collision checking.

The Constraints checkboxes for the X, Y, and Z axes, defines which axis objects should not move.


Additionally, we can redefine and change elements of the Unity Physics Engine values by selecting from the drop-down menu: Edit > Project Settings > Physics (Figure 05).
rigidbody_2.png

参考文献

Unity Learn
Intro to the Unity Physics Engine - Unity Learn
Rigidbody-drag - Unity スクリプトリファレンス
Rigidbody-interpolation - Unity スクリプトリファレンス
【Unity】RigidbodyのInterpolate(補間)を変えて実験 - エクスプラボ
最適な衝突判定を即選択。Collision Detection 早見表【Unity 2018.3 以降】

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Unity VR】備忘録 GVRを使った際にAndroid端末で2画面にならなかったときの話。

UnityVersion : 2019.4.16f

GVRの設定を終わらせ、
Cardboardの設定も済ませたが、
Android実機で2画面にならなかった。

Screenshot_20210103-224833.jpg

設定を見直したが、
マニュアル通りの設定になっている。

おかしい。

ジャイロセンサーも効かない状態。

何度か繰り返しても1画面のままなので、
ふとした瞬間にある事がよぎった。

「もう一回CardboardのSDKインストールしてみるか。。。」

VR SDKsのCardboardを削除して、もう一度プラスボタンを押し、
CardboardSDKを再インストール。
スクリーンショット 2021-01-03 224609.png

これが大当たり。

Screenshot_20210103-224828.jpg

ようやく動作して一安心。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Unity】iOSネイティブプラグインをSwiftで実装する際には、2019.3前後で設定方法が変わる

Unity 2019.3から新機能としてUnity as a Libraryが入った影響で、iOS向けビルド後の.xcodeprojの構成に大きく変更が掛かりました。

その影響としてか、例えば以下の記事にある方法でSwiftコードを実装しようとしてもビルドが通らない状況となっていたので、今回は従来の方法と照らし合わせつつ解決策諸々を備忘録序に纏めていければと思います。
※以降、以下に記事にある2019.2までのやり方を従来のやり方と表記する形で解説していきます。

ひょっとしたら「実はこのパターンが出来なかった」といった見落としがあるかもしれないので、そちらについては分かり次第随時追記予定。
(もし「ここの内容だとあれが出来ない」と言った情報があれば、コメントや編集リクエストなどで教えて頂けると幸いです :pray: :sweat_drops: )

バージョン

  • Unity
    • 2018.4.30f1
      • 従来のやり方の検証に利用
    • 2019.4.17f1
      • 2019.3からのやり方の検証に利用
  • Xcode 12.3

公開リポジトリ

今回検証に用いたプロジェクト一式をGitHubにて公開してます。
「従来のやり方を適用したプロジェクト」と「2019.3からのやり方を適用したプロジェクト」の2つを用意してます。

2019.3からどの様な変更が掛かったのか?

※一応補足として記載しておきます。「ここまでは知ってるので、早くSwiftコードを実装する方法を知りたい」という方は読み飛ばして下さい。

従来はUnity-iPhoneと言うターゲットに全てのコードやデータなどが集約される形となっておりましたが、2019.3からは新たに「UnityFramework」と言うフレームワークのターゲットが追加されており、ClassesLibraries folders、その他依存関係となっているフレームワーク各種はこちらに切り離されるようになりました。

ここらの詳細については公式ドキュメントの方にも記述があるので、詳しくは以下を御覧ください。

この変更によって大きく影響を受ける箇所としては、恐らくは[PostProcessBuild]で処理されるであろうPBXProjectの更新処理であり、GUIDの向き先を以下の様にUnityFrameworkに向け直す必要が出てきました。

        [PostProcessBuild]
        static void OnPostProcessBuild(BuildTarget target, string path)
        {
            if (target != BuildTarget.iOS) return;

            var projectPath = PBXProject.GetPBXProjectPath(path);
            var project = new PBXProject();
            project.ReadFromString(File.ReadAllText(projectPath));

#if UNITY_2019_3_OR_NEWER
            // NOTE: 2019.3からは`UnityFramework`に設定を適用
            var targetGUID = project.GetUnityFrameworkTargetGuid();
#else
            var targetName = PBXProject.GetUnityTargetName();
            var targetGUID = project.TargetGuidByName(targetName);
#endif

            project.AddFrameworkToProject(targetGUID, "MonafuwaLowMemoryWarningFramework.framework", false);
            File.WriteAllText(projectPath, project.WriteToString());
        }

ただ、Swiftを扱う上では↑の様に単純にGUIDの向き先をUintyFrameworkに変えるだけでは解決しないので、具体的な解決策を後述していきます。

従来のSwiftコードの実装方法

先に予備知識として2019.2までの従来の実装方法について記載していきます。

とは言え、やっている事自体はほぼ以下の記事にあるやり方そのままです。
こちらも大体把握されている方は読み飛ばしてしまっても問題有りません。

ここでは以下のプロジェクトにあるExsamplesを元に解説していきます。

PBXProjectの変更点

ほぼ記事にあるやり方のとおりです。
幾つか要点だけ箇条書きで纏めておきます。

  • Objective-C Bridging HeaderUnitySwift-Bridging-Header.hを設定
  • Objective-C Generated Interface Header Nameunityswift-Swift.hを設定
  • Runpath Search Paths@executable_path/Frameworksを設定
  • Swiftのバージョンを5.0に設定
    • ※コメントにも記載しているが、こちらを明示的に指定しないとデフォルトで3.0辺りが設定される?影響で、XcodeによってはUnspecified扱いになることがある
    • ※因みに5.0を指定しているのは最新だからとりあえず指定しているだけであって、特にこれと言った理由などは無い。こちらのバージョンは要件に応じて必要な値を設定すること
XcodePostProcess.cs
    /// <summary>
    /// Swiftを実装するにあたって必要な設定を自動で適用する
    /// </summary>
    sealed class XcodePostProcess
    {
        [PostProcessBuild]
        static void OnPostProcessBuild(BuildTarget target, string path)
        {
            if (target != BuildTarget.iOS) return;

            var projectPath = PBXProject.GetPBXProjectPath(path);
            var project = new PBXProject();
            project.ReadFromString(File.ReadAllText(projectPath));

            var targetGuid = project.TargetGuidByName(PBXProject.GetUnityTargetName());
            project.SetBuildProperty(targetGuid, "SWIFT_OBJC_BRIDGING_HEADER", "Libraries/UnitySwift/UnitySwift-Bridging-Header.h");
            project.SetBuildProperty(targetGuid, "SWIFT_OBJC_INTERFACE_HEADER_NAME", "unityswift-Swift.h");
            project.AddBuildProperty(targetGuid, "LD_RUNPATH_SEARCH_PATHS", "@executable_path/Frameworks");

            // Swift version: 5.0
            // NOTE: 明示的に指定しないと3.0ぐらいの古いのが設定されるっぽいので、Xcodeによっては`Unspecified`扱いになる
            project.AddBuildProperty(targetGuid, "SWIFT_VERSION", "5.0");

            File.WriteAllText(projectPath, project.WriteToString());
        }
    }

UnitySwift-Bridging-Header.hには予めFoundation.hUIKit.hの他、UnityInterface.hをimportしておきます。
(UnitySendMessageなどはUnityInterface.hで宣言されているため、SwiftからUnitySendMessageを呼び出したい場合にはimportしておく必要がある)

UnitySwift-Bridging-Header.h
//
//  Use this file to import your target's public headers that you would like to expose to Swift.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "UnityInterface.h"

Swiftのコード

Swiftのコードは以下のように実装してます。

callSwiftMethodはC#側から渡された文字列をprintで出力するだけのものであり、callUnityMethodUnitySendMessageを呼び出してC#側に"Hello, Unity!"と言う文字列を送ります。

Exsample.swift
import Foundation

class Example : NSObject {

    // ObjC++からSwiftのメソッドを呼び出す
    @objc static func callSwiftMethod(_ message: String) {
        print("\(#function) is called with message: \(message)")
    }

    // SwiftのメソッドからSendMessageを呼び出す
    @objc static func callUnityMethod() {
        // Call a method on a specified GameObject.
        UnitySendMessage("CallbackTarget", "OnCallFromSwift", "Hello, Unity!")
    }
}

Objective-C++のコード

SwiftのコードだけだとC#から呼び出せないので、P/Invokeで呼び出せるようにObjC++コードを用意します。
内容はSwift側のメソッドをそのまま呼び出しているだけです。

ExsampleBridge.mm
#import <Foundation/Foundation.h>

// ObjC++からSwiftのクラスにアクセスする際に必要
// NOTE: `unityswift-Swift.h`の実態はビルド時に`DerivedData`以下に自動生成される
#import "unityswift-Swift.h"    // Required

// P/Invoke
extern "C" {

    void callSwiftMethod(const char *message) {
        [Example callSwiftMethod:[NSString stringWithUTF8String:message]];
    }

    void callUnityMethod() {
        [Example callUnityMethod];
    }
}

C#のコード

上記で実装したSwiftコード及びP/Invoke用のObjC++コードの呼び出し処理を実装します。
Exsampleでは画面上にある2つのButtonからSwift側のcallSwiftMethodcallUnityMethodを呼び出せるようにしてます。

なお、callUnityMethodについてはSendMessageで結果を受け取る都合上、GameObject名やメソッド名を合わせる形にして受け取った文字列をログ出力するようにしてます。

Exsample.cs (クリックで展開)
Exsample.cs
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.UI;

namespace UnitySwift.Exsamples
{
    /// <summary>
    /// iOS NativePluginの呼び出しサンプル
    /// </summary>
    public sealed class Exsample : MonoBehaviour
    {
        [SerializeField] Button _callSwiftMethod = default;
        [SerializeField] Button _callUnityMethod = default;

        void Start()
        {
            // SwiftからSendMessageを呼び出す際に指定されているGameObjectの名称を設定
            this.name = "CallbackTarget";

            _callUnityMethod.onClick.AddListener(() =>
            {
#if !UNITY_EDITOR && UNITY_IOS
                CallUnityMethod();
#endif
            });

            _callSwiftMethod.onClick.AddListener(() =>
            {
#if !UNITY_EDITOR && UNITY_IOS
                CallSwiftMethod("Gorilla");
#endif
            });
        }

        /// <summary>
        /// SwiftからSendMessageで呼び出される措定のメソッド
        /// </summary>
        /// <param name="message"></param>
        void OnCallFromSwift(string message)
        {
            Debug.Log(message);
        }

        /// <summary>
        /// ObjC++からSwiftのメソッドを呼び出す
        /// </summary>
        /// <remarks>[C# -> ObjC++ -> Swift]の流れで呼び出される</remarks>>
        [DllImport("__Internal", EntryPoint = "callSwiftMethod")]
        static extern void CallSwiftMethod(string message);

        /// <summary>
        /// SwiftのメソッドからSendMessageを呼び出す
        /// </summary>
        /// <remarks>※SwiftからUnity側で定義されているメソッドを呼び出したい意図がある</remarks>>
        [DllImport("__Internal", EntryPoint = "callUnityMethod")]
        static extern void CallUnityMethod();
    }
}

2019.3からのSwiftコードの実装方法

上述した従来のやり方のまま.xcodeprojをビルドすると確実にエラーが出て怒られます。

その理由の一つとして、UnityFrameworkの実態であるFrameworkと言うターゲットはBridging-Header.hを設定することが出来ないので、恐らくは早いタイミングでこの旨に関連するエラーが出力されるかと思われます。

この他にも細かい所で幾つか変更が掛かっている箇所があるので、順を追って説明していきます。

ここでは以下のプロジェクトにあるExsamplesを元に解説していきます。

PBXProjectの変更点

先にPBXProjectの変更点についての解説ですが、結論から言うと「Swiftのバージョン指定」以外不要になっているように思われました。

UnitySwift-Bridging-Header.hについてはそもそも設定することが出来ないので、プロジェクトからも削除してます。

XcodePostProcess.cs
    sealed class XcodePostProcess
    {
        /// <summary>
        /// Swiftを実装するにあたって必要な設定を自動で適用する
        /// </summary>
        [PostProcessBuild]
        static void OnPostProcessBuild(BuildTarget target, string path)
        {
            if (target != BuildTarget.iOS) return;

            var projectPath = PBXProject.GetPBXProjectPath(path);
            var project = new PBXProject();
            project.ReadFromString(File.ReadAllText(projectPath));

            // 2019.3からは`UnityFramework`に分離しているので、targetGuidはこちらを指定刷る必要がある。
            // NOTE: 前バージョンと共存させたい場合には「#if UNITY_2019_3_OR_NEWER」で分けることも可能
            var targetGuid = project.GetUnityFrameworkTargetGuid();

            // NOTE:
            // 以前まで設定していた`Bridging-Header.h`の設定の類は2019.3からは不要な模様。
            // 寧ろCocoa touch FrameworkがBridging-Headerに対応していないので、設定していると怒られる。

            // Swift version: 5.0
            // NOTE: 明示的に指定しないと3.0ぐらいの古いのが設定されるっぽいので、Xcodeによっては`Unspecified`扱いになる
            project.AddBuildProperty(targetGuid, "SWIFT_VERSION", "5.0");

            File.WriteAllText(projectPath, project.WriteToString());
        }
    }

Swiftのコード

変更点としては以下の2点が挙げられます。

  • ObjC++に公開するクラス/メソッドのアクセスレベルをpublicに設定
  • UnitySendMessageの代わりにUnityFrameworkに実装されているsendMessageToGOを利用

後者の変更については以下のissue/PRを参考にさせて頂きました。
(記憶だとsendMessageToGOはUaaL1に於ける「Native → Unity」間のやりとり辺りで使われていた覚え)

従来のUnityInterface.hはそもそもターゲットに含まれておらず、参照すら出来ない模様...?

Exsample.swift
import Foundation

// NOTE: ObjCに公開する物はアクセスレベルを`public` or `open`に設定する必要あり

public class Example : NSObject {

    // ObjC++からSwiftのメソッドを呼び出す
    @objc public static func callSwiftMethod(_ message: String) {
        print("\(#function) is called with message: \(message)")
    }

    // SwiftのメソッドからSendMessageを呼び出す
    @objc public static func callUnityMethod() {

        // NOTE: 従来の`UnityInterface.h`にある`SendMessage`は参照でき無さそう?なので、以下のsendMessageToGOを利用する。

        // Call a method on a specified GameObject.
        if let uf = UnityFramework.getInstance() {
            uf.sendMessageToGO(
                withName: "CallbackTarget",
                functionName: "OnCallFromSwift",
                message: "Hello, Unity!")
        }
    }
}

Objective-C++のコード

こちらの主な変更点としては、importするヘッダーであり、対象をunityswift-Swift.hからUnityFramework/UnityFramework-Swift.hに変更してます。

ExsampleBridge.mm
#import <Foundation/Foundation.h>

// 2019.3からはこちらをimportする必要がある
#import <UnityFramework/UnityFramework-Swift.h>

// P/Invoke
extern "C" {

    void callSwiftMethod(const char *message) {
        [Example callSwiftMethod:[NSString stringWithUTF8String:message]];
    }

    void callUnityMethod() {
        [Example callUnityMethod];
    }
}

C#のコード

C#側の呼び出しコードに変更は無いので割愛。

参考リンク


  1. UaaL・・・Unity as a Libraryの略称 

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Unity]WebGL: Server configuration for Nginx

Unityの公式には、WebGLのサーバ設定例はIISとApacheしか書いていません。
WebGL: Server configuration code samples

nginx向けに書いて動作確認したものを掲載しておきます。

環境など

  • Unity 2020.2.0f
  • 使用したDockerイメージ: nginx:alpine
  • Herokuにホスティングする都合上、ポート番号が環境変数になっています。
  • gzip圧縮にのみ対応。Brotli圧縮の場合でも同じように書けばよいはず。

nginx.conf

server {
  listen $PORT;

  location / {
    root   /webgl; # お好みで
    index  index.html;

    gzip off;

    location ~* \.gz$ {
      add_header Content-Encoding gzip;

      location ~* \.data\.gz$ {
          types { }
          default_type application/octet-stream;
      }
      location ~* \.wasm\.gz$ {
          types { }
          default_type application/wasm;
      }
      location ~* \.js\.gz$ {
          types { }
          default_type application/javascript;
      }
      location ~* \.symbols\.json\.gz$ {
          types { }
          default_type application/octet-stream;
      }
    }
  }
}

content-typeの設定について

若干ハック感ありますが、一応nginxの公式の記法に倣っています。
Module ngx_http_core_module#types

追加モジュールが必要ですが、以下の方法で設定した方が可読性は高くなると思います。
nginxでレスポンスヘッダを書き換える - Qiita

余談: Herokuデプロイ用のDockerfile

FROM nginx:alpine

# copy binary files
WORKDIR /webgl
COPY ./bin .

# configure and run in foreground
WORKDIR /etc/nginx/conf.d
RUN rm default.conf
COPY ./environments/webgl.conf.template .
CMD /bin/ash -c "envsubst '\$PORT' < webgl.conf.template > default.conf" && /usr/sbin/nginx -g "daemon off;"

全体を通して

もっとこうしたほうがいいぞ、等あればご指摘ください。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Unity]DISSOLVEエフェクトをShader Graphでやってみる

こんな感じのものを作ります

概要

ShaderGraphの練習でDISSOLVEエフェクトを作ってみました。
ShaderGraphはまだまだ新しい技術でどんどん更新されて行ってます。現時点での最新の操作手順を共有する為に投稿しました。

なお、この記事は海外YouTuber Brackeysさんの動画をベースにしています。
https://www.youtube.com/watch?v=taMp1g1pBeE&t=115s

前準備

Unityのバージョンは2019以降なら大丈夫だと思います。今回は最新の2020.2.1f1で新規作成しました。
スクリーンショット (1540).png

テンプレートはHDRPもしくはURPを選択すると今回のテーマであるShaderGraphがすぐ使える状態になります。今回はシンプルで軽量なつくりのURPを選択しました。

スクリーンショット (1541).png

Unityが起動したらProjectからCreate > Shader > Universal Render Pipeline > Lit Shader Graphを選びます。

スクリーンショット (1542).png

生成されたShaderGraphには適当な名前を付けてください。
次に、これから作るShaderGraphを適用させるマテリアルを作ります。
生成されたShaderGraphにマウスポインタを重ねた状態で右クリック。Create > MaterialでShaderGraphが適用されたマテリアルが作成されます(ShaderGraphの上で右クリックするのがポイントです)

スクリーンショット (1543).png

ShaderGraphを編集する(準備1)

ShaderGraphをダブルクリックしてください
スクリーンショット (1544).png
ShaderGraphを編集する画面が表示されます。画面が小さい時は編集エリア上にマウスカーソルを置いた状態でShiftキー + スペースキーで全体表示に切り替わります(もう一度押すと元に戻ります)

スクリーンショット (1546).png

ShaderGraphを編集する(準備2)

VertexとFragmentがShaderGraphを通して画面に表示される最終出力です。
今回のDissolveエフェクトの肝になる透明度(Alpha)が表示されていないと思います。画面右側Graph Inspector(タブはGraph Settings)のAlphaClipにチェックを入れるとFlagmentにAlphaが2つ表示されます。
スクリーンショット (1547).png
ついでにTwo Sidedにもチェックを入れておいてください

ShaderGraphを編集する(いきなり最終形)

一つ一つのノードを解説すると冗長な記事になると思うので、最終的な完成図を載せます。
ですが、ShaderGraphは操作のコツをつかんだら後はただのパズルのようなものです(ノードごとの役割を理解する必要があります。個々で気になった箇所をその度ググるのが一番頭に入ると思います)
以降でノードを構築する時に必要なコツを挙げていきます。
スクリーンショット (1550).png

ShaderGraphを編集するコツ(ノードを作成する)

まずノード(枠で囲まれた1つ1つのパーツがいわゆるノードです)を作成する方法は2つあります「右クリックで表示されるメニューからCreateNode」もしくは「何もノードを選択していない状態でスペースキーを押す」

スクリーンショット (1552).png

作成したいノードの名前を検索欄に入力すると対象のノードを作成できます。
今回のサンプルは
Time
Remap
Simple Noise
Add
Step
Multiply

Color
Float
で構成されています。それぞれ検索欄に入力して完成図のようにつないでいきます。
※Colorだけ種類がたくさんありますがInput > Basic > Colorを選んでください

スクリーンショット (1553).png

ShaderGraphを編集するコツ(その他)

ノード同士を線でつなぐのは感覚で出来ると思います。端末同士をドラッグでつなぐだけです。
線を消したい時は、その線をクリックして選択状態にした後、Deleteキーで消せます。

Floatノードは数値を設定するためのものです。左の数字の枠内に数を入力すると設定数を変更できます。(Colorノードも同様に色を変更できます)

スクリーンショット (1554).png

ShaderGraphを編集するコツ(適用)

ShaderGraphはノードを構築しただけでは画面に反映されません。変更を確認する時はその度、左上のSaveAssetを押してください。
スクリーンショット (1555).png

結果を確認する

Unityの最初の画面に戻り冒頭で作成した(ShaderGraphを適用した)Materialを効果を付与したいオブジェクトにドラッグアンドドロップなどで適用させます。
実行させるとDISSOLVEエフェクトのアニメーションが見られます。
スクリーンショット (1559).png

最後に

事細かに説明するとすごく長くなるので、つまづきそうな部分を中心に記事にしました。後は最初にリンクを張ったYouTube動画も参考にしながらやってみると大丈夫だと思います。
Floatの数字を変えたり、色を変えたり、Noiseの種類を変えたり、FloatをPropertiesに変えてみたり。応用できる場所はたくさんあります。楽しんで見てください:grinning:

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

toioの簡易カード(StandardID)でかるたっぽいものを作る

概要

toio買って、toio SDK for Unityでアプリ開発を勉強中です。
購入時に一緒に付いてきた簡易カードを見て、真っ先に思いついたのがかるた。
ということで試作しました。

GitHub repository

https://github.com/zurachu/toio-karuta/

WebGL sample

toio SDK for Unityの説明にある形で、WebGLビルドをGitHub Pagesで公開しています。
toioキューブと簡易カード(A〜Z)が必要です。
https://zurachu.github.io/toio-karuta/

動画(Twitter)

書いている通り、手元の簡易カードが、最初に付いてきた1個しかないので、カード切り離すのは躊躇しているところ。
実際にかるたっぽくするには、開発用プレイマットを買い足して、切り離さないと…
A〜Zを使っているので、「Apple」「Banana」「Cat」などにして、絵をつけて子ども向けのアルファベットかるたにしようかなと思っています。

技術情報

StandardIDの更新をコールバックで受け取る

Update毎にCube.standardIdで取得しても良いですが、UIのボタン操作などと同様にイベントドリブンで記述するために、コールバックでStandardIDが更新された(センサーが新しい簡易カードを認識した)、またはStandardIDが失われた(センサーが簡易カードから離れた)イベントを受け取るようにします。
作法として一応前に登録したListenerを削除してから追加します。

KarutaPlayer.cs
cube.standardIdCallback.RemoveListener(callbackKey);
cube.standardIdCallback.AddListener(callbackKey, OnUpdateStandardId);
cube.standardIdMissedCallback.RemoveListener(callbackKey);
cube.standardIdMissedCallback.AddListener(callbackKey, OnMissedStandardId);

StandardIDの値を使いやすくする

StandardIDからtoio.Simulator.StandardID.SimpleCardTypeやSimpleCardNamesへの変換をUtilityとして用意しました。

ToioSimpleCardUtility.cs
using System;
using System.Collections.Generic;
using toio.Simulator;

public static class ToioSimpleCardUtility
{
    public static readonly List<StandardID.SimpleCardType> AlphabetTypes = new List<StandardID.SimpleCardType>
    {
        StandardID.SimpleCardType.Char_A,
        // 中略
        StandardID.SimpleCardType.Char_Z,
    };

    // 以下、interfaceだけ列挙します
    public static bool IsSimpleCardId(uint standardId);
    public static StandardID.SimpleCardType TypeOf(uint simpleCardId);
    public static string NameOf(uint simpleCardId);
    public static string NameOf(StandardID.SimpleCardType simpleCardType);
    public static bool IsAlphabet(uint simpleCardId);
    public static bool IsAlphabet(StandardID.SimpleCardType simpleCardType);
}

プリセット効果音のIDを定数化

https://toio.github.io/toio-spec/docs/ble_sound#%E5%8A%B9%E6%9E%9C%E9%9F%B3%E3%81%AE-id
これはSDKにあっても良さそうな…!

ToioSoundUtility.cs
public static class ToioSoundUtility
{
    public static class PresetSoundId
    {
        public static readonly int Enter = 0;
        public static readonly int Selected = 1;
        public static readonly int Cancel = 2;
        public static readonly int Cursor = 3;
        public static readonly int MatIn = 4;
        public static readonly int MatOut = 5;
        public static readonly int Get1 = 6;
        public static readonly int Get2 = 7;
        public static readonly int Get3 = 8;
        public static readonly int Effect1 = 9;
        public static readonly int Effect2 = 10;
    }
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む