Search Unity

Question on Unity custom spawn handler

Discussion in 'Connected Games' started by AbhinayNegi, Dec 22, 2018.

  1. AbhinayNegi

    AbhinayNegi

    Joined:
    Dec 22, 2017
    Posts:
    17
    In unity manual https://docs.unity3d.com/Manual/UNetCustomSpawning.html I learned about how to create spawn handler. It says we need to Register handler functions
    Code (CSharp):
    1. ClientScene.RegisterSpawnHandler(coinAssetId, SpawnCoin, UnSpawnCoin);
    I understood that SpawnCoin andUnSpawnCoin is handler function but my question is why it needs assetId ?
     
  2. vis2k

    vis2k

    Joined:
    Sep 4, 2015
    Posts:
    3,369
    AbhinayNegi likes this.
  3. goldbug

    goldbug

    Joined:
    Oct 12, 2011
    Posts:
    696
    @AbhinayNegi Here is an example of how to use spawn handlers:

    Code (CSharp):
    1. class Myclass : MonoBehaviour {
    2.    public NetworkIdentity prefab;
    3.  
    4.    public void RegisterMyHandler()
    5.    {
    6.       ClientScene.RegisterSpawnHandler(prefab.assetid, spawn, unspawn);
    7.    }
    8.  
    9.    private GameObject Spawn(Vector3 position, Guid assetId)
    10.    {
    11.       return GameObject.Instantiate(prefab, position);
    12.    }
    13.    private void Unspawn(GameObject go)
    14.    {
    15.       Destroy(go);
    16.    }
    17. }
    You can register any number of handlers. A handler for each type of object. The client stores this information in Dictionary<Guid, SpawnDelegate>();
    Every prefab has an assetid. That is how the client can tell object types apart.
    When the server spawns an object, it gets the assetid from the object being spawned, sends a message to the clients "spawn an object with assetid xxxx". The client looks up the assetid in the dictionary and invokes the handler.

    Edit. forgot to clarify that Mirror uses Guid, UNET uses NetworkHash128, but the idea is exactly the same.
     
    Last edited: Dec 23, 2018
    AbhinayNegi likes this.
  4. AbhinayNegi

    AbhinayNegi

    Joined:
    Dec 22, 2017
    Posts:
    17
    Finally, I know what is the use of assetID and how the custom spawn system works, really informative thanks @goldbug and thanks @vis2k for your help
     
  5. AbhinayNegi

    AbhinayNegi

    Joined:
    Dec 22, 2017
    Posts:
    17
  6. AbhinayNegi

    AbhinayNegi

    Joined:
    Dec 22, 2017
    Posts:
    17
    @goldbug I have one more question. For example, there are 4 clients and one of them call
    Code (CSharp):
    1. NetworkServer.Spawn()
    and remaining 3 clients will get a request to spawn that object as well on their machine using handler function. And all of the 3 clients want to know, which client requested for spawning. My question is How the clients will know about which client or player GameObject requested for spawning?
     
  7. goldbug

    goldbug

    Joined:
    Oct 12, 2011
    Posts:
    696
    You don't call NetworkServer.Spawn() from a client. You can only call that in the server.
    If you want one of the clients to be assigned as the owner of that object, then in your server call SpawnWithClientAuthority instead. Your clients can check if they own the object by checking hasAuthority.
     
  8. AbhinayNegi

    AbhinayNegi

    Joined:
    Dec 22, 2017
    Posts:
    17
    Ok, you said that Your clients can check if they own the object by checking hasAuthority. But can they check who is the owner or client called the
    Code (CSharp):
    1. NetworkServer.Spawn()
    on server. For example Client A playerObject calls
    Code (CSharp):
    1. [Command]
    2. void CmdFire() {
    3.  
    4. GameObject o =  Instantiate(bullet);
    5. NetworkServer.Spawn(o);
    6. }
    on the server. Then handler function is called on clients B and C. But both clients B and C want to know which player object or client called NetworkServer.Spawn() on the server. B wants to know was it A or B and B wants to know was it A or C.
     
  9. goldbug

    goldbug

    Joined:
    Oct 12, 2011
    Posts:
    696
    There is nothing built in for that, because this is very much case specific. But you can track the shooter in a variable. For example:

    Code (CSharp):
    1. public class Bullet : NetworkBehaviour {
    2.  
    3.     [SyncVar]
    4.     public GameObject shooter;
    5.  
    6. }
    7.  
    8. public class Player : NetworkBehaviour {
    9.  
    10.      [Command]
    11.      void CmdFire() {
    12.           GameObject o =  Instantiate(bullet);
    13.           Bullet b = o.GetComponent<Bullet>();
    14.           b.shooter = this.gameObject;
    15.           NetworkServer.Spawn(o);
    16.      }
    17. }
    18.  
     
    AbhinayNegi likes this.
  10. AbhinayNegi

    AbhinayNegi

    Joined:
    Dec 22, 2017
    Posts:
    17
    @goldbug really helpful now I'll try with my implementation. And Correct Me if I'am wrong : If we don't make shooter[SyncVar]
    so only the server is aware of the change and not the cilents.
     
  11. goldbug

    goldbug

    Joined:
    Oct 12, 2011
    Posts:
    696
    @AbhinayNegi that is correct, the purpose of [SyncVar] there is so that all the clients are aware of who the shooter is. Without it, only the server would know. It depends on what you need.
     
    AbhinayNegi likes this.
  12. AbhinayNegi

    AbhinayNegi

    Joined:
    Dec 22, 2017
    Posts:
    17
    @goldbug thanks for clearing my doubts.
     
unityunity