MRが楽しい

MRやVRについて学習したことを書き残す

UnityのInspectorビューにクラスの関数に合わせて関数を実行するボタンを自動で追加する

本日は Unity の小ネタ枠です。
UnityのInspectorビューにクラスの関数に合わせて関数を実行するボタンを自動で追加する手順を記事にします。
f:id:bluebirdofoz:20210716235527j:plain

前提条件

前回記事の続きです。
bluebirdofoz.hatenablog.com

Type.GetMethods

クラスのメソッドの一覧を取得します。
引数の BindingFlags タイプを変更することで様々な定義のメソッドを指定して取得できます。
docs.microsoft.com
docs.microsoft.com

MethodBase.GetParameters

メソッドが持つ引数の情報一覧を取得します。
docs.microsoft.com

サンプルスクリプト

以下のサンプルスクリプトと、そのエディター拡張を行うスクリプトを作成しました。
エディター拡張では拡張対象のクラスのメソッド一覧を取得し、そのクラス階層が持つ引数のない Public な関数の実行ボタンを自動で追加します。
・TestScript.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// サンプルスクリプト
/// </summary>
public class TestScript : MonoBehaviour
{
    /// <summary>
    /// Public関数(引数無し)
    /// </summary>
    public void PublicMethod()
    {
        Debug.Log("PublicMethod");
    }

    /// <summary>
    /// Public関数(引数有り)
    /// </summary>
    public void ArgPublicMethod(string message)
    {
        Debug.Log("PublicMethod : " + message);
    }

    /// <summary>
    /// Private関数
    /// </summary>
    private void PrivateMethod()
    {
        Debug.Log("PrivateMethod");
    }
}

f:id:bluebirdofoz:20210716235603j:plain

・TestMessageScriptEditor.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

#if UNITY_EDITOR
// クラス名を別名でまとめて管理する
using CUSTOMTYPE = TestScript;

using UnityEditor;
using System.Reflection;

// 拡張するクラスを指定する
[CustomEditor(typeof(CUSTOMTYPE))]
public class TestScriptEditor : Editor
{
    // GUIの表示関数をオーバーライドする
    public override void OnInspectorGUI()
    {
        // 元のインスペクター部分を表示
        base.OnInspectorGUI();

        // targetを変換して対象スクリプトの参照を取得する
        CUSTOMTYPE targetScript = target as CUSTOMTYPE;

        // Editor実行中のみ有効化なUIを設定する
        if (EditorApplication.isPlaying)
        {
            // Publicかつ指定したクラス階層のメソッドのみの一覧を取得する
            BindingFlags flag = BindingFlags.Public |
                BindingFlags.Instance | BindingFlags.DeclaredOnly;
            MethodInfo[] methods = targetScript.GetType().GetMethods(flag);

            foreach (MethodInfo method in methods)
            {
                // メソッドの引数一覧を取得する
                ParameterInfo[] methodParam = method.GetParameters();

                // 引数がない関数のみ実行ボタンを作成する
                if (methodParam.Length == 0)
                {
                    // public関数を実行するボタンの作成
                    if (GUILayout.Button(method.Name + "の実行"))
                    {
                        method.Invoke(targetScript, null);
                    }
                }
            }
        }
    }
}
#endif

f:id:bluebirdofoz:20210716235614j:plain

シーンの適当なオブジェクトにサンプルスクリプトを設定します。
f:id:bluebirdofoz:20210716235625j:plain

動作確認

シーンを再生するため、Unity エディターの[再生]ボタンをクリックします。
f:id:bluebirdofoz:20210716235636j:plain

対象クラスの関数が自動的に検出されて Inspectro ビューに関数を実行する拡張UIが表示されました。
f:id:bluebirdofoz:20210716235646j:plain

HoloLens2実機上で動作するアプリに対してVisualStudioのUnityデバッガーでスクリプトデバッグを行う

本日は HoloLens の技術調査枠です。
HoloLens2 実機上で動作するアプリに対して VisualStudio の Unity デバッガーでスクリプトデバッグを行う手順を記事にします。
f:id:bluebirdofoz:20210715025307j:plain

Unity を使用したマネージデバッグ

Unity プロジェクトで所定の設定を行うことで HoloLens 2 上で動作する IL2CPP UWP アプリに対して Unity デバッガーを利用できます。
docs.microsoft.com

サンプルシーンの作成

デバッグを実施する自作のサンプルアプリを作成してみます。

サンプルスクリプト

以下のような HoloLens2 上(UWP時のみ)で動作するコードを含むサンプルスクリプトを用意しました。
IncNumber 関数を実行すると動作環境に応じて異なる変数がインクリメントされます。
・TestScript.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TestScript : MonoBehaviour
{
    /// <summary>
    /// Unityエディター上でのインクリメント値
    /// </summary>
    private int Number = 0;

    /// <summary>
    /// HoloLens2上でのインクリメント値
    /// </summary>
    private int UWPNumber = 0;

    /// <summary>
    /// インクリメント実行
    /// </summary>
    public void IncNumber()
    {
#if WINDOWS_UWP
        // HoloLens2(UWP)時の実行コード
        UWPNumber++;
#else
        // Unityエディター時の実行コード
        Number++;
#endif
    }
}

f:id:bluebirdofoz:20210715025343j:plain

ボタンオブジェクトをシーンに配置し、ボタンをタップしたときに IncNumber 関数が呼ばれるようにしました。
f:id:bluebirdofoz:20210715025355j:plain

Unityエディター上でのスクリプトデバッグ

まずは Unity エディター上でスクリプトデバッグを実施してみます。
[再生]ボタンを押してシーンを再生します。
f:id:bluebirdofoz:20210715025407j:plain

スクリプトデバッグを実施したいスクリプトファイルを開きます。
VisualStudio が開いたら[Unity にアタッチ]を実行してスクリプトデバッグを開始します。
f:id:bluebirdofoz:20210715025418j:plain

[準備完了]が表示されたら、スクリプトデバッグが開始しています。
デバッグ動作を確認するため、インクリメントの実行コードの左行をクリックしてブレークポイントを設定します。
f:id:bluebirdofoz:20210715025430j:plain

この状態で Unity エディターに戻り、シーン上でボタンをタップしてみます。
f:id:bluebirdofoz:20210715025440j:plain

ブレークポイントのコードが実行され、処理が一時的に中断します。
マウスオーバーでコードが実行される直前の変数の状態が確認できます。
f:id:bluebirdofoz:20210715025451j:plain

シーンを再開したい場合は VisualStudio の[続行]ボタンをクリックします。
f:id:bluebirdofoz:20210715025513j:plain

Unity エディターに戻り、再びシーン上のボタンをタップすると、変数が正常にインクリメントされていることが確認できます。
f:id:bluebirdofoz:20210715025525j:plain

これで Unity エディター上でのスクリプトデバッグを確認できました。
シーンを停止してデバッグを終了します。

Tips

MRTK のシミュレータを用いた Unity エディター上でのシーンの操作方法の詳細は以下を参照ください。
bluebirdofoz.hatenablog.com

Unityプロジェクトの設定と環境設定

HoloLens2 上で動作するアプリケーションを Unity デバッガーにアタッチするため、幾つかの設定を行います。

UnityプロジェクトのCapability設定

アプリケーションにネットワークの利用許可を設定します。
メニューから[Edit -> Project Settings]を開き、[Player -> Publishing Settings]パネルを開きます。
f:id:bluebirdofoz:20210715025615j:plain

以下の2つの Capability にチェックを入れて有効にします。
・InternetClientServer
・PrivateNetworkClientServer
f:id:bluebirdofoz:20210715025630j:plain

Unityデバッガーを実行するPCのネットワーク環境設定

Unity デバッガーを実行する PC は HoloLens2 と同一のネットワーク上に配置されており、かつ、そのネットワーク環境でマルチキャストがサポートされている必要があります。
コントロールパネルからファイアウォールの[詳細設定]を確認します。
f:id:bluebirdofoz:20210715025641j:plain

利用のネットワーク環境で VisualStudio の UDP 通信が許可されていることを確認します。
f:id:bluebirdofoz:20210715025653j:plain

特定の環境下で動作するコードのアセンブリ参照を追加

本項目の作業は特定の環境下で動作するコードのスクリプトデバッグを行いたい場合にのみ必要です。
今回はサンプルコードでの #if WINDOWS_UWP の部分のコードをデバッグするため、指定プラットフォームのアセンブリ参照を追加します。
f:id:bluebirdofoz:20210715025705j:plain

指定プラットフォームのアセンブリ参照の追加手順は以下の記事を参照して実施してください。
bluebirdofoz.hatenablog.com

本手順を実行すると、左上のプルダウンからアセンブリ参照を切り替えることができます。
これでプラットフォーム依存のコードのデバッグが可能になります。
f:id:bluebirdofoz:20210715025727j:plain

プロジェクトのビルドとインストール

Unity プロジェクトのビルドと HoloLens2 へのインストールを実行します。

Unityプロジェクトのビルド設定

メニューから[Edit -> Build Settings]を開きます。
f:id:bluebirdofoz:20210715025756j:plain

設定欄から以下の2つの項目にチェックを入れて有効化し、[Build]を実行します。
・Development Build
・Script Debugging
f:id:bluebirdofoz:20210715025807j:plain

Unity ビルドで作成された VisualStudio のソリューションファイルを開きます。
f:id:bluebirdofoz:20210715025819j:plain

ソリューションの Package.appxmanifest ファイルを開き、[機能]タブを確認します。
[機能]欄の以下の項目がチェックされていることを確認します。
・インターネット(クライアントとサーバー)
・プライベートネットワーク(クライアントとサーバー)
f:id:bluebirdofoz:20210715025833j:plain

構成を[Debug]に指定してビルドし、HoloLens2 にアプリケーションをインストールします。
今回はメニューから[デバッグ -> デバッグ無しで開始]で HoloLens2 にアプリケーションをインストールしました。
f:id:bluebirdofoz:20210715025844j:plain

スクリプトデバッグはアプリ起動後に接続を行うものなので、インストール時に自動起動したアプリケーションは閉じて問題ありません。

HoloLens2上でのスクリプトデバッグの実行

HoloLens2 にインストールしたアプリケーションのスクリプトデバッグを実施します。

HoloLens2側のアプリケーション起動

初めに、HoloLens2 がスクリプトデバッグを行う PC と同じネットワークに接続されていることを確認します。
また、このとき HoloLens2 が PC にUSB接続されていない必要があります。
これは USB 接続を行うと Windows IP Over USB により IP アドレスが割り当てられてしまうためです。
f:id:bluebirdofoz:20210715025859j:plain

アプリ一覧からインストールを行ったアプリケーションを起動します。
f:id:bluebirdofoz:20210715025911j:plain

HoloLens2 でアプリケーションが起動し、ボタンが表示されました。
f:id:bluebirdofoz:20210715025926j:plain

次に PC 側の作業に戻り、スクリプトデバッグの接続を行います。

Unityデバッガーの接続

スクリプトデバッグを実施したいスクリプトファイルを開きます。
VisualStudio が開いたらメニューから[デバッグ -> Unity デバッガーのアタッチ]を実行します。
f:id:bluebirdofoz:20210715025948j:plain

[Unityインスタンスの選択]ダイアログが表示されます。
ネットワーク環境設定が正しく行われていれば一覧に、アプリケーションを起動中の HoloLens2 の情報が表示されます。
これを選択し、[OK]ボタンをクリックします。
f:id:bluebirdofoz:20210715030029j:plain

[準備完了]が表示されたら、HoloLens2 上のアプリケーションのスクリプトデバッグが開始しています。
デバッグ動作を確認するため、インクリメントの実行コードの左行をクリックしてブレークポイントを設定します。
なお、#if WINDOWS_UWP の部分のコードをデバッグするには前述のアセンブリ参照の追加を実施しておく必要があります。
f:id:bluebirdofoz:20210715030040j:plain

この状態で HoloLens2 の操作に戻り、アプリケーションのボタンをタップしてみます。
f:id:bluebirdofoz:20210715030052j:plain

ブレークポイントのコードが実行され、HoloLens2 上のアプリケーションが一時的に中断します。
VisualStudio を確認すると、マウスオーバーでコードが実行される直前の変数の状態が確認できます。
f:id:bluebirdofoz:20210715030112j:plain

シーンを再開したい場合は VisualStudio の[続行]ボタンをクリックします。
f:id:bluebirdofoz:20210715030125j:plain

HoloLens2 上のアプリケーションの動作が再開されます。
再びボタンをタップしてみます。
f:id:bluebirdofoz:20210715030136j:plain

再び、ブレークポイントのコードが実行され、HoloLens2 上のアプリケーションが中断します。
変数が正常にインクリメントされていることが確認できました。
f:id:bluebirdofoz:20210715030148j:plain

これで HoloLens2 実機上のアプリケーションに対してスクリプトデバッグを実施できました。

UnityのInspectorビューにエディター再生中のみ関数を実行するボタンを追加する

本日は Unity の小ネタ枠です。
UnityのInspectorビューにエディター再生中のみ関数を実行するボタンを追加する手順を記事にします。
f:id:bluebirdofoz:20210714222742j:plain

前提条件

前回記事の続きです。
bluebirdofoz.hatenablog.com

UnityEditor.EditorApplication

エディターが再生中か否かは UnityEditor.EditorApplication クラスの isPlaying 変数で取得できます。
UnityEditor.EditorApplication クラスではその他、様々な UnityEditor の情報が取得できます。
docs.unity3d.com

サンプルスクリプト

以下のサンプルスクリプトと、そのエディター拡張を行うスクリプトを作成しました。
・TestMessageScript.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// サンプルスクリプト
/// </summary>
public class TestMessageScript : MonoBehaviour
{
    /// <summary>
    /// デバッグメッセージを表示するPublic関数
    /// </summary>
    public void PublicMessageMethod(string message)
    {
        Debug.Log("PublicMessageMethod : " + message);
    }

    /// <summary>
    /// デバッグメッセージを表示するPrivate関数
    /// </summary>
    private void PrivateMessageMethod(string message)
    {
        Debug.Log("PrivateMessageMethod : " + message);
    }
}

f:id:bluebirdofoz:20210714222849j:plain

・TestMessageScriptEditor.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

#if UNITY_EDITOR
using UnityEditor;

// クラス名を別名でまとめて管理する
using CUSTOMTYPE = TestMessageScript;

// 拡張するクラスを指定する
[CustomEditor(typeof(CUSTOMTYPE))]
public class TestMessageScriptEditor : Editor
{
    /// <summary>
    /// テスト入力メッセージ
    /// </summary>
    private string TestMessage;

    // GUIの表示関数をオーバーライドする
    public override void OnInspectorGUI()
    {
        // 元のインスペクター部分を表示
        base.OnInspectorGUI();

        // targetを変換して対象スクリプトの参照を取得する
        CUSTOMTYPE targetScript = target as CUSTOMTYPE;

        // Editor実行中のみ有効化なUIを設定する
        if (EditorApplication.isPlaying)
        {
            // public関数を実行するボタンの作成
            if (GUILayout.Button("PublicMessageMethodの実行"))
            {
                targetScript.PublicMessageMethod(TestMessage);
            }

            // private関数を実行するボタンの作成
            if (GUILayout.Button("PrivateMessageMethodの実行"))
            {
                targetScript.SendMessage("PrivateMessageMethod", TestMessage, SendMessageOptions.DontRequireReceiver);
            }

            // メッセージの入力テキストフィールド
            TestMessage = EditorGUILayout.TextField("Message", TestMessage);
        }
    }
}
#endif

f:id:bluebirdofoz:20210714222905j:plain

シーンの適当なオブジェクトにサンプルスクリプトを設定します。
f:id:bluebirdofoz:20210714222927j:plain

動作確認

シーンを再生するため、Unity エディターの[再生]ボタンをクリックします。
f:id:bluebirdofoz:20210714222939j:plain

シーンが再生されると、Inspectro ビューに関数を実行する拡張UIが表示されました。
f:id:bluebirdofoz:20210714222949j:plain

これによりシーンを再生中にのみ、関数実行を試すことができます。
f:id:bluebirdofoz:20210714223001j:plain

MRTKのBuildWindowを利用してUnityからHoloLens2へのデプロイまでを自動で行う

本日は MRTK の小ネタ枠です。
MRTKのBuildWindowを利用してUnityからHoloLens2へのデプロイまでを自動で行う手順を記事にします。
f:id:bluebirdofoz:20210713195451j:plain

MRTKのBuildWindow

MRTK の BuildWindow を使用すると、Unity プロジェクトのビルドから VisualStudio でのビルドと HoloLens へのインストールを1回のクリック操作で行うことができます。
docs.microsoft.com

Toolsパッケージの取得

BuildWindow は MRTK の Tools パッケージに含まれています。
以下の Release ページから Foundation パッケージのほか、Tools パッケージも取得します。
github.com
f:id:bluebirdofoz:20210713195522j:plain

パッケージのインポート

Foundation パッケージとTools パッケージを Unity プロジェクトにインポートします。
f:id:bluebirdofoz:20210713195532j:plain

Tools パッケージをインポートするとメニューに[MixedReality -> Toolkit -> Utilities -> BuildWindow]が追加されます。
f:id:bluebirdofoz:20210713195541j:plain

BuildToolsの設定

サンプルシーンを作成し、HoloLens へのデプロイ設定を行ってみます。
f:id:bluebirdofoz:20210713195554j:plain

メニューから[MixedReality -> Toolkit -> Utilities -> BuildWindow]を開きます。
f:id:bluebirdofoz:20210713195606j:plain

これで BuildWindow の画面が開きます。
BuildWindow には以下の3つのオプション設定タブがあります。
・Unity Build Options:Unityビルドの設定
・Appx Build Options :VisualStudioビルドの設定
・Deploy Options :デプロイ先の設定
f:id:bluebirdofoz:20210713195617j:plain

Unity Build Options

[Target Device]の指定と、ビルド対象のシーンを選択します。
f:id:bluebirdofoz:20210713195629j:plain

シーンの追加は[File -> BuildSettings]の[BuildSettings]ダイアログで行います。
シーンが設定されてない場合は現在、選択中のシーンがビルドされます。
HoloLens2 へのデプロイの場合、[Any Device]の設定のままで問題ありません。

Appx Build Options

Build 時のプラットフォームの指定やビルド方法の変更が行えます。
HoloLens2 向けの Build を実行する際は[Build Platform]を[ARM]または[ARM64]に指定します。
f:id:bluebirdofoz:20210713195640j:plain

デフォルト設定では[Versioning Options]の[Auto Incremetn]が ON になっています。
本項目が ON だとビルドを実行するたびに新しい Appx ファイルが生成されます。
回数とサイズによっては PC の容量を圧迫するので、ビルドを繰り返す場合は OFF にしておくことをお勧めします。
f:id:bluebirdofoz:20210713195651j:plain

Deploy Options

デプロイ先の設定を行うことができます。
f:id:bluebirdofoz:20210713195703j:plain

HoloLens にデプロイを行う場合は[TargetType]を[Remote]に変更します。
[IpAddress][Username][Password]にデプロイ先の HoloLens のデバイスポータルのアクセス設定を行います。
[Test Connection]ボタンで接続確認と HoloLens の情報取得が行われます。
f:id:bluebirdofoz:20210713195712j:plain

ビルドとデプロイの実行

設定を完了したらアプリケーションのビルドとデプロイを実行してみます。
初めに[BuildWindow]の[Build All]ボタンをクリックしてアプリケーションをビルドします。
f:id:bluebirdofoz:20210713195724j:plain

ビルドが成功すると Command Successful のログが表示され、[Build All]ボタンが[Build All, then install]ボタンに切り替わります。
f:id:bluebirdofoz:20210713195736j:plain

以降は[Build All, then install]ボタンをクリックするだけで、ビルドとデプロイ先へのアプリケーションのインストールが実行されます。
インストールが正常に完了すると Successfully installed (アプリケーション名).appx on (デプロイ先) のログが表示されます。
f:id:bluebirdofoz:20210713195748j:plain

HoloLens2でのアプリの起動

BuildWindows はデバイスポータルを通じてアプリケーションをインストールするため、自動でアプリケーションは起動されません。
アプリケーションの一覧からアプリケーションを選択して起動します。
f:id:bluebirdofoz:20210713195800j:plain

以下の通り、デプロイしたアプリケーションが起動します。
f:id:bluebirdofoz:20210713195812j:plain

UnityHubからプロジェクトに不足しているバージョンのUnityをインストールする

今回は UnityHub の小ネタ枠です。
UnityHubからプロジェクトに不足しているバージョンのUnityをインストールする方法を記事にします。

プロジェクトに必要なUnityバージョン

UnityHub で一覧にプロジェクトを追加するとプロジェクトが参照する Unity バージョンが表示されます。
指定の Unity バージョンがインストールされていない場合、以下のように警告マークが表示されます。
f:id:bluebirdofoz:20210712225610j:plain

Unityのインストール

対象の Unity バージョンをインストールしたい場合は警告マークをクリックすることで直接インストールが可能です。
f:id:bluebirdofoz:20210712225622j:plain

インストールの実行確認が表示されるので[インストール]ボタンをクリックします。
f:id:bluebirdofoz:20210712225630j:plain

これで UnityHub から指定バージョンの Unity をインストールすることができます。
f:id:bluebirdofoz:20210712225640j:plain

HoloLens2でホロモンアプリを作る その46(ホロモンの感情マークを表示する)

本日はアプリ作成枠です。
HoloLens2でホロモンアプリを作る進捗を書き留めていきます。
f:id:bluebirdofoz:20210711234521j:plain

今回はホロモンアプリに感情マークの表示機能を追加するメモです。

感情マークの表示機能

ホロモンの頭部位置の追従オブジェクトに感情を表すアイコンを追加しました。
f:id:bluebirdofoz:20210711234532j:plain

以下の2つのスクリプトで表示するマークと表示アニメーションを管理します。

f:id:bluebirdofoz:20210711234550j:plain

表示アニメーションはアニメーションコントローラで制御します。
ローカルの位置と回転で表示アニメーションを行うため、Animator コンポーネントの[Apply Root Motion]を有効にしています。
f:id:bluebirdofoz:20210711234600j:plain

最後にこれらを合わせて管理するコントローラとなるスクリプトを作成します。
デバッグが行いやすいよう Inspector 上から関数実行を行うエディター拡張を追加しました。

f:id:bluebirdofoz:20210711234611j:plain

動作確認

シーンを再生して動作確認を行います。
f:id:bluebirdofoz:20210711234623j:plain

ExclamationStart 関数を実行するとビックリマークが、QuestionStart 関数を実行するとハテナマークがアニメーションとともに表示されます。
f:id:bluebirdofoz:20210711234635j:plain
f:id:bluebirdofoz:20210711234645j:plain

HoloLens2でホロモンアプリを作る その45(ホロモンアプリにオブジェクト追跡UIを追加する)

本日はアプリ作成枠です。
HoloLens2でホロモンアプリを作る進捗を書き留めていきます。
f:id:bluebirdofoz:20210710233930j:plain

今回はホロモンアプリにオブジェクト追跡UIを追加するメモです。

オブジェクト追跡UI

以下の2つの記事で作成した機能を組み合わせて、ターゲットオブジェクトを追跡して到達と同時に弾けるアニメーションを行うUIを作成しました。
bluebirdofoz.hatenablog.com
bluebirdofoz.hatenablog.com
f:id:bluebirdofoz:20210710233954j:plain

シーンを再生して動作を確認します。
コントロールスクリプトの BreakStart 関数を呼び出します。
f:id:bluebirdofoz:20210710234005j:plain

球体オブジェクトが弧を描きながらスターとオブジェクトとして指定していたカメラから射出されます。
f:id:bluebirdofoz:20210710234015j:plain

目的位置に到達すると同時に弾けるアニメーションが再生されます。
f:id:bluebirdofoz:20210710234026j:plain

ホロモンアプリへの取り込み

プレイヤーとホロモンのそれぞれの頭部位置を追跡するオブジェクトを作成し、それぞれ開始位置と到達位置に設定します。
f:id:bluebirdofoz:20210710234037j:plain

これでプレイヤーとホロモンがどこにいても追跡UIが機能します。
視覚的にプレイヤーからホロモンに情報が届いていることがわかりやすくなりました。
f:id:bluebirdofoz:20210710234047j:plain
f:id:bluebirdofoz:20210710234057j:plain