ノート: UNet は非推奨となり、今後 Unity から削除される予定です。新しいシステムが開発中です。詳細は ブログ と FAQ を参照してください。 |
ネットワークシステムにはネットワークを通して処理を実行する方法が用意されています。このような処理は遠隔手続き呼出し (リモートプロシージャコール、RPC) と呼ばれることがあります。ネットワークシステムの RPC には2種類あります。まず、コマンド (Command)。これはクライアントから呼び出し、サーバー上で実行するものです。そして、クライアント RPC 呼び出し (ClientRpc)。これはサーバーから呼び出し、クライアント上で実行するものです。
以下のダイアグラムは遠隔手続きの動作の流れを示しています。
コマンドはクライアントの操作するプレイヤーオブジェクトから、サーバー上にあるプレイヤーオブジェクトへと送信されるものです。セキュリティ上の理由で、コマンドは 自分自身の プレイヤーオブジェクトからのみ送信できます。そのため、他のプレイヤーを操作することはできません。関数をコマンドに導入するためには、カスタム属性 [Command] を追加し、「Cmd」プレフィックスを加える必要があります。これでこの関数はクライアントの呼び出しに応じてサーバー上で動作するようになります。どのような引数であれ、コマンドによって自動的にサーバーに渡されます。
コマンド関数にはプレフィックスの 「Cmd」を必ずつけなければなりません。このプレフィックスは、コマンドを呼び出すコードを見つける際のヒントなのです。つまり、この関数は特別で、通常の関数と同じローカル環境では実行されないということを表しています。
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();
bullet2D.velocity = transform.right * bulletSpeed;
Destroy(bullet, lifeTime);
NetworkServer.Spawn(bullet);
}
void Update()
{
if (!isLocalPlayer)
return;
if (Input.GetKeyDown(KeyCode.Space))
{
CmdDoFire(3.0f);
}
}
}
クライアントからのコマンド送信は毎フレーム実行されることに注意してください。この影響で多くのネットワーク障害が起こる可能性があります。
通常、コマンドはチャンネル 0 で送信されます。これはデフォルトで使用する、信頼できるチャンネルです。そのため通常すべてのコマンドは確実にサーバーへと送信されます。チャンネルは [Command] カスタム属性の「Channel」パラメーターで変更することができます。パラメーターは Int 型で、チャンネル数を表します。
チャンネル 1 は、デフォルトでは信頼性の低いチャンネルとして設定されています。使用するには Command 属性のパラメーターで 1 を設定してください。以下のようになります。
[Command(channel=1)]
Unity 5.2 からは、クライアント権限を持つノンプレイヤーのオブジェクトからコマンドを送信することが可能です。オブジェクトは NetworkServer.SpawnWithClientAuthority でスポーンされているか、NetworkIdentity.AssignClientAuthority で権限を付加する必要があります。これらのノンプレイヤー オブジェクトから送信された Commands は、クライアントに関連するプレイヤーオブジェクト上ではなく、オブジェクトのサーバーインスタンス上で実行されます。
ClientRpc はサーバー上のオブジェクトからクライアントのオブジェクトへと送信されます。この呼び出しは、スポーンされた NetworkIdentity を持つすべてのサーバーオブジェクトから、送信することができます。サーバーには権限があるため、サーバーオブジェクトに対してセキュリティ上の問題なくこれらの呼び出しを送信することができます。関数を ClientRpc に加えるためには [ClientRpc] カスタム属性を加え、「Rpc」プリフィックスを付けてください。これで、この関数はサーバーで呼び出されると、クライアント上で実行されます。どのような 引数も自動的に ClientRpc でクライアントへと渡されます。
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 に対するローカルクライアントとリモートクライアントの挙動は、同じになります。
Command と ClientRpc の呼び出しで渡す引数は、シリアル化されネットワークを介して渡されます。引数として渡せるものは以下の通りです。
遠隔手続きの引数には、スクリプトのインスタンスや Transform のようなゲームオブジェクトの付属コンポーネントを使用できません。ネットワークを介してシリアル化できない、他の型も使用できません。
Did you find this page useful? Please give it a rating:
Thanks for rating this page!
What kind of problem would you like to report?
Thanks for letting us know! This page has been marked for review based on your feedback.
If you have time, you can provide more information to help us fix the problem faster.
Provide more information
You've told us this page needs code samples. If you'd like to help us further, you could provide a code sample, or tell us about what kind of code sample you'd like to see:
You've told us there are code samples on this page which don't work. If you know how to fix it, or have something better we could use instead, please let us know:
You've told us there is information missing from this page. Please tell us more about what's missing:
You've told us there is incorrect information on this page. If you know what we should change to make it correct, please tell us:
You've told us this page has unclear or confusing information. Please tell us more about what you found unclear or confusing, or let us know how we could make it clearer:
You've told us there is a spelling or grammar error on this page. Please tell us what's wrong:
You've told us this page has a problem. Please tell us more about what's wrong:
Thank you for helping to make the Unity documentation better!
Your feedback has been submitted as a ticket for our documentation team to review.
We are not able to reply to every ticket submitted.