Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NetworkObjects spawned inside a scene are spawned before the scene is loaded on late-joining clients #3115

Open
Moe-Baker opened this issue Nov 6, 2024 · 3 comments
Assignees
Labels
stat:awaiting response Status - Awaiting response from author. stat:awaiting triage Status - Awaiting triage from the Netcode team. type:bug Bug Report

Comments

@Moe-Baker
Copy link

Description

NetworkObjects spawned inside a scene are spawned before the scene is loaded on late-joining clients using Distributed Authority.

Reproduce Steps

  1. Clients A & B enter matchmaking.
  2. Client A is assigned NetworkManager session owner and loads a scene "Scene".
  3. Scene contains a "Level" NetworkBehaviour script.
  4. Level script has an OnInSceneObjectsSpawned override and will spawn a "Player" NetworkObject on it.
  5. The Player is spawned via SpawnWithOwnership(NetworkManager.Singleton.LocalClientId, destroyWithScene: true).
  6. The Player has a NetworkBehaviour with an OnNetworkPostSpawn override and will register itself with the Level.
  7. All this works correctly for Client A.
  8. When a late-joining Client B tries to join, it will sometimes (random) spawn Client A's Player before it even Loads the Level's Scene.

Actual Outcome

A null reference exception as Client A's Player tries to register itself on the Level script before the Scene is even loaded.

Expected Outcome

That the logical flow of scene and object spawning is maintained.
When a late-joining client joins the game, they should first load the active scene, and then spawn NetworkObjects, not just randomly do both.

Environment

  • OS: [Windows 11, Android]
  • Unity Version: [60000.23f1]
  • Netcode Version: [2.0.0]
  • Netcode Topology: Distributed Authority.
  • Netcode Commit: [Unspecified]
@Moe-Baker Moe-Baker added stat:awaiting triage Status - Awaiting triage from the Netcode team. type:bug Bug Report labels Nov 6, 2024
@NoelStephensUnity
Copy link
Collaborator

@Moe-Baker

This part of your steps:

  • Level script has an OnInSceneObjectsSpawned override and will spawn a "Player" NetworkObject on it.

I need a bit more context as to why you want the in-scene placed NetworkObject to spawn the players?
Is there any way you could provide me with a replication project (it will help me narrow down the issue faster)?
If not, then I need some additional details behind using the in-scene placed NetworkObject as opposed to just using the client to handle the spawning...even just the script on the in-scene placed NetworkObject would help me understand the sequence better.

@NoelStephensUnity NoelStephensUnity added the stat:awaiting response Status - Awaiting response from author. label Nov 8, 2024
@NoelStephensUnity NoelStephensUnity self-assigned this Nov 8, 2024
@Moe-Baker
Copy link
Author

I need a bit more context as to why you want the in-scene placed NetworkObject to spawn the players

I find that this better organizes my project, we have a few different game modes, with a few different player prefabs, so choosing the player prefab inside the loaded scene is more convenient for me.

Is there any way you could provide me with a replication project

I'll create a replicated project and share it later.

even just the script on the in-scene placed NetworkObject would help me understand the sequence better

For the time being, these are the two scripts stripped down to the offending parts.
Player Script & Level Script

@NoelStephensUnity
Copy link
Collaborator

@Moe-Baker

What I would recommend is to:

  • Update to NGO v2.1.1
  • Disable the NetworkManager's "Auto Spawn Player Prefab" in the inspector view.
  • Use something like this adjusted MiniGamesLevel component script:
public class MiniGamesLevel : NetworkBehaviour
{
    public GameObject PrefabToSpawn;

    // When a client finishes synchronizing it invokes this
    protected override void OnNetworkSessionSynchronized()
    {
        var instance = Instantiate(PrefabToSpawn).GetComponent<NetworkObject>();
        instance.SpawnWithOwnership(NetworkManager.Singleton.LocalClientId, destroyWithScene: true);
        base.OnNetworkSessionSynchronized();
    }
}

There is a known issue where the Multiplayer SDK "re-enables" the "Auto Spawn Player Prefab" setting when joining a distributed authority session, but a PR to remove that is in place and should be in the next update.

Until then, you can not assign a player prefab to avoid the initial automatic spawn and just rely on the MiniGamesLevel to handle this for you.

Let me know if this helps?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stat:awaiting response Status - Awaiting response from author. stat:awaiting triage Status - Awaiting triage from the Netcode team. type:bug Bug Report
Projects
None yet
Development

No branches or pull requests

2 participants