Search Unity

  1. Unity 2019.2 is now released.
    Dismiss Notice

Unity Multiplayer UNet ClientRpc issue

Discussion in 'Connected Games' started by MartinLyne, Jun 25, 2015.

  1. MartinLyne


    Apr 25, 2013
    I'm trying to register my prefabs dynamically on a ClientRpc function, but for some reason clients that join don't receive the command. Also the Host's Client aspect doesn't show it (though I think that is a known issue)

    In my Online scene I have a scene object that has my own test script and a Network Identity (I have set that to all possible combinations in my tests)

    My script looks like:

    Code (csharp):
    2. using UnityEngine;
    3. using UnityEngine.Networking;
    5. class NetTest : NetworkBehaviour {
    7.     void Start () {
    8.         DontDestroyOnLoad(gameObject);
    9.     }
    11.     public override void OnStartServer () {
    12.         if (isServer) {
    13.             Debug.LogError("Server started");
    14.             // Instantiate on server
    15.             GameObject prefab = GameObject.Instantiate(Resources.Load("Prefabs/Buildings/Scraper2")) as GameObject;
    16.             // Register prefab on clients
    17.             RpcReg("Prefabs/Buildings/Scraper2");
    18.             // Register on server needed?
    19.             ClientScene.RegisterPrefab(prefab);
    20.             // Actually send spawn to clients
    21.             NetworkServer.Spawn(prefab);
    22.         }
    23.     }
    25.     [ClientRpc]
    26.     void RpcReg (string prefabPath) {
    27.         Debug.LogError("registering:"+prefabPath);
    28.         ClientScene.RegisterPrefab(Resources.Load(prefabPath) as GameObject);
    29.     }
    30. }
    31. [code]
    33. I just don't understand why the RPC isn't called?
    35. Thanks for any help
    36. Martin
  2. seanr


    Unity Technologies

    Sep 22, 2014
    the server does not need to register prefabs.
    the clientRpc is called when the server starts.. the client is not connected yet, so it does not receive it.
  3. MartinLyne


    Apr 25, 2013
    Thanks for the info.

    Shouldn't later client connections receive it? Or throw an error if the call is made too early?

    I think I mistook "OnStartServer" to be the equivalent of "When the server is ready". Which brings me to my next question: What should I use? There seems to be no NetworkBehaviour method that handles the "readiness" of the server?

    I've tried OnClientStart, OnStartLocalPlayer and OnStartAuthority.

    Old methods no longer get triggered (as I expected, really).

    Do I really need to set a timer (bleh) or register a handler just to detect that its okay to send RPCs?
  4. MartinLyne


    Apr 25, 2013
    I've used a handler now, triggered on Ready (The docs page for Handlers is out of date btw - uses old version of MsgType vars)

    Good news: The RPC triggers for the Host-Client.

    Bad news: Clients that join don't receive the RPC. Is there a way to mark ClientRPCs as Buffered?

    Edit: I guess also I don't see why Registering and Spawning are not integrated. Can't spawn without Register. Registering only useful for spawning?
    Last edited: Jun 25, 2015
  5. MartinLyne


    Apr 25, 2013
    For further test I added the RegisterPrefab call to the Start of the script.

    What I see on the client when I join the server is this..

    Failed to spawn server object, assetId=387512f7cd028489b25b8ce526cff7 (server telling client to spawn the item)

    [... a few more debug logs..]

    Registering prefab 'Scraper2' as asset:387512f7cd028489b25b8ce526cff7 (from my new Start() RefgisterPrefab() call)

    So I actually don't see how RegisterPrefab is ever useful? If you can't guarantee it gets called on a script before a spawn is called over the network?

    If you are meant to use it via ClientRrc then it would have to be buffered before the Spawn() call - which I can't seem to get to work.

    Edit: After some more testing I have the RegisterPrefab in the Awake() method. But the RegisterHandler doens't work while in there, so I moved that back into the Start() method.

    That seems to work, it still doesn't enable me to actually do what I wanted, my question about "can we call buffered clientrpcs and can we guarantee they arrive before Spawn calls" remains valid.

    Highlighted to bypass waffling :)
    Last edited: Jun 26, 2015
  6. MartinLyne


    Apr 25, 2013
    Further attempts:

    SyncVar Hook:
    Added a [SyncVar(hook=blah)] to a list of "registerTheseAssets" list.
    Hope: Sync request for spawner is sent before spawn events, update registers everything in list
    Reality: Hook methods need to receive the updated item, but I can't find right signature. List<string>, string, string[] all fail when using associated types. Fail.

    SyncVar Handler:
    Removed the "hook=" and tried to add a handler for MsgType.UpdateVars but it won't allow me to override that (I guess it uses that for the "hook=" stuff) Fail.

    Manually Request List
    OnClientConnect -> Ask Server for List -> Server RPCs list to all clients -> Register locally on reciept.
    Spawn is called before OnClientConnect, so it is already too late to register the assets. Fail.
    Last edited: Jun 26, 2015