重要: UNet は非推奨のソリューションになり、現在、新しい Multiplayer とネットワーキングソリューション (Netcode for GameObjects) が開発中です。詳細は、GameObjects Web サイトの Unity Netcode を参照してください。 |
「高レベル」コマンドと遠隔手続き呼び出し (RPC) に加えて、生のネットワークメッセージも送信することが可能です。
MessageBase と呼ばれるクラスは、シリアライズ可能なネットワークメッセージクラスを作成するために拡張することができます。このクラスは、パラメーターとして reader と writer のオブジェクトを取る Serialize と Deserialize 関数を持っています。開発者はこれらの関数を自分で実装することもできますが、ネットワークシステムによって自動的に作成される、コード生成による実装に任せることもできます。基本クラスは以下の通りです。
public abstract class MessageBase
{
// reader のコンテンツをメッセージにデシリアライズします
public virtual void Deserialize(NetworkReader reader) {}
// メッセージのコンテンツを writer にシリアライズします
public virtual void Serialize(NetworkWriter writer) {}
}
Message のクラスには、基本型、構造体、配列、Unity のほとんどの通常の型 (Vector3 など) のメンバーが含まれます。複雑なクラスやジェネリックのコンテナのメンバーは含まれません。コード生成による実装に任せたい場合は、型がパブリックに見えるようにしておく必要があります。
一般的なタイプのネットワークメッセージのためにビルトインのメッセージクラスがあります。
メッセージを送信するには、NetworkClient、NetworkServer、NetworkConnection クラスのSend()
関数を使用します。これらの関数はすべて同様に機能します。また、Send 関数は、MessageBase から派生したメッセージ ID とメッセージオブジェクトをパラメーターとして取ります。以下のコードでは、ビルトインのメッセージクラスの 1 つを使用したメッセージの送信と処理方法を示しています。
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.Networking.NetworkSystem;
public class Begin : NetworkBehaviour
{
const short MyBeginMsg = 1002;
NetworkClient m_client;
public void SendReadyToBeginMessage(int myId)
{
var msg = new IntegerMessage(myId);
m_client.Send(MyBeginMsg, msg);
}
public void Init(NetworkClient client)
{
m_client = client;
NetworkServer.RegisterHandler(MyBeginMsg, OnServerReadyToBeginMessage);
}
void OnServerReadyToBeginMessage(NetworkMessage netMsg)
{
var beginMessage = netMsg.ReadMessage<IntegerMessage>();
Debug.Log("received OnServerReadyToBeginMessage " + beginMessage.value);
}
}
カスタムのネットワークメッセージのクラスを宣言し、それを使用する例は以下の通りです。
using UnityEngine;
using UnityEngine.Networking;
public class Scores : MonoBehaviour
{
NetworkClient myClient;
public class MyMsgType {
public static short Score = MsgType.Highest + 1;
};
public class ScoreMessage : MessageBase
{
public int score;
public Vector3 scorePos;
public int lives;
}
public void SendScore(int score, Vector3 scorePos, int lives)
{
ScoreMessage msg = new ScoreMessage();
msg.score = score;
msg.scorePos = scorePos;
msg.lives = lives;
NetworkServer.SendToAll(MyMsgType.Score, msg);
}
// クライアントを作成し、サーバーポートに接続します
public void SetupClient()
{
myClient = new NetworkClient();
myClient.RegisterHandler(MsgType.Connect, OnConnected);
myClient.RegisterHandler(MyMsgType.Score, OnScore);
myClient.Connect("127.0.0.1", 4444);
}
public void OnScore(NetworkMessage netMsg)
{
ScoreMessage msg = netMsg.ReadMessage<ScoreMessage>();
Debug.Log("OnScoreMessage " + msg.score);
}
public void OnConnected(NetworkMessage netMsg)
{
Debug.Log("Connected to server");
}
}
この例の中には ScoreMessage
クラスのシリアライゼーションコードはありません。このクラスのシリアライゼーション関数の本体は Unity によって自動的に作成されます。
ErrorMessage クラスもあり、これは MessageBase
から派生します。このクラスは、クライアントおよびサーバーのエラーコールバックへ渡されます。
ErrorMessage クラスの errorCode は Networking.NetworkError 列挙型に対応します。
class MyClient
{
NetworkClient client;
void Start()
{
client = new NetworkClient();
client.RegisterHandler(MsgType.Error, OnError);
}
void OnError(NetworkMessage netMsg)
{
var errorMsg = netMsg.ReadMessage();
Debug.Log("Error:" + errorMsg.errorCode);
}
}