- Rename ClientRpc to something like ObserverRpc. I just found out that ClientRpc only calls the Rpc for the client’s observers, not for all clients (it says ‘all clients’ in the documentation, that’s very misleading).
- Add something like GlobalRpc: calls the Rpc on ALL clients. Right now we have to iterate through NetworkServer.objects and send a Message to all of them. This is just a lot of work for something that should be simple.
- Add something like TargetRpc: calls the Rpc on just ONE client. seanr mentioned somewhere that this will be part of 5.4, so that’s good. Right now we still have to use a Message, which is a lot of work for something that should be simple.
+1 The documentation is misleading and would like what Vis2k considered.
Bump dis like there is no tomorrow.
+1 that’d be a good thingimho
I can’t find the source anymore, but as mentioned above: seanr said that TargetRpc will be in 5.4, but there is nothing in the release notes.
Pro users can already test 5.4: Unity Editor Beta Releases , can any Pro user confirm that it contains TargetRpc? Or any word on this from @seanr perhaps?
GlobalRpc would be glorious
If renaming class names would be so easy to do, I would also be grateful.
I am pretty sure there’s a reason why it’s named after ClientRpc, ServerRpc, and so on, and it has to do with the name reflecting upon the tech framework behind the scenes. But I don’t know.
If you do a poll, maybe it will tell a different side of the story?
There is no ServerRpc as far as I know. Rpc always means ‘call this on the client’ in UNET. Functions that should be called on the server are Commands ala CmdMyFunction.
So as long as it ends with ‘Rpc’, it’s probably clear enough that it’s for the client.
I really need that send to one client RPC it would make my life so much easier right now I am thinking about adding a “owner” string to all clients and if the client’s name is not “owner” then it disregards the information, but that is so much wasted overhead it isn’t even funny. I guess Unet is still very young in it’s inception - I even thought ClientRPC sent to all clients any other odd things you all have seen?
I think TargetRPC is in Unity 5.4 already.
[TargetRPC] doesn’t seem to exist within UnityEngine.Networking in 5.3.5f1
I just tried to type it in and it was no go there is a [GUITarget] though…
I’ve learned my lesson about upgrading to new builds of unity when working on something. lol I’ll load it on the laptop maybe and see.
I attached a class based on NetworkBehariour at run time (gameObject.addComponent()) but when i do, it never receives ClientRpc calls. Anybody know anything about that?
Does anyone here know how to use the message base? I’ve looked at the doc and stuff and faint tutorials but I just don’t get it… What I need to do doesn’t seem that complex to me ![]()
I’m using 5.4b23, ClientRpc seems to send to all clients, but i want to send to all clients except the owner.
Right now im just ignoring the message by
If(IsLocalPlayer)
return;
But its such a waste to send to a target that doesnt need it…
Am i missing something here?
I also thought that something like this might be a nice addition so I had created this feature request.
TargetRpc was finally implemented in the latest versions, it works fine
Yes, but this is not about TargetRPC. It is about RPC to all but one, like an inverted TargetRPC.
For example, if the server has received data from one client and then needs to redistribute it, it might not always be necessary to send this data back to the client who originally send it. So, this client could be excluded from the ClientRPC and some bandwidth could be saved. Currently, this option seems to be missing in the HLAPI.
Oh okay, sorry
This is how I’ve done it, it took a while to figure out how to get all the relevant connection ID’s.
The only downside is that with target RPC’s you’re forced to send the client the NetworkConnection data, so if that data is more expensive than simply sending the client redundant information there’s no point worrying about it. I’m not sure how to find out the size of the connection data, but I assume it’s on the larger end (40 bytes?, plus whatever unet does to optimise it), multiplied by the number of clients that don’t own it.
In other words it’s only worth it for really large data unless you only have 2 or 3 clients.
[Command]
void CmdUpdatePosition(string serializedPositions)
{
//We the server have now been informed of these positions so now just inform all the clients about them
for (int i = 0; i < NetworkServer.connections.Count; ++i)
{
//If it's null then the client disconnected
if (NetworkServer.connections[i] == null)
{
Debug.Log("Skipping disconnected");
continue;
}
//Don't call the Rpc on ourselves in case we are hosting
//Untested on server-only instance. Will this always be 0?
if (NetworkServer.connections[i].connectionId == NetworkManager.singleton.client.connection.connectionId)
{
Debug.Log("Skipping self id " + NetworkManager.singleton.client.connection.connectionId);
continue;
}
//We don't need to tell the owner of the object the positions it just sent us
if (NetworkServer.connections[i].connectionId == GetComponent<NetworkIdentity>().clientAuthorityOwner.connectionId)
{
Debug.Log("Skipping owner client id " + NetworkServer.connections[i].connectionId + " for " + gameObject.name);
continue;
}
TargetUpdatePosition(NetworkServer.connections[i], serializedPositions);
}
//We also need them in case we are hosting, plus that way we know how many we received from the client
DeserializePositions(serializedPositions, ref networkPositions);
//Debug.Log("Received & Forwarding clients " + networkPositions.Count + " positions from " + gameObject.name);
}
[TargetRpc]
void TargetUpdatePosition(NetworkConnection target, string serializedPositions)
{
if (!hasAuthority)
{
DeserializePositions(serializedPositions, ref networkPositions);
}
else
{
Debug.LogError("Received position update from server even though we own this object");
}
}