Runner.Spawn OnBeforeSpawned

Hey guys,

I'm currently trying to spawn Network Objects in Host / Client Mode.

While spawning "naked" objects works quite well, I seem to fail to understand how to use the OnBeforeSpawn method in the Runner.Spawn properly.

On the Host / Server everything works. But on the clients, the initialisation method never runs and therefore, values, Hitboxes etc of the spawned object are not set up correctly.

Is there a simple way to have the server run the OnBeforeSpawn method first and then sending the final object with initialised values to the network?

Or is there another way to do this?

Best regards,

Chris

Best Answer

  • Isaac_Augusto
    edited June 2022 Answer ✓

    Hi,

    OnBeforeSpawn only runs on the Host/Server. So everything you initialize there should be part of the game state (e.g modifying networked properties).

    You cannot add a Collider to the game state, the weaver will complain. But you can set the NetworkID of the caster and use it on the client to get the NetworkObject (Considering that the caster is a NO).

    So it should be something like this:

    • OnBeforeSpawn only runs on the Host/Server
    • col = GetComponent<Collider>() -> That should be done on the Spawned() of the projectile spawned.
    • CasterCollider should be replaced with the NetworkID of the caster NetworkObject , on the Spawned() of the projectile, you can try find the object with: Runner.TryFindObject() using the ID, then get the collider on the client side.
    • Physics.IgnoreCollision(col, casterCol, true); -> This should probably be on Spawned() as well.

    -----

    Isaac Augusto

    Photon Fusion Team

Answers

  • So, I have checked the Kart Game example. If I understand correctly, the Kart Game Items simply have a general timer that enables the hitbox after 0.5 sec.

    I do however want to track which kart the item originated from for various reasons (tracking scores for hits, disabling homing for the Kart that shot the item etc) and fail to do so.

    I need this to be initialised before the first frame of the objects existence to avoid invalid collision calls on clients. Isn't the OnBeforeSpawn method in the Runner.Spawn meant for exactly that? 🤔

  • Hi,

    Yes, the OnBeforeSpawn is a good place for initialise custom networked variables.

    -----

    Isaac Augusto

    Photon Fusion Team

  • Ok, but initialisation only runs on the server, right?

    On the Init method, I'm referencing the collider of the Playerkart to the Object that is being created / shot to avoid that the objects collides with the Kart that shot it.

    So, I tried to add "[Networked]" to the collider reference which gave me a weaving Error in unity. But if the hitbox reference is a non-networked variable, it stays empty / null on clients.

    How do I get the reference synced to the clients?

    Maybe to clarify, here is what I did in code:

    //Spawning the object:

    Runner.Spawn(itemPrefab, castProps.castPosition, castProps.castRotation, inputAuthority: null, InitializeObjBeforeSpawn, predictionKey: null);

    //BeforeSpawn Method:

    private void InitializeObjBeforeSpawn(NetworkRunner runner, NetworkObject obj) {

                obj.GetComponent<SpawnedProjectileItem>().Initialize(castProps); //runs init method of the created Object

     }

    //Init Method:

    public void Initialize(ItemCastProperties props) {

    col = GetComponent<Collider>();

    casterCol = props.castCollider;

    Physics.IgnoreCollision(col, casterCol, true);

    }

  • Ok. So is this also possible for referencing Colliders? If I put a Networked on them, I get a Fusion weaving Error.

    To clarify what I'm doing, here are some code pieces:

    // spawning the projectile:
    Runner.Spawn(itemPrefab, castProps.castPoint, castProps.castRotation, inputAuthority: null, InitializeObjBeforeSpawn, predictionKey: null);
    
    // Before Spawn Method:
    private void InitializeObjBeforeSpawn(NetworkRunner runner, NetworkObject obj) {
      obj.GetComponent<SpawnedProjectileItem>().Initialize(castProps);
    }
    
    // Init method on the to be spawned object:
    public void Initialize(ItemCastProperties props) {
      col = GetComponent<Collider>();
      casterCol = props.castCollider;
      Physics.IgnoreCollision(col, casterCol, true);
    }
    


    As stated before, this works on the server but on clients, the colliders stay null and therefor I get errors or invalid collisions on clients.

    How do I get the server-side initialised colliders set up on the clients correctly?

  • Isaac_Augusto
    edited June 2022 Answer ✓

    Hi,

    OnBeforeSpawn only runs on the Host/Server. So everything you initialize there should be part of the game state (e.g modifying networked properties).

    You cannot add a Collider to the game state, the weaver will complain. But you can set the NetworkID of the caster and use it on the client to get the NetworkObject (Considering that the caster is a NO).

    So it should be something like this:

    • OnBeforeSpawn only runs on the Host/Server
    • col = GetComponent<Collider>() -> That should be done on the Spawned() of the projectile spawned.
    • CasterCollider should be replaced with the NetworkID of the caster NetworkObject , on the Spawned() of the projectile, you can try find the object with: Runner.TryFindObject() using the ID, then get the collider on the client side.
    • Physics.IgnoreCollision(col, casterCol, true); -> This should probably be on Spawned() as well.

    -----

    Isaac Augusto

    Photon Fusion Team

  • Thank you for the clarification. I'll try it that way 👍️

  • hello, please what solution did you use @Crushl, cause i am in the same situation now