Need help with custom messages

I have been attempting to solve a player - object communication problem using messages, and need to create a custom message that contains both an integer and a string. I tried to follow the example from the documentation, but have been getting inconsistent results and some strange errors.

When running with only a host present, there are no runtime errors, but the string in the message received in the client callback is empty. When running with a host and a client present, if the client sends a message an IndexOutOfRangeException occurs in the server callback.

This is my message handling script. It’s currently attached to my player prefab:

using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.Networking.NetworkSystem;
using System.Collections;

public class RotationHandler : NetworkBehaviour
{

    public class DataMsgType
    {
        public static short ROT_MSG = MsgType.Highest + 1;
    };

    public class RotationMessage : MessageBase
    {
        public int dir;
        public string obj;
    };

    NetworkClient client;

    public GameObject datum;

    // Use this for initialization
    void Start ()
    {
        NetworkManager netManager = GameObject.FindObjectOfType<NetworkManager>();
        client = netManager.client;
        if (client.isConnected)
        {
            client.RegisterHandler(DataMsgType.ROT_MSG, ClientReceiveRotMessage);
        }
        if (isServer)
        {
            NetworkServer.RegisterHandler(DataMsgType.ROT_MSG, ServerReceiveRotMessage);
        }
    }

    // Update is called once per frame
    void Update ()
    {}

    public void SendRotMessage(int rot, string obj)
    {
        RotationMessage rotMsg = new RotationMessage();

        rotMsg.dir = rot;
        rotMsg.obj = obj;

        Debug.Log ("Rot: " + rot + " Obj: " + obj); //This prints out the rot and object name correctly

        if (isServer)
        {
            Debug.Log ("Server Message");
            NetworkServer.SendToAll (DataMsgType.ROT_MSG, rotMsg);
        }
        else if (client.isConnected)
        {
            Debug.Log("Client Message");
            client.Send(DataMsgType.ROT_MSG, rotMsg);
        }
    }

    public void ServerReceiveRotMessage(NetworkMessage netMsg)
    {
        Debug.Log("Server Callback"); //Somewhere after this message an IndexOutOfRangeException occurs
        int dir = netMsg.ReadMessage<RotationMessage>().dir;
        string obj = netMsg.ReadMessage<RotationMessage>().obj;
        RotationMessage test = netMsg.ReadMessage<RotationMessage>();
        Debug.Log("Server" + test);
        SendRotMessage(dir, obj);
    }

    public void ClientReceiveRotMessage(NetworkMessage netMsg)
    {
        //Debug.Log("Client Callback");

        if (isServer && isClient)
        {
            Debug.Log("Host Action");

            int dir = netMsg.ReadMessage<RotationMessage>().dir;
            string obj = netMsg.ReadMessage<RotationMessage>().obj;

            Debug.Log (dir); //The dir is correct
            Debug.Log (obj); //Obj is blank
            datum = GameObject.Find(obj); //datum is NULL

            if (datum != null && client.isConnected)
            {
                if (dir == 1)
                {
                    Debug.Log("1 for Up");
                    datum.GetComponent<ApplyRotation>().RotateUp();
                }
                else if (dir == 2)
                {
                    Debug.Log("2 for Down");
                    datum.GetComponent<ApplyRotation>().RotateDown();
                }
                else if (dir == 3)
                {
                    Debug.Log("3 for Right");
                    datum.GetComponent<ApplyRotation>().RotateRight();
                }
                else if (dir == 4)
                {
                    Debug.Log("4 for Left");
                    datum.GetComponent<ApplyRotation>().RotateLeft();
                }
            }
            else
            {
                Debug.Log("Datum is NULL");
            }
        }
    }
}

The exact error issued is:

This is the first time I’ve worked on code using messages. It seemed to be working when I was only sending integers using the default IntegerMessage class, but not now that I’m using my custom message. If someone could point me in the right direction I would appreciate it a lot.

I don’t think you should be calling ReadMessage<>() multiple times. Once you’ve read it once you have fully deserialized it. Calling it again will attempt to read from the end of the buffer and will throw the error you see.

It should be:

RotationMessage rotMsg = netMsg.ReadMessage<RotationMessage>();
rotMsg.dir ... etc
1 Like

Ya, that was it. Thanks!