Unity-Technologies / com.unity.netcode.gameobjects

Netcode for GameObjects is a high-level netcode SDK that provides networking capabilities to GameObject/MonoBehaviour workflows within Unity and sits on top of underlying transport layer.
MIT License
2.09k stars 431 forks source link

SpawnManager.InstantiateAndSpawn doesn't Instantiate on Server #2911

Open AsmPrgmC3 opened 1 month ago

AsmPrgmC3 commented 1 month ago

Description

SpawnManager.InstantiateAndSpawn doesn't instantiate the prefab when run on a server.

Reproduce Steps

  1. Add a cube to the scene with a Network Object component
  2. Create a prefab from that cube and add it to the Network Prefab list; remove the original from the scene
  3. Add an empty to the scene and add the following component:
    
    using Unity.Netcode;
    using UnityEngine;

[RequireComponent(typeof(NetworkObject))] public class Spawner : NetworkBehaviour { public NetworkObject prefab;

public override void OnNetworkSpawn()
{
    if (!IsServer)
    {
        return;
    }

    NetworkManager.SpawnManager.InstantiateAndSpawn(prefab);
    NetworkManager.SpawnManager.InstantiateAndSpawn(prefab);
}

}


4. Assign the cube prefab to the `Spawner` component
5. Start the project as a server (*not* host)

### Actual Outcome

The cube prefab never gets instantiated, causing:
- No cubes get added to the scene/hierarchy
- (Inside the Editor only) The first `InstantiateAndSpawn` causes the error `Transform resides in a Prefab asset and cannot be set to prevent data corruption`
- The second `InstatiateAndSpawn` causes the error `SpawnStateException: Object is already spawned`

### Expected Outcome

Two cubes spawn.

### Environment

- OS: Windows 10 (22H2)
- Unity Version: 2022.3.7f1
- Netcode Version: Release 1.8.1
NoelStephensUnity commented 1 month ago

@AsmPrgmC3 Indeed this does look like a bug and we need to make sure our integration tests includes testing server only. Unless you are using overrides for your prefabs, you can set forceOverride to true and it should when running as a server:

using Unity.Netcode;
using UnityEngine;

[RequireComponent(typeof(NetworkObject))]
public class Spawner : NetworkBehaviour
{
    public NetworkObject prefab;

    public override void OnNetworkSpawn()
    {
        if (!IsServer)
        {
            return;
        }

        NetworkManager.SpawnManager.InstantiateAndSpawn(prefab, forceOverride: true);
        NetworkManager.SpawnManager.InstantiateAndSpawn(prefab, forceOverride: true);
    }
}

This would be a temporary work around until the next update. The fix for this is pretty simple so I am going to go out on a limb and say the fix will be in the next update (whatever version we end up with that proceeds v1.9,1).

Thank you for the detailed information! 👍