In the legacy system if I wanted a player to let all other players know about something I could send an RPC with the mode being all so that even the sender will receive the call.
How do I do this in UNet?
Alternative solution: Send a command to the host from the client.
Here I have a different issue:
I am able to send RPCs from the host to the client
I am unable to send Commands to the host from the client
My situation:
I have a two player game with one host and one client
The game has no âplayersâ as such because you donât have characters which you move etc
The game is perhaps more applicable to a turn based card game (but you have no health or similar)
I have a NetworkBehaviour and NetworkIdentity attached to a separate GameObject in the scene from the start of the game
I am using the NetworkBehaviour successfully to send RPCs from the host to the client
Commands in the same script can be called by the client but are not called on the server (breakpoints arenât hit)
In the manual it says âCommands are sent from player objects on the client to player objects on the serverâ but I donât know what a âplayer objectâ is or if thatâs even the issue I have or not.
Right, but what is a player object? The documentation doesnât quite make that clear and it almost seems like my NetworkBehaviour should simply be names Player?
Okay that makes sense, but it actually already has a NetworkIdentity component attached!
The Commands and RPCs are in a script I have created which inherits from NetworkBehaviour which is attached to a GameObject in the scene which also has a NetworkIdentity component but nothing else.
The GameObject which has this script attached is added as a public variable in another script (and set in the inspector) so that this other script can call the RPCs and Commands by reference.
You need an object with âLocal authorityâ. This object can then send âCommandsâ to the server and the server can broadcast the information via RPCs or SyncVars.
The âLocal Player Authorityâ checkbox is ticked already.
The âAuto Create Playerâ checkbox under âSpawn Infoâ is unchecked as I am not spawning any players but there is just the one which exists in the scene before running.
To clarify, this is my entire NetworkManager script:
public class DSMNet : NetworkManager
{
public GameObject networkController;
// called when a client connects
public override void OnServerConnect(NetworkConnection conn)
{
networkController.SetActive(true);
}
}
networkController is the GameObject mentioned above which has the script which inherits from NetworkBehaviour and NetworkIdentity component.
I tried using more than one but clearly didnât do that right. What I donât understand is that both the server and client can call functions on that GameObject but only one can receive?
If I duplicated that GameObject, how would I specify which is the server and which is the client? (The game is just 1v1 for now)
Also, I have seen examples of scripts around online that people use which have both Commands and RPCs so why is that not possible here?
The reason I did it this way is Iâm used to the legacy system and wanted basically one central point which anything can use to send messages.
you can create a type of message on the server side, register a handler for that message type on the client, and use that to send messages.
Server side:
public static short MSG_MESSAGETOSEND = 54;
public class MessageClass : MessageBase
{
public string messageToSend;
}
public static void sendMessage(string message)
{
MessageClass msg = new MessageClass();
msg.messageToSend = message;
NetworkServer.SendToAll(msg);
}
Client Side:
public static short MSG_MESSAGETOSEND = 54;
static NetworkClient netClient = new NetworkClient();
public class MessageClass : MessageBase
{
public string messageToSend;
}
//Network Clients connect to the server
netClient.RegisterHandler(MSG_MESSAGETOSEND, OnSomeMessageReceived);
public void OnSomeMessageReceived(NetworkMessage netMsg)
{
MessageClass msg = new MessageClass();
msg = netMsg.ReadMessage<MessageClass>();
foo(msg.messageToSend); //Where foo does something with the incoming message.
}
of course, if you are doing things beyond sending a message, RPCâs and Commands are likely the way to go.
I believe what this should do is the local player will send CmdDoStuff to server, but will not run the method yet due to the if statement in CmdDoStuff.
The server will then call the Rpc which will then send to all of the clients including the original sender who will then execute the DoStuff code.
You can also move the if(isLocalPlayer) part into the RPC if you want it to execute in realtime on the client without waiting for the server.
The problem was that the command was not running on the local player. Maybe there should be a warning for if you are trying to send commands from a player that isnât yours, even though when worded like that it should be obvious. I also changed it so that the NetworkManager automatically spawns the player prefab. Letting that do its own thing is the easiest way for sure.
Thanks @seanr for the assistance.