Search Unity

  1. Unity 2018.3 is now released.
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. We've updated our Terms of Service. Please read our blog post from Unity CTO and Co-Founder Joachim Ante here
    Dismiss Notice
  4. Want to provide direct feedback to the Unity team? Join the Unity Advisory Panel.
    Dismiss Notice
  5. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice

Unity Multiplayer ClientScene.RegisterPrefab(assetId, SpawnDelegate, UnSpawnDelegate) issue

Discussion in 'Connected Games' started by xVergilx, Mar 29, 2017.

  1. xVergilx


    Dec 22, 2014
    Hi guys. I'm trying to do an objects pooling (for multiple prefab types) spawned via NetworkServer.Spawn but I'm stuck with this issue.
    ClientScene.prefabs are out of sync when I register prefabs on the server and then try to join with a fresh client.

    So I can't get a prefab via assetId called in SpawnDelegate.

    I've checked ClientScene.prefabs dictionary on client, and can confirm that they do not sync on fresh client join.
    Do I have to sync prefabs (ClientScene.prefabs) manually before I join with the client somehow?
    Or maybe there's a way to load a prefab on a client via assetId (which I doubt exists)?

    Also, I can't just put prefabs on spawnable list in NetworkManager, because it overrides Spawn/UnSpawn delegates.

    Any tips appreciated

    Spawn/UnSpawn delegates snippet:
    Code (CSharp):
    3. public delegate GameObject SpawnDelegate(Vector3 position, NetworkHash128 assetId);
    4. public delegate void UnSpawnDelegate(GameObject spawned);
    6. public void RegisterPrefab(GameObject unitPrefab, NetworkHash128 assetId) {
    7.     ClientScene.RegisterPrefab(unitPrefab, SpawnUnit, UnSpawnUnit);
    8. }
    10. private GameObject SpawnUnit(Vector3 position, NetworkHash128 assetid) {
    11.     GameObject prefab;
    13.     ClientScene.prefabs.TryGetValue(assetid, out prefab);
    14.     if (prefab == null) {
    15.         Debug.LogError("UnitPool:: SpawnUnit() - Unable to retrieve prefab by assetId");
    16.     }
    18.     return InstantiateFromUnitPool(prefab, position);
    19. }
    21. public void UnSpawnUnit(GameObject spawned) {
    22.     Debug.Log("Unspawning");
    23.     spawned.SetActive(false);
    24. }
    Last edited: Mar 29, 2017
  2. xVergilx


    Dec 22, 2014
    I've actually managed to do pooling without any spawn/undelegate.
    For those who interested - just pool everything on server (standard instantiate), spawn if it's a new object and update it on clients via Rpc.
  3. gsus725


    Aug 23, 2010
  4. hexagonius


    Mar 26, 2013
    @VergilUa the way you describe your first attempt is not the way this works. The Server knows which prefab it spawns, because you need to instantiate a version of it and pass it to NetworkServer.Spawn. RegisterPrefab needs to be called on the clients because they are the ones that do NOT know what to spawn when the server sends them just a hash. Furthermore, you don't need to provide your own delegate declarations because they're already provided, otherwise the Method would not exist.

    SideNote: I just recently reported a bug that running this from OnStartClient in a NetworkBehaviour that is in a scene used by the NetworkManager as the online scene, is too late for the registration and will throw an error when running in Host mode or server and client on the same machine. Awake is your best bet.