1. ホーム
  2. c#

[解決済み】Unity3D. 権限のないオブジェクトに対してコマンドを送信しようとする

2022-01-27 08:16:40

質問

私は多人数参加型のターン制ストラテジーゲームを持っていますが、現在のゲーム状態(誰のターンか等)をコントロールするゲームマネージャーが必要です。このマネージャーは、すべてのクライアントで共通であるべきで、その状態はサーバー上で同期されるべきです。

こんな感じでやってます。 ゲームマネージャーオブジェクトはNetworkBehaviourであり、ローカルプレイヤー権限でもサーバー権限でもないNetworkIdentityを持っています。私はカスタムNetworkManagerを作り、クライアント接続時にゲームマネージャーを生成し、それがサーバーであるかどうかもテストしています。以下はそのコードです。

public override void OnClientConnect(NetworkConnection conn)
    {
        ClientScene.Ready(conn);
        if (NetworkServer.active)
        {
            var manager = Instantiate(MultiplayerManagerPrefab, Vector3.zero, Quaternion.identity) as GameObject;
            var tacticsManager = manager.GetComponent<MultiplayerManagerModel>();
            NetworkServer.RegisterHandler(MsgType.AddPlayer, tacticsManager.CreatePlayerOnServer);
            NetworkServer.Spawn(manager);
        }
        ClientScene.AddPlayer(0);
    }

サーバー上で実行すると、クライアント上にインスタンスが作成され、サーバーからクライアントへ変数が同期され、正常に動作します。しかし、クライアントからコマンドを実行しようとすると、このような警告が表示され、無視されます。

権限のないオブジェクトに対してコマンドを送信しようとしています。 UnityEngine.Networking.NetworkBehaviour:SendCommandInternal(NetworkWriter.NetworkWriter.NetworkWriter), Int32, String)

この Game Manager はプレイヤーの前に生成されることに注意してください。私は何を間違えているのでしょうか?

解決方法は?

あなたのコード断片の横に、警告が表示されます。

<ブロッククオート

を送信しようとしています。 コマンド を、権限のないオブジェクトのために使用しています。

という意味です。 あなたが送信しているのは コマンド を持つオブジェクトから 権限 を、あなた(プレイヤー)は持っていない。

Unityのドキュメントに書かれていること。 コマンド は、クライアント上のプレイヤーオブジェクトから、サーバー上のプレイヤーオブジェクトに送信されます。セキュリティのため コマンド からしか送信できません。 あなたのプレイヤーオブジェクト そのため、他のプレイヤーのオブジェクトを操作することはできません。

しかし

Unityリリース5.2より からコマンドを送信することができます。 ノンプレイヤーオブジェクト クライアント権限を持つ これらのオブジェクトは NetworkServer.SpawnWithClientAuthorityで生成された、あるいは NetworkIdentity.AssignClientAuthorityで権限を設定します。コマンド これらのオブジェクトから送信されたメッセージは、そのオブジェクトのサーバーインスタンス上で実行されます。 クライアントに関連付けられたプレイヤー・オブジェクトではなく ( より ).

では、その解決策とは。 を送信する前に コマンド (を実行する(または コマンド 関数)を使用します。 そのオブジェクトの権限を自分のプレイヤーに割り当てる . こんな感じ

assignAuthorityObj.GetComponent<NetworkIdentity>().AssignClientAuthority(this.GetComponent<NetworkIdentity>().connectionToClient);

" これ が、あなたのプレイヤーオブジェクトに表現されます。を作成した後 コマンド を呼び出すと、次のコードで権限を削除することができます。

 assignAuthorityObj.GetComponent<NetworkIdentity>().RemoveClientAuthority(this.GetComponent<NetworkIdentity>().connectionToClient);

再び、"。 これ は、プレイヤーオブジェクトに表現されます。

重要なお知らせ : 私は通常、オブジェクトの権威を(それを使用したい場合)使用します。 OnTriggerEnter で権限を削除し OnTriggerExit . どのようなイベントでオブジェクトの権限を取得または削除するかは、特定のシナリオに依存します。