tanaka's Programming Memo

プログラミングについてのメモ。

Unity5.1 ネットワークシステムのRemote Actions

前へ | 次へ

UNet Unity5.1からの新しいネットワークシステム
Unity5.1のネットワークマニュアル斜め読み(2)
UNet NetworkManagerの利用
Unity5.1 ネットワークシステムのオブジェクト生成
Unity5.1 ネットワークシステムの状態同期
Unity5.1 ネットワークシステムのRemote Actions
Unity5.1 ネットワークシステム PlayerObjects
Unity5.1 ネットワークシステム Object Visibility
Unity5.1 ネットワークシステム Network Messages
Unity5.1 ネットワークシステム Matchmaker
Unity5.1 ネットワークシステム Scene Objects
Unity5.1 ネットワークシステム:シングルプレイヤーゲームを多人数に対応させる
Unity5.1 ネットワークシステム Multiplayer Lobby
Unity5.1 ネットワークシステム Network Clients and Servers
Unity5.1 ネットワークリファレンス概要

公式サイトの以下のページの斜め読みメモです。
Unity - マニュアル: Remote Actions

リモート動作(Remote Actions)

ネットワークシステムは、ネットワークを介して動作を行うための方法があります。この手の動作をRemote Procedure Calls(RPC)などと呼びます。ネットワークシステムには2種類のRPCがあります。Commandsは、クライアントから呼ばれ、サーバー上で実行されます。ClientRpcはサーバー上で呼ばれ、クライアント上で実行されます。

図が公式サイトにあります。

Commands

Commandsはクライアント上のプレイヤーオブジェクトからサーバー上のプレイヤーオブジェクトに送られます。安全性のため、Commandsはプレイヤーオブジェクト本人からのみ送信できます。そのため他のプレイヤーオブジェクトを操作することはできません。Commands用の関数を作成する場合は、[Command]属性を設定した上で、関数名を"Cmd"で始めます。設定した関数は、クライアント上で呼ばれるとサーバー上で動作するようになります。Command関数が持つ引数はすべて自動的にサーバーに送信されます。

Command関数の名前はすべて"Cmd"から始まるので、コードを読むときにCommand関数であることがわかりやすくなります。この関数は特殊であり、通常の関数のようにローカルで実行されることはありません。

以下、プログラム例の公式サイトからの抜粋です。

class Player : NetworkBehaviour
{

    public GameObject bulletPrefab;

    [Command]
    void CmdDoFire(float lifeTime)
    {
        GameObject bullet = (GameObject)Instantiate(
            bulletPrefab, 
            transform.position + transform.right,
            Quaternion.identity);
            
        var bullet2D = bullet.GetComponent<Rigidbody2D>();
        bullet2D.velocity = transform.right * bulletSpeed;
        Destroy(bullet, lifeTime);

        NetworkServer.Spawn(bullet);
    }

    void Update()
    {
        if (!isLocalPlayer)
            return;

        if (Input.GetKeyDown(KeyCode.Space))
        {
            CmdDoFire();
        }

    }
}


毎フレームでCommand関数を呼び出すのは注意が必要です。ネットワークに大きな負担をかけることになります。

初期設定では、Commandsはデータを保証する0チャンネルで送信されます。つまり初期設定ではすべてのデータが信頼性の高いチャンネルでサーバーに送信されることになります。これは[Command]属性の"Channel"パラメータで変更することができます。この値はint型でチャンネル番号を表します。

チャンネル1もまた初期設定で用意されており、これは信頼性のないチャンネルです。パケットロスなどが発生しても構わないようなデータは以下のようにしてチャンネル1で送信することができます。

    [Command(channel=1)]

ClientRpc Calls

ClientRpc callは、サーバー上のオブジェクトからクライアント上のオブジェクトに送信されます。NetworkIdentityを持つspawn済みのオブジェクトであれば、サーバー上のどのオブジェクトからも呼ぶことができます。サーバーが制御権を持つので、これらの呼び出しをサーバーから送ってもセキュリティ上の問題は発生しません。ClientRpc関数を作成するには、[ClientRpc]属性を書いた上で、関数名を"Rpc"で始めます。そうすることで、その関数がサーバー上から呼ばれると、クライアント上で実行されます。すべての引数は自動的にクライアントに渡されます。

ClientRpc関数は"Rpc"から始まるので、関数を見分けるのに便利です。この関数は特殊で、通常の関数のようにローカルで実行されることはありません。

以下、公式サイトのプログラム例の抜粋です。

class Player : NetworkBehaviour
{

    [SyncVar]
    int health;

    [ClientRpc]
    void RpcDamage(int amount)
    {
        Debug.Log("Took damage:" + amount);
    }

    public void TakeDamage(int amount)
    {
        if (!isServer)
            return;

        health -= amount;
        RpcDamage(amount);
    }
}


ゲームがホストとして動作している場合、ホストを兼ねるクライアントから呼び出すClientRpcは、サーバーと同じプロセスでローカルクライアント上で実行されます。この場合のClientRpcコールの振る舞いは、LocalClientとRemoteClientsで同じになります。


前へ | 次へ