仮想と物理とエトセトラ

xRや物理とかごった煮の備忘録的技術ブログ

MLAPIをHoloLensでつかう その3 (物体の操作を共有する)

今回は前回の続きです。

xr-physics-work-etc.hatenablog.com

HoloLensを使った共有に重要な物体の操作に関する共有を行います。

Spawnする物体を用意する

今回はCubeをSpawnし、それを操作します。
まずは、Spawn対象であるCubeを用意します。

Hierarchy上で右クリックし、[3D Object]→[Cube]を選択します。

f:id:napo909:20210717183953p:plain

作成したCubeにNetwork ObjectコンポーネントNetwork TransformコンポーネントObject Manipulatorコンポーネントをアタッチします。
これらをアタッチすることで、MLAPIの共有対象であることと、位置、姿勢を共有すること、手で物体位置を変更することができます。
MaterialはMRTK_Standard_Redを設定しておきます。

f:id:napo909:20210717184736p:plain

作成したオブジェクトをAsset/PrefabsディレクトリにドラッグしてPrefab化します。
Prefabにした後、Cubeのスケールは好みの大きさに変更しておきます。 Hierarchy上のCubeは削除します。

f:id:napo909:20210717185349p:plain

作成したPrefabは、Hierarchy上のNetworkManagerNetwork Prefabsに設定します。
今回追加したオブジェクトはPlayerではないので、Default Player Prefabのチェックを外します。

f:id:napo909:20210717185538p:plain

Spawnする機構を用意する

次に物体をSpawnする機構を用意します。
今回はボタンを押すたびに物体がSpawnするようにします。
MRTK Tool BoxからPressableButtonHoloLens2を選択し、Hierarchy上に追加します。

f:id:napo909:20210717190719p:plain

オブジェクトを参加しているユーザ全員でSpawnできるように、NetworkSpawn.csを作成します。

  • NetworkSpawn.cs
クリックで展開
using UnityEngine;
using MLAPI;
public class NetworkSpawn : NetworkBehaviour
{
    /// <summary>
    /// Spawnさせるプレハブ
    /// </summary>
    [SerializeField]
    private GameObject spawnPrefab;

    public void SpawnObject()
    {
        // Spawnされる場所は、自オブジェクトの1m奥、1m上に設定。
        Vector3 spawnPosition = this.transform.position + new Vector3(0f, 1f, 1f);

        // ローカルでSpawn
        GameObject spawnObject = Instantiate(spawnPrefab, spawnPosition, Quaternion.identity);
        
        // ほかのユーザでもSpawn実施
        spawnObject.GetComponent<NetworkObject>().Spawn();
    }
}

作成したNetworkSpawnコンポーネントをボタンにアタッチし、Onclickで実行されるように設定します。

f:id:napo909:20210718184202p:plainf:id:napo909:20210718184206p:plain

これで、ボタンが押されるとCubeがSpawnするようになりました。

動作確認

今回も前回と同様にHoloLens側でConnect Host、PC側でConnect Clientボタンを押して共有を開始しました。

xr-physics-work-etc.hatenablog.com

Host側であるHoloLens2からSpawnボタンを押しCubeを召喚、PCからHoloLens2側からの操作を確認することができました。

f:id:napo909:20210718185245g:plain

ただし、問題点が3点あります。

  • NetworkTransformがScaleの変更に対応していない。
    → 実装すれば解決可能。
  • Client側から物体の操作はできない。
  • Client側からSpawnボタンを押すと下記エラーが発生して正しくSpawnできない。
    NotServerException: Only server can spawn NetworkObjects

原因としては、Host(Server)側からSpawnしたCubeには、PCであるClient側からの操作権限がないこと、またMLAPIではNetwork共有された物体のSpawn処理(NetworkObject.Spawn())はServer側からしか実行できないことが挙げられます。
そのため、Client側からそれぞれをを実行するためには、Client側からServer側に操作権限取得依頼と、Spawnの依頼を実施する必要があります。
次回は共有対象のオブジェクトの操作権限取得と、Server側にSpawn依頼を行う方法について記載します。