MRが楽しい

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

Hdg Remote Debugドキュメントを読み解く

本日は Unity のアセットの調査枠です。
Hdg Remote Debugドキュメントを翻訳して読み進めてみます。

Hdg Remote DebugVersionとは

assetstore.unity.com
f:id:bluebirdofoz:20200218004034j:plain

Hdg Remote DebugはUnityのライブアップデートおよびデバッグツールです。
バイスにデプロイされた後に、シーンのゲームオブジェクト、コンポーネント、シリアル化されたフィールドを検査できます。

Unityエディター上で、ライブビルドのフィールドを調整できます。
UIレイアウトやタッチコントロールなどの設定変更をすばやく繰り返すのに最適です。

Unityがサポートするほぼ全てのプレーヤープラットフォームでビルドをデバッグできます。
例えば、PCからiOSバイスに接続できます。

特徴

・簡単に利用できます。
・Unityがサポートするほぼ全てのプラットフォームで実行しています。
(エディターは Mac および Windows でテストされ、デバイスAndroidiPhone、およびUWPデバイスでテストしています)
・デバイスのタッチコントロールを繰り返せます。
・Unity FreeまたはProで動作します。
・再ビルドおよび再デプロイすることなく、実際のデバイスでの設定を微調整するのに最適です。

多数のバグ修正に加えて、最新リリースでは、HoloLensやWindows Phone などの UWP プラットフォームのサポートします。
および ADB ポートフォワーディングを使用した Android USB 接続を介したデバッグが追加されます。

Hdg Remote DebugVersionのドキュメント

以下に使用方法をまとめたドキュメントがあります。
www.horsedrawngames.com
f:id:bluebirdofoz:20200218004103j:plain

本記事ではこちらのドキュメントを読み進めます。

Getting Started

設置

HdgRemoteDebug.unitypackage ファイルをプロジェクトにインポートします。
インポートすると、ツールは以下の場所に追加されます。

Assets/Plugins/HdgRemoteDebug

使用法

1.プレハブをシーンに追加する

HdgRemoteDebugフォルダにある RemoteDebugServer.prefab を追加します。
f:id:bluebirdofoz:20200218004115j:plain

このプレハブはサーバーの役割を持ちます。
ネットワークを制御し、実行時にゲームが Unity に情報を送信できるようにします。

2.HdgRemoteDebugウィンドウを開く

Unityのメニューから、Window -> HdgRemoteDebug を選択します。
f:id:bluebirdofoz:20200218004123j:plain

HdgRemoteDebug ウィンドウが表示されます。
f:id:bluebirdofoz:20200218004131j:plain

デフォルトでは自動更新は有効になっています。
つまり、サーバーはシーン内の GameObjects のリストをエディターに自動的に送り返します。
数千の GameObject がある場合、この処理が遅くなる可能性があります。
その場合は[Automatic Refresh]をクリックしてこの機能をオフにし、[Refresh]ボタンを使用して手動で更新します。

3.ビルド後に実行してゲームに接続する

バイスにゲームをビルドして実行します。
バイス上で RemoteDebugServer プレハブのあるシーンがロードされたら[Active Player]をクリックします。
接続リストにデバイスがリストされるので、デバイスを選択してゲームに接続します。
f:id:bluebirdofoz:20200218004139j:plain

4.プロパティを変更してゲーム内で更新されるのを確認します

接続すると、ゲーム内の GameObject が表示されます。
それらをクリックして、コンポーネントのプロパティを変更することができます。
これを行うとデバイス上のゲームで状態が更新されます。
f:id:bluebirdofoz:20200218004146j:plain

コンポーネントまたはゲームオブジェクト全体を有効または無効にすることもできます。

HdgRemoteDebug はベクトル、マトリックス、リスト、配列などの基本的な種類のパブリックフィールドをシリアル化します。
さらに、SerializeField 属性でマークされたプライベートフィールドもシリアル化されます。

delete キーを押すことで GameObject を削除できます。

DontDestroyOnLoadオブジェクト

残念ながら、HdgRemoteDebug は DontDestroyOnLoad オブジェクトを自動的に追跡できません。
DontDestroyOnLoad オブジェクトを表示したい場合は、DontDestroyOnLoad を呼び出した後、以下のコードを使用します。

Hdg.RemoteDebugServer.AddDontDestroyOnLoadObject(gameObject);

DontDestroyOnLoad オブジェクトを破棄する場合は、以下のようにサーバーからも削除してください。

Hdg.RemoteDebugServer.RemoveDontDestroyOnLoadObject(gameObject);

docs.unity3d.com

Unity 4.6.8-Unity 5.3.1

Unityのバージョン4.6.8と5.3.1で HdgRemoteDebug を使用している場合、いくつかの制限があります。
Unityのこれらのバージョンにはシーン内のルート GameObjects にアクセスする方法がありません。

それらを見つける唯一の方法は Resources.FindObjectsOfTypeAll を使用することです。
この関数の問題は Assets フォルダーからプレハブも返すため、それらを検出してフィルターで除外する方法がないことです。

HdgRemoteDebug が実装する回避策は activeInHierarchyフラグを確認することです。
これは Assets フォルダー内のプレハブでは false です。
デフォルトではこのフラグが false に設定されている GameObject はツールに表示されません。
つまり、無効になっている Hierarchy 内の GameObject も表示されません。

Hierarchy 内の非アクティブなオブジェクトを表示するには HdgRemoteDebug ツールバーの[Show disabled objects]ボタンをクリックします。
ただし、これによってプレハブも表示されることに注意してください。
他の方法でアセットを除外する方法を探していますが、現時点では不可能と思われます。

UWP / HoloLens

UWP(Windows 10)プラットフォーム(Windows PhoneやHoloLensなど)に展開する場合は Internet(Client & Server) アプリケーションの機能を有効にする必要があります。
これにより、HdgRemoteDebug サーバーがネットワークを介して通信できるようになります。

以下の操作を行います。
1.Unity のメニューから Edit -> Project Settings -> Player Settings の Player 設定に移動します。
2.InternetClientServer オプションにチェックを付けます。

サーバーポートのオーバーライド

サーバーのデフォルトのTCPポート 12000 は上書きできます。
シーン内の RemoteDebugServerFactory プレハブの Server Port フィールドを変更し、プロジェクトを保存、ビルド、再デプロイするだけです。

サーバー検出はUDPブロードキャストを介して機能します。
デフォルトではこのポートは12000に設定されています。
これを変更するには、RemoteDebugServerFactory の Broadcast Port フィールドを変更し、Edit -> Preferences -> Remote Debug も変更します。

Android-ADBを使用して接続する

Android ではローカルネットワークではなく、USB接続を介してデバイスに接続することもできます。
これはADBポート転送を使用して、PCからデバイスTCP接続を転送することで実行できます。
ただし、サーバー検出は転送できないUDPブロードキャストを介して機能するため、サーバー検出を行うには HdgRemoteDebug ウィンドウからデバイスに手動で接続する必要があります。

ローカルポートをPCから接続デバイスに転送するには、コマンドプロンプトで次を実行します。

adb forward tcp:12000 tcp:12000

adb は Android Debug Bridge ツールです。Android SDK の platform-tools フォルダーにあります。
これにより、ローカルポート 12000 (HdgRemoteDebug がTCP通信に使用するポート)がリモートデバイスのポート12000に転送されます。
ポート転送が設定されたら、Unity で Active Player メニューで を選択し、IPアドレス 127.0.0.1 を入力してデバイスに接続します。
f:id:bluebirdofoz:20200218004217j:plain

[Connect]をクリックします。
ポート転送が正しくセットアップされてサーバーがデバイスで実行されている場合、HdgRemoteDebug ウィンドウが接続するはずです。

リモートメソッドのトリガー

公開したいメソッドに Hdg.Button 属性を追加することで、パブリックメソッドをトリガーできます。
それはクリックできるボタンとして HdgRemoteDebug ウィンドウに表示されます。
メソッドは現在引数を持つことができません。

以下にコード例を示します。

public class MethodTriggerTest : MonoBehaviour
{
    [Hdg.Button]
    public void RunMe()
    {
        Debug.Log("Hello, World!");
    }
}

HdgRemoteDebug ウィンドウに以下が表示されます。
f:id:bluebirdofoz:20200218004228j:plain

[Run Me]ボタンをクリックすると、Rum Me メソッドが実行されます。
現在、引数のないメソッドのみがサポートされていることに注意してください。

トラブルシューティング

バイスが表示されない

バイスが[Active Player]に表示されない場合は、以下を確認してください。

・デバイスとUnityを実行しているコンピューターが同じネットワークに接続されていることを確認してください。
 HdgRemoteDebug はネットワーク接続を介してデバイスと通信します。

・ゲームが開始され、RemoteDebugServer プレハブのあるシーンが読み込まれるまで待ちます。
 ロードされるとデバイスがリストに表示されます。

・デバイス、PC、またはネットワークでファイアウォールが有効になっている場合、接続がブロックされている可能性があります。
 ファイアウォールを無効にするか、ポート 12000 で TCP および UDP の接続を許可します。

・RemoteDebugServer コンポーネントがビルドから削除されていないことを確認します。
 Hdg Remote Debug には、link.xmlファイルが付属しています。
 このファイルは強制的に削除されませんが、欠落している場合は、Hdg Remote Debug ディレクトリに(DLLと一緒に)次の内容で配置してください。

<linker>
    <assembly fullname="HdgRemoteDebugRuntime" preserve="all"/>
    <assembly fullname="HdgRemoteDebugRuntimeUWP" preserve="all"/>
</linker>

BuildHelpersクラスを使用して、ビルドパイプラインの一部としてこのファイルを自動的に書き出すこともできます。
詳細については「パイプラインの構築」セクションを参照してください。

プロパティがありません

ウィンドウに表示されない一部のプロパティに問題がある場合は、次を確認してください。

・IL2CPPではなくMonoスクリプトバックエンドを使用していることを確認してください。
 IL2CPPは、コードで使用されていないプロパティを削除できる最適化を実行します。

・Unityのストリップレベルを「無効」に設定してみてください。

IL2CPPはストリッピングを積極的に行います。
IL2CPPを使用する場合は、link.xml ファイルを使用して、プロパティが強制的に削除されないようにすることができます。
例えば、全ての UnityEngine プロパティが削除されないようにしたい場合は、link.xml に次のコードを追加します。

<linker>
    <assembly fullname="UnityEngine" preserve="all" />
</linker>

link.xml ファイルをAssetsフォルダーのルートに配置します。
link.xml およびストリッピングレベルの変更の詳細については以下を参照ください。
docs.unity3d.com

ゲームのリリースバージョンをビルドする前に link.xml またはエントリを忘れずに削除してください。
削除すると、不要なクラスとDLLが含まれます。

エディターまたはビルドエラー

ランタイムDLLには HdgRemoteDebugRuntime.dll と HdgRemoteDebugRuntimeUWP.dll の 2つのバージョンがあります。
UWPランタイムDLLはUWPビルドでのみ使用できます。エディターや他のプラットフォームでは使用できません。
「モジュール内のクラスをロードできません」などの不可解なエラーがある場合はUWPランタイムDLLがWSAPlayerに対してのみ有効になっていることを確認してください。
f:id:bluebirdofoz:20200218004248j:plain

他のすべてのプラットフォームでは、非UWPランタイムDLLを有効にする必要があります。
f:id:bluebirdofoz:20200218004257j:plain

ゲームの実行が遅い

[Automatic Refresh]ボタンをクリックして自動更新をオフにし、GameObjects のリストを更新するたびに[Refresh]ボタンを押してください。
シーン内に何千もの GameObjects がある場合、自動更新(デフォルトで有効)が遅くなる可能性があります。

「Ran out of trampolines」エラー

iOSバイスで「Ran out of trampolines」エラーが発生した場合は、モノコンパイラにフラグを渡してトランポリンの数を増やしてみてください。

以下の通り、操作を行います。

1.Unityのメニューから Edit -> Project Settings -> Player Settings を開き、[Player]設定に移動します。

2.iOSの設定を開き、[AOT Compilation Options]までスクロールします。

3.エラーのトランポリンのタイプに応じて、適切な設定を追加します。
・「Ran out of trampolines of type 0」の場合、「ntrampolines = 2048」を追加します
・「Ran out of trampolines of type 1」の場合、「nrgctx-trampolines = 2048」を追加します
・「Ran out of trampolines of type 2」場合は、「nimt-trampolines = 512」を追加します

エラーが続く場合は、エラーが消えるまで数字を増やします。
このエラーメッセージの詳細については、Xamarinのドキュメントを参照してください。
developer.xamarin.com

パイプラインを構築する

Hdg Remote Debug には BuildHelpers ヘルパークラスが付属しています。
これはビルドパイプラインで使用して、最終ビルドでプラグインを自動的に有効または無効にすることができます。
(Unityは、プラグインディレクトリ内のDLL を常にコンパイルおよびリンクします)

このクラスには4つの機能があります。

・WriteRemoteDebugLinkXml - link.xml を Hdg Remote Debug ディレクトリに書き込み、削除されないようにします。
・RemoveRemoteDebugLinkXml - 上記で作成した link.xml を削除します。
・DisableRemoteDebug - リモートデバッグDLLを無効にして、プロジェクトに組み込まないようにします。
・EnableRemoteDebug - 上記で無効にしたリモートデバッグDLLを再度有効にします。

Hdg Remote Debug が有効化、構築、およびリンクされていることを確認する場合は、ビルドを開始する前に WriteRemoteDebugLinkXml を呼び出し、ビルドの完了後に RemoveRemoteDebugLinkXml を呼び出します。

Hdg Remote Debug が無効で、リンクされていないことを確認する場合は、ビルドを開始する前に DisableRemoteDebug を呼び出し、ビルドの完了後に EnableRemoteDebug を呼び出します。

注意事項と制限事項

・現在、列挙型は機能しません。

・UWP DLLをインポートすると、Unityのログに次の例外が表示される場合があります。
 これはUnityのAPIアップデーターのバグのようであり、最終ビルドには影響を与えないようです。

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.

・現在、コンソールはサポートされていません。
 (動作する場合と動作しない場合があります。現在、これをテストする機能はありません)

・カスタムインスペクターは表示されません。
 (Hdg Remote Debug は自身のカスタム階層とインスペクタービューを描画します)

・サーバーは GameObject を DontDestroyOnLoad としてマークするため、メモリ内に残り続けます。

・Unityのバグのため、現時点では、手動でロードされたリソースも階層に表示されます。このバグは5.3.4p3で修正されました。
 これは Hdg Remote Debug が現在のシーンのルートゲームオブジェクトのリストを収集するために使用する SceneManagement.GetRootGameObjects のバグが原因です。

・DontDestroyOnLoad オブジェクトはサーバーに手動で追加する必要があります。
 「DontDestroyOnLoadオブジェクト」のセクションを参照してください。

・ライブ接続でサーバーを実行するとパフォーマンスが低下します。
 サーバーは1秒ごとに現在の GameObjects のリストをエディターに送り返し、GameObject を選択すると全てのコンポーネントとシリアル化されたフィールドも送り返します。
 これらはやや高価な操作であり、残念ながらいくつかのメモリ割り当ても発生します。
 サーバーはリフレクションを使用してフィールドを検索し、Mono は多くのリフレクションメソッドを使用するときに割り当てを行います。
 従って、プロファイリングを行うときは Hdg Remote Debug を切断するか、RemoteDebugServer GameObject を無効にすることをお勧めします。