UNETでプレイヤー以外のオブジェクトにCommand権限を持たせる


UNETで通信するゲームを作る際に、プレイヤー以外のオブジェクトでCommand関数を実行しようとした時に、Trying to send command for object without authority.と出たときの解決法。

結論

結論からいうとプレイヤー以外のオブジェクトの権限を持たせるためには、NetworkServer.SpawnWithClientAuthorityを使って権限と共にSpawnさせる必要があります。

手順

  1. 権限を持たせたいオブジェクトのプレハブにNetworkIdentityをアタッチし、LocalPlayerAuthorityにチェックを入れる
  2. そのプレハブをNetworkManagerのSpawnable Prefabに登録する。
  3. 権限をもったオブジェクトのコンポーネントから先ほどのプレハブをSpawnさせる。たとえばPlayerオブジェクトがWeaponManagerというコンポーネントを持っていたとすれば、下記のスクリプトで権限を持った武器オブジェクトを生成することができます。
  using UnityEngine;
  using UnityEngine.Networking;

  public class PlayerInventoryManager : NetworkBehaviour
  {
    [SerializeField] private GameObject weaponPrefab;

    void Start()
    {
      CmdSpawnWeapon();
    }

    [Command]
    void CmdSpawnWeapon()
    {
        var go = Instantiate(weaponPrefab, transform.position, Quaternion.identity);
        NetworkServer.SpawnWithClientAuthority(go, connectionToClient);
    }
  }

権限を持たせられないやり方

  • NetworkIdentityのLocalPlayerAuthorityにチェックを入れたオブジェクトを最初からシーンに配置する
  • 普通にSpawnする(サーバー側だと権限があるが、クラアント側だと権限がない)

NetworkIdentity.AssignClientAuthorityを使えば他のやり方でオブジェクトに権限を持たせることができるのかもしれません