Version: 2020.2
言語: 日本語
NetworkBehaviour コールバック
クライアントとサーバーへの対処

ネットワークメッセージ

ノート: UNet は非推奨となり、今後 Unity から削除される予定です。新しいシステムが開発中です。詳細は ブログFAQ を参照してください。

「高レベル」コマンドと遠隔手続き呼び出し (RPC) に加えて、生のネットワークメッセージも送信することが可能です。

MessageBase と呼ばれるクラスは、シリアライズ可能なネットワークメッセージクラスを作成するために拡張することができます。このクラスは、パラメーターとして reader と writer のオブジェクトを取る SerializeDeserialize 関数を持っています。開発者はこれらの関数を自分で実装することもできますが、ネットワークシステムによって自動的に作成される、コード生成による実装に任せることもできます。基本クラスは以下の通りです。

public abstract class MessageBase
{
    // reader のコンテンツをメッセージにデシリアライズします
    public virtual void Deserialize(NetworkReader reader) {}

    // メッセージのコンテンツを writer にシリアライズします
    public virtual void Serialize(NetworkWriter writer) {}
}

Message のクラスには、基本型、構造体、配列、Unity のほとんどの通常の型 (Vector3 など) のメンバーが含まれます。複雑なクラスやジェネリックのコンテナのメンバーは含まれません。コード生成による実装に任せたい場合は、型がパブリックに見えるようにしておく必要があります。

一般的なタイプのネットワークメッセージのためにビルトインのメッセージクラスがあります。

メッセージを送信するには、NetworkClientNetworkServerNetworkConnection クラスの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 クラス

ErrorMessage クラスもあり、これは MessageBase から派生します。このクラスは、クライアントおよびサーバーのエラーコールバックへ渡されます。

ErrorMessage クラスの errorCodeNetworking.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);
    }
}

NetworkBehaviour コールバック
クライアントとサーバーへの対処