メッセージを送受信する
スタートガイドに書いてある通りに Unity シーンを設定したら、メッセージの送受信を行う準備ができています。
コンセプト
同じゲームセッション内のクライアント間でメッセージを送り合う際に、3 つのプロトコルを使用することができます。
ホストメッセージ
ホストメッセージはホストのみ送信することができます。ホスト以外のプレイヤーがホストメッセージを送ろうとするとエラーが発生します。メッセージはホスト自身を含んだネットワーク上の接続している全てのクライアントに送信されます。
プレイヤーメッセージ
プレイヤーメッセージは全てのクライアントが送ることができます。このメッセージは、送り主以外のネットワーク上の接続している全てのクライアントに送信されます。メッセージを受け取るためのコールバックは、送信者のローカルでのみ呼び出されることに注意してください。これは、あくまでもネットワークトラフィックを減らすためのものです。
プレイヤーからホストへのメッセージ
各プレイヤーからホストへのメッセージは、どのクライアントから送ることができます。メッセージ自体は、ホストにのみ送信されます。
Host To Player Message
Host To Player Message can only be sent by the host. The message will be sent only to one specific client that is specified from the input parameter.
NetworkMessage を定義する
メッセージを送受信するために、ネットワークメッセージを定義する必要があります。
// Networking SDK uses MessagePack to do serialization.
// Read more about MessagePack here:
// https://github.com/neuecc/MessagePack-CSharp
using MessagePack;
using PretiaArCloud.Networking;
// NetworkMessage is an attribute used to turn a class/struct to a NetworkMessage.
[NetworkMessage]
// MessagePackObject is an attribute used for setting this as a serialization target
// The SDK will automatically generate the serialization code for all classes/structs
// that have this attribute based on the key attribute.
[MessagePackObject]
public struct NetworkInputMsg
{
// The key attribute is applied to any fields/properties
// that needs to be serialized.
[Key(0)]
public float HorizontalAxis;
// The key attribute requires an int index for every fields/properties.
// The keys need to be unique from each other.
[Key(1)]
public float VerticalAxis;
public NetworkInputMsg(float horizontalAxis, float verticalAxis)
{
HorizontalAxis = horizontalAxis;
VerticalAxis = verticalAxis;
}
}
メッセージを送受信する
NetworkMessage を定義したら、そのタイプのメッセージを送り始めることができます。
using PretiaArCloud.Networking;
using UnityEngine;
public class NetworkInputController : MonoBehaviour
{
private IGameSession _gameSession;
private async void OnEnable()
{
// Get an instance of IGameSession.
_gameSession = await NetworkManager.Instance.GetLatestSessionAsync();
// Register a callback when receiving a message of type NetworkInputMsg.
_gameSession.PlayerMsg.Register<NetworkInputMsg>(ApplyInput);
// It is a good practice to register callbacks meant for the host
// only if the client is appointed as a host.
// This can be done by using OnHostAppointment event.
_gameSession.OnHostAppointment += RegisterHostCallbacks;
}
private async void Start()
{
// Wait until we have a working IGameSession instance before sending messages
await _gameSession.WaitForConnectionAsync();
// Send messages!
_gameSession.PlayerMsg.Send(new NetworkInputMsg(0f, 1f));
_gameSession.HostMsg.Send(new NetworkInputMsg(0f, 1f));
}
private void OnDisable()
{
if (_gameSession != null)
{
// Don't forget to Unregister the callback!
_gameSession.PlayerMsg.Unregister<NetworkInputMsg>(ApplyInput);
_gameSession.HostMsg.Unregister<NetworkInputMsg>(Host_ApplyInput);
_gameSession.OnHostAppointment -= RegisterHostCallbacks;
// Unregister host callbacks.
if (_gameSession.IsHost)
{
_gameSession.HostMsg.Unregister<NetworkInputMsg>(Host_ApplyInput);
}
}
}
// Register host only callbacks here.
private void RegisterHostCallbacks()
{
// We can register different callbacks for the same message type, but different protocol type.
_gameSession.HostMsg.Register<NetworkInputMsg>(Host_ApplyInput);
}
// This function will be called every NetworkInputMsg that is received from the PlayerMsg protocol.
// The user ID of the sender can also be accessed from PlayerMsg and PlayerToHostMsg callback
private void ApplyInput(NetworkInputMsg msg, uint sender)
{
// Do something important
}
// This function will be called every NetworkInputMsg that is received from the HostMsg protocol.
// Note that the user ID of the sender cannot be accesed from a HostMsg callback.
// As a convention, HostMsg callbacks should have a "Host_" prefix.
private void Host_ApplyInput(NetworkInputMsg msg)
{
// Do something important
}
}
送信前にメッセージをキューに積むことも可能です。これによりネットワークトラフィックの負荷を減らすことができます。
_gameSession.PlayerMsg.Enqueue(new NetworkInputMsg(0f, 1f));
_gameSession.PlayerMsg.Enqueue(new NetworkInputMsg(0f, 1f));
_gameSession.PlayerMsg.SendQueue();
// This can be done with any of the protocols.
// e.g:
// _gameSession.HostMsg.Enqueue(..);
// _gameSession.HostMsg.Enqueue(..);
// _gameSession.HostMsg.SendQueue();
無事に最初のネットワークメッセージの送受信に成功しました!