littlewing

人間とコンピューターとメディアの接点をデザインするために考えたこと

HoloLensのSharingに自作のCustomMessagesを追加する方法

HoloLens

HoloLens開発につかえる HoloToolkit-Unityの複数台での空間共有機能 Sharing において自作オブジェクトを同期したり自作メッセージを飛ばし あうための方法のメモ。

  • 前提がいろいろぶっ飛んでますが、自分用のメモに書いたものを公開。
  • エミュレーターと実機でシェアリングのテストもできます。
  • OSCの開発に慣れている人には、結構簡単かも。ほぼOSCっぽい仕様です。

CustomMessages.cs のカスタマイズ手順

イベントの送信方法(オリジナルのイベントメッセージを追加)

1. 新しTestMessageID を定義する
//(CustomMessages.cs) TestMessageID を追加する。
public enum TestMessageID : byte
{
   HeadTransform = MessageID.UserMessageIDStart,
   //ここ(HeadTransform とMaxの間)に
   //追加したいイベントのメッセージIDを追加する。
   StageTransform,//追加したメッセージID

   Max
}
2. 追加したいメッセージのメソッドを追加する。
//(CustomMessages.cs) にメソッドを追加
    public void SendStageTransform(Vector3 position, Quaternion rotation)
    {
        // If we are connected to a session, broadcast our head info
        if (this.serverConnection != null && this.serverConnection.IsConnected())
        {
            // Create an outgoing network message to contain all the info we want to send
            NetworkOutMessage msg = CreateMessage((byte)TestMessageID.StageTransform);

            AppendTransform(msg, position, rotation);

            // Send the message as a broadcast, which will cause the server to forward it to all other users in the session.
            this.serverConnection.Broadcast(
                msg,
                MessagePriority.Immediate,
                MessageReliability.ReliableOrdered,
                MessageChannel.Avatar);
        }
    }
3. イベントを発生させたい別のスクリプトで CustomMessagesのメソッドを呼び出す
//(AnotherScript.cs)
CustomMessages.Instance.SendStageTransform(transform.localPosition, transform.localRotation);

イベント受信について

  • 受信側のスクリプトの先頭に以下を追加する必要もあります。
//(AnotherScript.cs)
using HoloToolkit.Sharing;
using HoloToolkit.Sharing.Tests;
  • イベントの受信はCustomMessages.csのOnMessageReceivedを経由して、コールバックを受け取ります。
//(CustomMessages.cs) に、このコードは存在しています。
    void OnMessageReceived(NetworkConnection connection, NetworkInMessage msg)
    {
        byte messageType = msg.ReadByte();
        MessageCallback messageHandler = MessageHandlers[(TestMessageID)messageType];
        if (messageHandler != null)
        {
            messageHandler(msg);
        }
    }
  • イベントを受信したいスクリプトのStart()メソッドでにコールバックを設定します。
//(AnotherScript.cs)
void start(){
     // ......
     
     CustomMessages.Instance.MessageHandlers[CustomMessages.TestMessageID.StageTransform] = this.OnStageTransfrom;
     // ......
}
  • 実際のコールバックを受け取るメソッドを定義します。
//(AnotherScript.cs)

    /// <summary>
    /// When a remote system has a transform for us, we'll get it here.
    /// </summary>
    /// <param name="msg"></param>
    void OnStageTransfrom(NetworkInMessage msg)
    {
        // We read the user ID but we don't use it here.
        msg.ReadInt64();

        transform.localPosition = CustomMessages.Instance.ReadVector3(msg);
        transform.localRotation = CustomMessages.Instance.ReadQuaternion(msg);

        //add any scripts you want.

    }
  • 上記の受信メソッドの例では、CustomMessages.Instance.ReadXXXを使ってメッセージを読み取っていますが、直接msg.ReadXXX()を使って値を取得することもできます。
//(AnotherScript.cs)
//receive event
void OnStageValues(NetworkInMessage msg){
    
    // We read the user ID but we don't use it here.
    msg.ReadInt64();
    
    H = msg.ReadInt32 ();
    D = msg.ReadInt32 ();
    T = msg.ReadInt32 ();
    selected = msg.ReadInt32 ();
}

参考にした情報

MixedRealityToolkit-Unity/README.md at master · Microsoft/MixedRealityToolkit-Unity · GitHub