メインコンテンツまでスキップ

メッセージを送受信する

スタートガイドに書いてある通りに 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();

無事に最初のネットワークメッセージの送受信に成功しました!