0
\$\begingroup\$

I want to send a large amount of data to only one player, as it would be wasteful to do this for every player when only one player needs the data. After a bit of research, it appears that TargetRPC is the thing that I want to use. Unfortunately, TargetRPC was only introduced semi-recently in Unity 5.4, and I have not been able to find a guide on how to use it properly.

Here is a barebones version of my attempt so far:

using System.Collections;
using System.Collections.Generic;
using UnityEngine.Networking;
using UnityEngine;

public class TargetRpcTest : NetworkBehaviour {

    private List<NetworkConnection> finishedConnections = new List<NetworkConnection>();

    void Start () {
        // We don't want to send data to ourselves. 
        finishedConnections.AddRange(NetworkServer.connections);
    }

    void Update () {

        // If we're not the server, we don't have any business in sending data to players.
        if (!isServer) {
            return;
        }

        // Do the code contained below for everyone we haven't done it for yet. 
        foreach (NetworkConnection connection in NetworkServer.connections) {
            if (!finishedConnections.Contains (connection)) {

                TargetSendStuff (connection);
                finishedConnections.Add (connection);
            }
        }
    }

    [TargetRpc]
    public void TargetSendStuff (NetworkConnection connection) {
        print ("I've just received a target RPC call!");
    }

}

This code is all I could come up with, and it does compile properly. No errors are thrown on the server side, either. However, when a client connects to the server, Unity throws this error:

Could not find target object with netId:5 for RPC call ClientRpc:InvokeRpcTargetSendStuff
UnityEngine.Networking.NetworkIdentity:UNetStaticUpdate()

The 5 in netId:5 varies depending on which object I apply this script to. All objects I attach this script to are required to have NetworkIdentity component because of NetworkBehavior. I have tried applying this script to static scene objects as well as the players themselves, but for some reason UNet still can't seem to find the target objects.

Also, I don't really need the TargetRPC call to apply to any particular object. The code within will do only operations to other objects, and even create new ones based on the sent data. All I need is some way that I can send data to specific clients.

\$\endgroup\$
1
\$\begingroup\$

It is probably an issue of timing. The error message is telling you that the object to which the TargetRpcTest script is attached exists on the server, but not on the client. On the frame upon which the connection is established, Unity has not yet spawned all the objects on the clientside, since it needs to send messages over the network to do that.

Just to confirm that this is the issue, you could try delaying your RPC call by some frames, and see if that fixes the issue. Of course, that isn't so robust; a better way would be to put, in the OnClientStart of TargetRpcTest, a Command which triggers the ClientRpc. But then that's two network calls.

There is yet another way. You say you don't need a specific object to receive the call; NetworkMessages can achieve this, and you shouldn't have any timing issues.

\$\endgroup\$
0
\$\begingroup\$

Based on this code i'm assuming that you want the data to be sent from player to player?

    // If we're not the server, we don't have any business in sending data to players.
    if (!isServer) {
        return;
    }

Which isn't the correct use of [TargetRpc]. If you look at the Unity documentation it says

This is an attribute that can be put on methods of NetworkBehaviour classes to allow them to be invoked on clients from a server. Unlike the ClientRpc attribute, these functions are invoked on one individual target client, not all of the ready clients.

So what a [TargetRpc] does is the same as [ClientRpc] except it only sends it to the client specified in NetworkConnection parameter. Basically you still need to send the data from the Server -> Client.

If you want to send Client -> Client data (i'm not sure the best way but staying in the context of this question) you would need to have a [Command] that would be supplied with what player you want to send the data to and then (from the server) specify that target/send the data using the [TargetRpc]

\$\endgroup\$
  • \$\begingroup\$ No, "if we're not the server, don't send" means "I don't want players to do this, only the server". Sorry for using double-negatives. \$\endgroup\$ – Aaron Franke Feb 27 at 20:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.