There are no words for how good it feels to get something working after such a long time. My hourly dev effort has definitely not worked out the way I wanted since I hit this problem, but I now have a solution to a couple of problems.
The first was to replicate an Unity’s old RPC system in Unet. RPCs still exist in a sense, but they function differently in the HLAPI, and have weird restrictions which means they aren’t suitable for what I want to do. In this case, send a piece of information, say, a simple string, like “I really don’t like Unet”.
The way to do this is actually with Unet’s network messages which you can read about here: http://docs.unity3d.com/Manual/UNetMessages.html
And if that doesn’t seem to make a whole lot of sense, here’s a fairly simple breakdown that got me started: http://forum.unity3d.com/threads/command-between-2-different-scripts.334902/#post-2168275
The forum post (Thanks Carpe Denius!) gave me the basic approach and understanding, and going back to the official documentation helped me flesh out what I needed to do.
Using the MessageBase class it’s possible to create a message with a range of data inside, but for now I’m just sending the aforementioned simple string.
On the client, in the one script I have
class StringMessage : MessageBase
{
public string deathCoords;
}
public class Networking : MonoBehaviour
{
NetworkClient myClient;
StringMessage msg;
// Use this for initialization
void Start ()
{
ConnectToServer();
}
// Update is called once per frame
void Update ()
{
if(Input.GetKeyDown(KeyCode.P))
{
Debug.Log("Pressed P");
msg = new StringMessage();
msg.deathCoords = "0,0";
myClient.Send(666, msg);
//some other functions doing some stuff...
}
So you can see I’m going to send coordinates of where the player has died (simulated by pressing P), and for now those are hard coded to a string saying 0,0. I’ll retrieve the actual player coords later, I just needed to get the message sent first; baby steps.
public class MyNetworkManager : MonoBehaviour
{
public StringMessage receivedMsg;
public bool isAtStartup = true;
void Start()
{
SetupServer();
}
void OnGUI()
{
//some display stuff
}
// Create a server and listen on a port
public void SetupServer()
{
NetworkServer.Listen(4445);
NetworkServer.RegisterHandler(666, DeathLog);
isAtStartup = false;
}
void DeathLog(NetworkMessage msg)
{
receivedMsg = msg.ReadMessage<StringMessage>();
Debug.Log("received Message " + receivedMsg.value);
guiUpdate += "player died at coords " + receivedMsg.value + "\n";
}
}
And here I’m logging the location. one of the things I was also doing wrong here in the DeathLog function was not setting a local stringmessage variable, and trying to do this
Debug.Log("received Message " + msg.ReadMessage<StringMessage>() .value);
guiUpdate += "player died at coords " + msg.ReadMessage<StringMessage>() .value + "\n";
This gives an error because you can’t deserialise the message more than once, which happens when ReadMessage is called. So by deserialising into receivedMsg it’s usable as many times as required. I spent a few hours trying to work out why the log would print out fine and then every other readmessage afterwards would fail.
I found that solution here: http://forum.unity3d.com/threads/need-help-with-custom-messages.339010/
So now I am sending and receiving messages. The next step is to fix my server GUI, because despite me updating it, the display does not change. I’m hoping that’s less painful than these last few weeks.