Note: UNet is deprecated, and will be removed from Unity in the future. A new system is under development. For more information and next steps see this blog post. |
Unity のネットワークのサーバーが権限を持つシステムでは、サーバーは NetworkServer.Spawn 関数を使用して、Network Identity コンポーネントを持つゲームオブジェクトをスポーンする必要があります。このようにすることにより、ゲームオブジェクトに NetworkInstanceId を割り当て、サーバーに接続するクライアント上にゲームオブジェクトを作成します。
注意: NetworkBehaviour はゲームオブジェクトに直接加えることのできるコンポーネントではありません。そうではなく、NetworkBehaviour
(デフォルトの MonoBehaviour
の代わりに) を継承するスクリプトを作成する必要があります。次に、このスクリプトをコンポーネントとしてゲームオブジェクトに加えます。
プロパティ | 説明 |
---|---|
isLocalPlayer |
ゲームオブジェクトがローカルクライアントのプレイヤーである場合は True を返します。 |
isServer |
ゲームオブジェクトがサーバー上で動作し、スポーンされている場合は True を返します。 |
isClient |
ゲームオブジェクトがクライアント上にあり、サーバーによってスポーンされている場合は True を返します。 |
hasAuthority |
このオブジェクトが権限を持つゲームオブジェクト (つまり、同期するときに、変更の元となるオブジェクト) である場合、True を返します。サーバー上では、大抵のゲームオブジェクトが True を返します。ただし、NetworkIdentity の localPlayerAuthority が True の場合、権限はプレイヤーのクライアントにあり、この値はサーバー上ではなく、クライアント上で True になります。 |
netId |
ゲームオブジェクトの独自のネットワーク ID で、ランタイムにサーバーによって割り当てられます。 ネットワークセッション内ですべてのゲームオブジェクトに与えられる一意の ID です。 |
playerControllerId |
NetworkBehaviour スクリプトに関連づけられたプレイヤーの ID です。 |
connectionToServer |
Network Identity コンポーネントに関連付けられた NetworkConnection で、ゲームオブジェクトに設定されます。これは、クライアント上のプレイヤーオブジェクトのみに有効です。 |
connectionToClient |
Network Identity コンポーネントに関連付けられた NetworkConnection で、ゲームオブジェクトに設定されます。これは、サーバー上のプレイヤーゲームオブジェクトのみに有効です。 |
localPlayerAuthority |
この値は Network Identity コンポーネント上で設定され、利便性のため、スクリプトを使用する場合は NetworkBehaviour スクリプトを使ってアクセス可能です。 |
NetworkBehaviour スクリプトは以下の機能を持っています。
変数の同期
ネットワークコールバック
サーバー関数とクライアント関数
コマンドの送信 (Command)
クライアントの RPC 呼出し (ClientRPC)
ネットワーク化されたイベント
NetworkBehaviour スクリプトのメンバー変数をサーバーからクライアントに対し同期できます。このシステムではサーバーに権限があるため、同期はサーバーからクライアントへの方向でのみ行われます。
SyncVar 属性を使用して、メンバー変数に同期済みのタグを付けます。同期される変数には、任意の基本型 (bool、byte、sbyte、char、decimal、double、 Float、int、uint、long、ulong、short、ushort、string) を使用できますが、クラス、リスト、その他のコレクションは使用できません。
public class SpaceShip : NetworkBehaviour
{
[SyncVar]
public int health;
[SyncVar]
public string playerName;
}
サーバー上で SyncVar
の値が変更される場合、サーバーはゲーム内の準備完了したすべてのクライアントに新しい値を自動的に送信し、それらのクライアント上の対応する SyncVar
値を更新します。ゲームオブジェクトがスポーンされる場合、ゲームオブジェクトはサーバーから送信されるすべての SyncVar
属性が最新の状態でクライアント上に作成されます。
注意: クライアントからサーバーに要求を行うには、同期された変数ではなく コマンド を使用する必要があります。詳細は、コマンドの送信に関するドキュメントを参照してください。
さまざまなネットワークイベントを NetworkBehaviour 上で実行するビルトインのコールバック関数があります。これらは基本クラスの仮想関数であるため、以下のようにオーバーライドして独自のコードに使用することができます。
public class SpaceShip : NetworkBehaviour
{
public override void OnStartServer()
{
// クライアントのものを無効にします
}
public override void OnStartClient()
{
// クライアントイベントを設定。効果を有効にします
}
}
ビルトインのコールバック は以下の通りです。
OnStartServer - ゲームオブジェクトがサーバー上で生成されるとき、またはシーンのゲームオブジェクトのためにサーバーが起動されたときに呼び出されます。
OnStartClient - ゲームオブジェクトがクライアント上で生成されるとき、または、クライアントがシーンのゲームオブジェクトのためにサーバーに接続するときに呼び出されます。
OnSerialize - 状態を取得してサーバーからクライアントに送信するために呼び出されます。
OnDeSerialize - クライアント上のゲームオブジェクトに状態を適用するために呼び出されます。
OnNetworkDestroy - サーバーがゲームオブジェクトを除去するときにクライアント上で呼び出されます。
OnStartLocalPlayer - ローカルクライアント上のプレイヤーゲームオブジェクトのため (のみ) にクライアント上で呼び出されます。
OnRebuildObservers - ゲームオブジェクトのオブザーバーのセットが再構築されるときにサーバー上で呼び出されます。
OnSetLocalVisibility - ゲームオブジェクトの可視性がローカルクライアントに対して変更されるときに、クライアントやサーバー上で呼び出されます。
OnCheckObserver - 新しいクライアントの可視性の状態を確認するためにサーバーで呼び出されます。
ピアホストの設定では、クライアントの 1 つがホストとクライアントの両方として動作している場合に、同じゲームオブジェクト上で OnStartServer
と OnStartClient
の両方が呼び出されることに注意してください。これらの関数は、サーバーへの影響を抑制したり、クライアント側のイベントを設定するなど、クライアントかサーバーいずれかに特有の処理に役立ちます。
NetworkBehaviour スクリプトのメンバー関数をカスタムの属性でタグ付けし、サーバーのみ、または、クライアントのみと指定することができます。
using UnityEngine;
using UnityEngine.Networking;
public class SimpleSpaceShip : NetworkBehaviour
{
int health;
[Server]
public void TakeDamage( int amount)
{
// サーバーでのみ作動します
health -= amount;
}
[ServerCallback]
void Update()
{
// コールバックを発します- サーバーでのみ実行されます
}
[Client]
void ShowExplosion()
{
// クライアントでのみ実行します
}
[ClientCallback]
void Update()
{
// コールバックを発します- クライアントでのみ実行されます
}
}
[Server]
と [ServerCallback]
はクライアントがアクティブでないときには、即座に実行されます。同様に、[Client]
と [ClientCallback]
はサーバーがアクティブでないときには、即座に実行されます。
[Server]
と [Client]
属性は、独自のカスタムコールバック関数用です。それらはコンパイルタイムエラーを出しませんが、誤ったスコープで呼び出されると警告のログメッセージを出力します。
[ServerCallback]
と [ClientCallback]
属性は、ビルトインのコールバック関数用です。それらは Unity によって自動的に呼び出されます。これらの属性が原因で警告が発生することはありません。
詳細は、以下の属性に関するスクリプトリファレンスを参照してください。
サーバー上でコードを実行するには、コマンド を使用します。高レベル API はサーバー権限のシステムのため、コマンドはクライアントがサーバー上のコードを起動する唯一の方法です。
プレイヤーゲームオブジェクトのみが、コマンドを送信できます。
クライアントのプレイヤーゲームオブジェクトがコマンドを送信する場合、コマンドはサーバー上の対応するプレイヤーゲームオブジェクト上で実行されます。このルーティングは自動的に発生するため、クライアントが違うプレイヤーにコマンドを送信するのは不可能です。
コード内で コマンド を定義するには、以下を含む関数を作成する必要があります。
Cmd
で始まる名前
[Command]
属性
例:
using UnityEngine;
using UnityEngine.Networking;
public class SpaceShip : NetworkBehaviour
{
bool alive;
float thrusting;
int spin;
[ClientCallback]
void Update()
{
// このコードはクライアント上で実行され、入力を収集します
int spin = 0;
if (Input.GetKey(KeyCode.LeftArrow))
{
spin += 1;
}
if (Input.GetKey(KeyCode.RightArrow))
{
spin -= 1;
}
// サーバーで実行されるコードを起動します
CmdThrust(Input.GetAxis("Vertical"), spin);
}
[Command]
public void CmdThrust(float thrusting, int spin)
{
// このコードが Update() の後に呼び出された後に
// コードが実行されます
if (!alive)
{
this.thrusting = 0;
this.spin = 0;
return;
}
this.thrusting = thrusting;
this.spin = spin;
}
}
コマンドは、単に通常通りにクライアント上の関数を呼び出すだけで呼び出されます。クライアント上でコマンド関数を実行する代わりに、サーバ上にある対応するプレイヤーゲームオブジェクトで自動的にコマンド関数が呼び出されます。
つまり、コマンドはタイプセーフで、ビルトインのセキュリティーとプレイヤーへのルーティング機能を持ち、引数の効率的なシリアライゼーションを使用して高速で呼び出すことができます。
クライアントの RPC 呼び出しは、サーバーのゲームオブジェクトがクライアントのゲームオブジェクトに何かを発生させるための方法です。
クライアントの RPC 呼び出しは、プレイヤーゲームオブジェクトに制限されているわけではありません。Network Identity コンポーネントを持つすべてのゲームオブジェクトで呼び出すことが可能です。
コード内で クライアントの RPC 呼び出し を定義するには、以下のような関数を作成する必要があります。
Rpc
で始まる名前を持っていること
[ClientRPC]
属性をもっていること
例:
using UnityEngine;
using UnityEngine.Networking;
public class SpaceShipRpc : NetworkBehaviour
{
[ServerCallback]
void Update()
{
// サーバー上で実行するコードです
int value = UnityEngine.Random.Range(0,100);
if (value < 10)
{
// すべてのクライアント上で RpcDoOnClient 関数を発生させます
RpcDoOnClient(value);
}
}
[ClientRpc]
public void RpcDoOnClient(int foo)
{
// すべてのクライアント上で実行されます
Debug.Log("OnClient " + foo);
}
}
ネットワーク化されたイベント は クライアントの RPC 呼び出しのようなものです。ただし、ゲームオブジェクト上の関数を呼び出す代わりに、イベントを発生させます。
ネットワーク化されたイベントを使って、イベントが発生するときのコールバックを設定するスクリプトを作成できます。
コード内で ネットワーク化されたイベント を定義するには、以下のような関数を作成する必要があります。
Event
で始まる名前を持っていること
[SyncEvent]
属性をもっていること
イベントを使用して、他のスクリプトで拡張可能な強力なネットワーク化されたゲームシステムを構築できます。この例は、クライアントの効果のスクリプトがサーバーの Combat スクリプトによって生成されたイベントにどのように応答するかを示しています。
SyncEvent は、Commands と ClientRPC 呼出しが派生する基本クラスです。独自に作成した関数で SyncEvent 属性を使用して、独自のイベントを利用するネットワーク化したゲームコードを作成できます。SyncEvent を使用して、Unity の Multiplayer 機能を拡張し、自身のプログラムのスタイルに合わせることができます。以下はその例です。
using UnityEngine;
using UnityEngine.Networking;
// サーバースクリプト
public class MyCombat : NetworkBehaviour
{
public delegate void TakeDamageDelegate(int amount);
public delegate void DieDelegate();
public delegate void RespawnDelegate();
float deathTimer;
bool alive;
int health;
[SyncEvent(channel=1)]
public event TakeDamageDelegate EventTakeDamage;
[SyncEvent]
public event DieDelegate EventDie;
[SyncEvent]
public event RespawnDelegate EventRespawn;
[ServerCallback]
void Update()
{
// 再スポーンすべきかを確認
if (!alive)
{
if (Time.time > deathTimer)
{
Respawn();
}
return;
}
}
[Server]
void Respawn()
{
alive = true;
// サーバーからすべてのクライアントに再スポーンイベントを送信
EventRespawn();
}
[Server]
void EventTakeDamage(int amount)
{
if (!alive)
return;
if (health > amount) {
health -= amount;
}
else
{
health = 0;
alive = false;
// すべてのクライアントに Die イベントを送信
EventDie();
deathTimer = Time.time + 5.0f;
}
}
}
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.