次の方法で共有


クラウド スクリプト プログラマ ガイド

このガイドでは、Mesh Cloud Scripting API と開発者ツールを使用して環境を構築する方法について説明します (これらはUnityのプロジェクトとして開始され、その後 Mesh コレクションにアップロードされます)。 まず、「 Azure でクラウド スクリプト インフラストラクチャを設定する 」を読んで、Mesh Cloud Scripting の概念と基本的なアーキテクチャについて理解することをお勧めします。

このセクションでは、Mesh Cloud Scripting API の機能とインターフェイスについて説明します。これは、環境での動作を駆動するスクリプトを記述するために使用されます。

基本的な DOM 構造

DOM 構造体は、Unity シーンの構造を反映します。 アプリケーションの "Scene" メンバーは、Mesh Cloud Scripting コンポーネントがアタッチされているゲーム オブジェクトに対応します。 次の Mesh Cloud Scripting API クラスは、エディターで作成されたUnity オブジェクトと 1 対 1 でマップされます。

  • GameObject (& 変換コンポーネント) -> TransformNode
  • Light コンポーネント -> PointLightNode、SpotLightNode、DirectionalLightNode
  • アニメーター コンポーネント -> AnimationNode (および派生クラスについては、以下を参照)
  • Box コライダー コンポーネント -> BoxGeometryNode
  • Sphere コライダー コンポーネント -> SphereGeometryNode
  • カプセル コライダー コンポーネント -> CapsuleGeometryNode
  • Mesh コライダー コンポーネント -> MeshGeometryNode
  • Text Mesh Pro コンポーネント -> TextNode
  • Rigidbody コンポーネント -> RigidBodyNode

たとえば、ライト コンポーネント (ポイント ライトに設定) と球コライダーがアタッチされたゲーム オブジェクトを使用してシーンを作成した場合、シーンには、PointLightNode と SphereGeometryNode の 2 つの子を持つ TransformNode が含まれます。

さらに、一部の Mesh Cloud Scripting API オブジェクトには、対応する組み込みのUnity コンポーネントがありません。 これらは、Mesh ツールキット パッケージの一部であるUnityで作成できる追加のコンポーネントです。

  • Mesh Cloud Scripting コンポーネント (前述)
  • WebSlate コンポーネント

Unity DOM を Mesh DOM にマッピングする

Mesh Cloud Scripting API で認識されないコンポーネントを含むシーンを作成できます。 これらは、シーンの Mesh Cloud Scripting DOM には存在しません。 ただし、GameObjects の完全なシーン構造は、DOM API で TransformNodes としてミラー化されます。

Unityは GameObject/component API シェイプを持ちますが、Mesh Cloud Scripting DOM には単一のツリー構造があります。 Mesh Cloud Scripting API の TransformNode には、他の TransformNode またはコンポーネントにマップされる他のノードである可能性がある子があります。 これは、関連付けられたゲーム オブジェクトのコンポーネントとその変換コンポーネントの子のマージされたリストと考えることができます。

Rect Transform

RectTransform (Text Mesh Pro コンポーネントなど) を使用するコンポーネントを追加した場合、ゲーム オブジェクトは Mesh Cloud Scripting シーン グラフの Node として表示されません。 このようなコンポーネントの移動、有効化、無効化は引き続き可能ですが、これを行うには、通常の Transform コンポーネントを使用して、RectTransform を使用して別のゲーム オブジェクトでゲーム オブジェクトをラップする必要があります。

プロパティ変更イベント

階層内の任意のノードで を呼び出 AddPropertyChangedEventHandler すことで、プロパティ変更イベントをサブスクライブできます。 プロパティの名前を文字列として渡す必要があります。

イベントをサブスクライブすることで、すべてのイベントを DomObjectPropertyChanged サブスクライブすることもできます。 これは、DOM 内のプロパティが変更されたときに呼び出されます。

オブジェクトのライフサイクル

ノードは、作成時に親が解除されます。 つまり、シーンまたは子孫の 1 人に子として明示的に追加されるまで、シーンに表示されません。 同様に、ノードの親を null に設定すると、ノードとその子孫がシーンから削除されます。

ノードを一時的に無効にしても、シーン内のどこにあったかを記録しない場合があります。 このため、各ノードには "アクティブ" フラグがあります。 false に設定すると、ノードとその子孫が無効になります。

シーンの一部であるが無効になっているUnityでゲーム オブジェクトとコンポーネントを作成できます。 これらは Mesh Cloud Scripting シーン階層のノードとして表示されますが、アクティブ フラグは false に設定されます。 アクティブ フラグを true に設定すると、Unity シーンで有効になります。

複製と親の再親

ノードは Mesh Cloud Scripting API で複製および再親できます。対応するUnityシーンがそれに応じて更新されます。 ノードを複製すると、そのノードとそのすべての子 (対応するUnity オブジェクト内にある可能性がありますが、Mesh Cloud Scripting には表示されない子を含む) が複製されます。

Unity コンポーネントに対応するノードを複製または再親することができます。 これは、Mesh Cloud Scripting Node の表現に基づいて、これらのUnity コンポーネントを再作成することによって実装されます。 Mesh Cloud Scripting API を使用して作成できるノードのみを複製または再親できます。 Unityでコンポーネントを作成し、対応する Mesh Cloud Scripting Node に反映されないフィールドを設定した場合、ノード自体が複製されると、これらのフィールドは既定値にリセットされます。 このため、Unityで作成されたオブジェクトを操作する変換ノードを複製または再親することをお勧めします。 これらは、元のすべてのUnity設定を常に正しく保持します。

ユーザー

API には、User プロパティを提供するさまざまな場所があります。 プロパティは User.Identifier 、ユーザーが離れ、再参加した場合でも、ユーザーに対して永続的な永続的な識別子文字列です。 ユーザーの表示名には、 を使用して User.DisplayNameアクセスすることもできます。 ユーザーが から接続したイベント ID には、 を介して User.ConnectedEventIdアクセスできます。

開発中に、ユーザーの表示名、識別子、およびイベント ID は、次に示すように、Mesh Cloud Scripting コンポーネント エディターの "開発者設定" でモックできます。

モック ユーザー プロパティ

アバター

アバターは、シーン内のユーザーの表現です。 ユーザーを特定の場所にテレポートしたり、シーン間を移動したり、トリガー ボリュームとの衝突を検出したりするために使用できます。

情報ダイアログ

Mesh Cloud Scripting では、カスタム メッセージを含む Microsoft Mesh アプリケーションの画面領域ダイアログをポップアップ表示できます。 SceneNode には、 の関数が ShowMessageToParticipants(string message, IReadOnlyCollection<Participant> participants)含まれています。 リッチ テキスト タグ は、メッセージ内でテキスト プロパティ (色、太字など) を制御するために使用できます。

入力ダイアログ

Mesh Cloud Scripting では、カスタム メッセージを使用して Mesh イベントの出席者にテキスト入力を要求できます。 CloudApplication は メソッド Task<string> ShowInputDialogToParticipantAsync(string message, Participant participant, CancellationToken token)を提供します。 リッチ テキスト タグ は、メッセージ内でテキスト プロパティ (色や太字など) を制御するために使用できます。

クラス

CloudApplication

インターフェイスは ICloudApplication 、Mesh アプリを開発するための出発点です。 _app変数として "App.cs" で使用できます。 シーンに加えて、 には、 ICloudApplication 使用可能なすべての型の作成関数があります。 他にもいくつかのメソッドがありますが、内部使用用です。

InteractableNode

MeshInteractableSetup は、Mesh ツールキット パッケージの一部であるカスタム Unity コンポーネントです。 Unityのゲーム オブジェクトにアタッチすると、ユーザーがそのゲーム オブジェクトまたはその子のアクティブな衝突可能のいずれかをクリックすると、クリック イベントが発生します。

次に、MeshInteractableSetup コンポーネントをボックス コライダーと同じゲーム オブジェクトに追加する簡単な例を示します。

単純な入力の例

WebSlateNode

WebSlate は、Mesh ツールキット パッケージの一部であるカスタム Unity コンポーネントです。 WebSlate プレハブをシーンに追加するには、メニュー バーから [GameObject>Mesh Toolkit>WebSlate ] を選択します。 WebSlate インスタンスの URL プロパティに割り当てられている Web サイトは、このプレハブの quad にレンダリングされます。

WebSlate プレハブがシーンに追加され、URL が割り当てられている例を次に示します。

        var webSlateNode = Root.FindFirstChild<WebSlateNode>(true);
        webSlateNode.Url = new System.Uri("https://en.wikipedia.org/wiki/Color");

WebSlate の例

クリックのリッスン

クリックするたびにキューブを回転させる単純な Mesh Cloud スクリプトスクリプトを次に示します。 内App.csのスタブ StartAsync メソッドをこのコードに置き換えます。

        private float _angle = 0;

        public Task StartAsync(CancellationToken token)
        {
            // First we find the TransformNode that corresponds to our Cube gameobject
            var transform = _app.Scene.FindFirstChild<TransformNode>();

            // Then we find the InteractableNode child of that TransformNode
            var sensor = transform.FindFirstChild<InteractableNode>();

            // Handle a button click
            sensor.Selected += (_, _) =>
            {
                // Update the angle on each click
                _angle += MathF.PI / 8;
                transform.Rotation = new Rotation { X = 1, Y = 0, Z = 0, Angle = _angle };
            };

            return Task.CompletedTask;
        }

ヒット情報

プロパティ変更イベント引数を調べることで、どのユーザーがコライダーをクリックしたかを確認できます。 また、イベント引数から、クリックの接触法線と位置を読み取ることもできます。 これらの座標は、InteractableNode のローカル座標空間に対して相対的になります。

アニメーター

Unity アニメーターを作成してシーンに追加し、Mesh Cloud Scripting を使用してそれを制御できます。 Mesh ツールキット プラグインは、Unity プロジェクト内のアセットを調べ、見つかった各アニメーターについて、Mesh Cloud Scripting プロジェクトの "AnimationScripts" フォルダーにクラスを生成します。 このクラスは AnimationNode から派生し、Mesh Cloud Scripting からアニメーターを制御するために使用できます。 Unityのゲーム オブジェクトにアニメーターをコンポーネントとして追加すると、生成されたクラスの対応するインスタンスが、対応する TransformNode の子として見つかります。 このクラスの API を使用すると、アニメーターを制御できます。

Mesh Cloud Scripting プログラミング モデルはサーバー権限を持ち、アニメーター機能のごく一部のみをサポートしています。 これは、サーバー上でアニメーターをモデル化し、すべてのクライアントがサーバー モデルと正確に同期することを想定しているためです。 このため、現在サポートされている API は次のとおりです。

  • 状態の設定 (各レイヤーに対応するプロパティがクラス内にあり、アニメーターで使用可能な状態に基づいて列挙型に設定できます)。 状態は、遷移ではなく、すぐに設定されます。
  • Float 変数の設定: Float 変数のみが公開され、アニメーターの "Motion Time" にバインドする目的でのみ公開されます。
  • レイヤー速度の設定

状態内では、Unity シーンで設定できる値に制限なくアニメーション クリップを作成できます。 ループ アニメーション クリップもサポートされています。 AnimationNodes では、アニメーターの次の機能はサポートされていません。

  • 画面切り替え: アニメーターに切り替えを追加すると、Mesh Cloud Scripting API を介してこれらをトリガーすることはできません (サーバーは遷移をモデル化しません)。
  • 変数 (モーション時間を駆動する float 以外)。 遷移ロジックまたは速度乗数を駆動するために使用される変数はサポートされていません。
  • ミラー化された状態、サイクル オフセット、およびフット IK。

遅延結合とアニメーター

クライアントが Mesh イベントに参加すると、実行中のすべてのアニメーション ノードの現在の状態とローカル時刻に同期されます。 実行時間の長いアニメーションが状態で再生されている場合、再生時間は遅延結合時のアニメーションの正しい現在の時刻に設定されます。 ただし、状態でイベントが発生した場合、これらは遅延参加クライアントでは発生しません。 その他のシナリオによっては、想定どおりに動作しない場合があります。たとえば、状態の開始時に AudioSource を有効にしてサウンドをトリガーした場合、その AudioSource は遅延参加クライアントで引き続き有効になりますが、オーディオ クリップの先頭で再生が開始されます。

アニメーターの初期状態

何もしない既定の状態を持つアニメーターを作成することをお勧めします。 シーンがUnityで再生を開始すると、すべてのアニメーターがアクティブになり、既定のアニメーションの再生が開始されます。 これは、Mesh Cloud Scripting Service 接続が発生する前に発生する可能性があります。したがって、これらの状態と動作を同期する方法はありません。

アニメーターの親の再作成と複製

AnimationNodes は、Mesh Cloud Scripting API を使用して作成することはできません。 AnimationNode を作成する唯一の方法は、アニメーター コンポーネントを含むUnityシーンをエクスポートすることです。 AnimationNode を複製または再親しようとすると、このアクションをサポートする方法がないため、エラーが発生します。 AnimationNode の親を複製または再親することは可能です。これは、複製およびにできるUnity Game オブジェクトを含む に対応するためです。

生成されたコードに関する注意事項

生成されたコードは、アニメーター、レイヤー、状態、変数の名前からスペースを削除します。たとえば、変数名 "my var" はコードの "myVar" になります。 このため、有効なコードを生成しないアニメーターを作成できます。 たとえば、"my var" と "myVar" という名前の 2 つの変数がある場合、生成中にエラーが発生し、変数の名前を変更するように求めるメッセージが表示されます。

LightNode

PointLightNode、DirectionalLightNode、SpotLightNode はすべて、Unity Light コンポーネントにマップされます (このコンポーネントの型は、対応する値に設定されます)。 LightNode API を使用して、これらのライトの基本的なパラメーターを設定できます。 また、API を介して手動でライトを作成することもできます。 API を使用してライト ノードを作成すると、Mesh Cloud Scripting API で設定できないパラメーターは既定値のままにされます。

GeometryNode

BoxGeometryNode、SphereGeometryNode、CapsuleGeometryNode、MeshGeometryNode はそれぞれ、Unityの Box コライダー コンポーネント、Sphere コライダー コンポーネント、カプセル コライダー コンポーネント、メッシュ コライダー コンポーネントにマップされます。 また、Mesh Cloud Scripting API を使用して作成することもできます。 Geometry ノードを有効または無効にすると、MeshInteractableSetup がゲーム オブジェクトまたはその親の 1 つにアタッチされている場合、ヒット候補に対する追加と削除が行われます。

API を使用してジオメトリ ノードを作成すると、Mesh API で設定できないパラメーターは既定値のままにされます (たとえば、物理マテリアルは none に設定され、isTrigger は false に設定されます)。

RigidBodyNode

オブジェクトに Rigidbody コンポーネントを追加すると、そのモーションは Mesh Physics のコントロールの下に配置されます。 コードを追加しないと、Rigidbody オブジェクトは重力によって下方向にプルされ、他のオブジェクトとの衝突に反応します。

: GeometryNode.Friction は を返します staticFriction。 ただし、Mesh Cloud Scripting 側で を設定すると、クライアントで と dynamicFriction の両方staticFrictionが更新されます。

ボリュームをトリガーする

ジオメトリ ノードは、プロパティが true に設定されている場合 IsTrigger にトリガー ボリュームとして機能できます。 このフラグは、Unityのコライダーの プロパティに対応IsTriggerしており、実行時に変更することはできません。 ジオメトリがトリガーである場合は、トリガーが生成Enteredされ、Exited開始または停止するアバターが生成されます。

: テレポート ビームを無視できるようにするには、Unity オブジェクトをレイヤにTriggerVolume追加する必要があります。これは、レイヤ内のコライダーがDefaultテレポート ビームをブロックするためです。

TextNode

TextNode は、Unityの TextMeshPro コンポーネントにマップされます。 TextMeshPro コンポーネントをシーンに追加すると、Mesh Cloud Scripting シーン階層に対応する TextNode が存在します。 これにより、実行時にコンポーネントのテキストを設定できます。 TextNode API (太字、斜体、下線、取り消し線、色) を使用して、基本的なテキスト プロパティを変更することもできます。 現時点では、API を使用して TextNode を作成することはできません。Unityのシーンに追加して作成する必要があります。 また、TextNode を直接複製することはできません。代わりに、TextNode の親 TranformNode を複製する必要があります。

メッシュ

メッシュは現在、Mesh Cloud Scripting API の "非表示" コンポーネントです。 これらはUnity エディターで作成でき、親ゲーム オブジェクト/Transform コンポーネントを操作して操作できますが、プログラムで作成したり、Mesh API を使用して実行時にプロパティを編集したりすることはできません。

その他の Mesh クラウド スクリプトに関するトピック

Mesh Cloud Scripting Service へのリソースの追加

Mesh Cloud Scripting Service で使用するリソースを追加する必要がある場合は、埋め込みリソースとして C# プロジェクト ファイルに追加する必要があります。 これを行うには、Visual Studio のプロジェクト UI を使用するか、次の行を .csproj ファイルに直接追加します。

<EmbeddedResource Include="<my_resource_file>" CopyToOutputDirectory="PreserveNewest" />

これは scene.map のパッケージ化方法であり、参照用の .csproj ファイルで確認できます。

メッシュ物理の操作

Mesh Physics は、クライアント間で剛体の動きを同期するように注意します。 Mesh Cloud Scripting TransformNode.Position、、 RigidBody.VelocityTransformNode.RotationRigidBody.AngularVelocity は、最新のシミュレーション状態では更新されません。 ただし、Mesh Cloud Scripting Service で設定されている場合、クライアントは変更を適用します。 1 つのプロパティを変更すると、他のプロパティは変更されません。 たとえば、位置のみが設定されている場合、速度は変更されません。剛体は新しい位置から古い速度で動き続けます。 Mesh Cloud Scripting Service が、剛体の最新のモーション状態で更新されないことを考えると、これらを新しい剛体にのみ設定することをお勧めします。

RigidBodyNodeが複製されている場合TransformNode、複製された本文が登録され、クライアント間の同期のために にMesh Physics引き渡されます。 : 複製された剛体は、元の剛体のシーンの先頭からの位置、回転、速度を持つことになります。 これらが異なる場合は、Mesh Cloud Scripting で明示的に設定する必要があります。

次の手順