Unityにはリアルタイムに、ネットワークを介してオブジェクトの位置などを同期する仕組みが用意されています。
Hello Worldはとても簡単で、NetworkView
コンポーネントを該当のオブジェクトにアタッチするだけです。
実際にはいくつかの分岐処理などを書かないとなりませんが、ネットワークを通してデータのやり取りをする部分などはほぼUnityが対応してくれます。これはとても便利な機能です。さすがUnity。
(ちなみにこちらの記事を参考にさせていただきました)
セットアップ手順
- ネットワークを介して操作したいオブジェクトをPrefab化する
- 該当オブジェクトに
NetworkView
コンポーネントをアタッチする - NetworkManager的なオブジェクトを作り、操作するためのスクリプトをアタッチする
-
Network
クラスのメソッドを用いてセットアップする- 具体的には
Network.Instanciate
、Network.Destroy
、Network.Connect
、Network.InitializeServer
メソッドなどを用いる
- 具体的には
具体的に見て行きましょう。
Prefab化する
このあたりはネットワーク関係なく通常の手順ですね。
Prefab化することでスクリプトから動的に生成することが可能となります。
ただひとつ注意点として、通常はInstantiate
を使ってインスタンス化しますが、NetworkView
を介して操作するオブジェクトはNetwork.Instantiate
メソッドを使ってインスタンス化します。
(基本的な引数はInstantiate
と同様、第4引数にグループをint
型で指定します)
Network.Instantiate(objectPrefab, objectPrefab.transform.position, objectPrefab.transform.rotation, 1);
NetworkView
コンポーネントをアタッチする
通常通り、Add Component
でNetworkView
と検索すると出てくるコンポーネントをアタッチします。
基本的にはこれだけです。
NetworkManagerを作る
通常のPrefab同様、Prefab化してコンポーネントをアタッチしても画面にはなにも表示されません。
それを管理するオブジェクトがないからです。
なので、空のオブジェクトでもカメラでもなんでもいいですが、NetworkManagerの役割を担うオブジェクトに、NetworkViewをコントロールするスクリプトをアタッチします。
具体的には、Prefabをインスタンス化する処理と、サーバの起動、クライアントからの接続といった処理を実装します。
using UnityEngine;
using System.Collections;
public class NetworkManager : MonoBehaviour {
public GameObject objectPrefab;
string ip = "127.0.0.1";
string port = "1192";
bool connected = false;
private void CreatePlayer() {
connected = true;
Network.Instantiate(objectPrefab, objectPrefab.transform.position, objectPrefab.transform.rotation, 1);
}
public void OnConnectedToServer() {
connected = true;
}
public void OnServerInitialized() {
CreatePlayer();
}
public void OnGUI() {
if (!connected) {
if (GUI.Button(new Rect(10, 10, 90, 90), "Client")) {
Network.Connect(ip, int.Parse(port));
}
if (GUI.Button(new Rect(10, 110, 90, 90), "Master")) {
Network.InitializeServer(10, int.Parse(port), false);
}
}
}
}
Network.Connectメソッド
こちらはクライアントサイドで実行するものです。Connect
からも分かるように、サーバを起動したのちに実行することでサーバに接続します。
引数はIPアドレスとポート番号です。
Network.Connect(ip, int.Parse(port));
Network.InitializedServerメソッド
こちらも見た通り、サーバサイドとして起動するためのメソッドです。
引数はコネクション数ととポート番号を指定します。第三引数にはNatを使うかのbool値を指定します。
Network.InitializeServer(10, int.Parse(port), false);
RPC(Remote Procedure Call)
さて、以上で位置や回転などは自動的に同期されるようになります。
しかし、例えばキャラクターが移動してなにかしらのアクションを実行するためのメソッドを呼びだそうとするとします。
しかし普通に実装するとこれはうまく行きません。
ネットワーク越しでは直接関数が実行できないからです。
そこで利用されるのがRPC(Remote Procedure Call)と呼ばれる、リモートの関数呼び出しを可能にする技術です。
これはUnityは関係なく、一般的に用いられる方法です。
これをUnityでも利用してリモートでのメソッド呼び出しを可能にします。
具体的には以下のように定義、実行することで実現できます。
定義
[RPC]
void AnyMetho(string name, int num) {
// RPC経由で実行したいメソッド
}
[RPC]
というAttributeを付けることでRPCで利用することを宣言できます。
実行
networkView.RPC("AnyMethod", RPCMode.All, "name", 10);
networkView
のRPC
メソッドを、上記のようにメソッド名やモード、RPCで呼び出したいメソッドの引数を指定して実行することでRPCに対応したメソッドを実行することができます。
※ ここでのnetworkView
はGameObjectにアタッチされているNetworkViewコンポーネントです。NetworkViewコンポーネントがアタッチされているとGetComponent
を実行しなくても参照可能です。