Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Resolved Problems with spawned Player Objects

Discussion in 'Netcode for GameObjects' started by erik969, Oct 19, 2023.

  1. erik969

    erik969

    Joined:
    May 10, 2020
    Posts:
    8
    I recently made a change to my game that broke everything.

    Before, the whole game would be in one scene, with a simple host and client button. Depending on if the Host pressed the button first, I would change the default player prefab through an approval check to fit the client character and then just run StartClient().

    Today I updated it so that you first have to go through a main menu and character selection screen before you enter the game, so I changed the spawn mechanic to an empty gameobject in the gameplay scene that spawns the character as a player prefab using SpawnAsPlayerObject() in OnNetworkSpawn()

    For some reason this completely broke my camera and movement script and I can't access the Singleton that's in the scene for some reason.

    For example this code doesn't instantiate the cameras anymore, neither locally nor on the network. I checked and the Client does have ownership:

    Code (CSharp):
    1. public class AssignCamera : NetworkBehaviour
    2. {
    3.     [SerializeField] GameObject _camerasPrefab;
    4.     public GameObject cameras;
    5.     public override void OnNetworkSpawn()
    6.     {
    7.         if (!IsOwner) return;
    8.         cameras = Instantiate(_camerasPrefab, Vector3.zero, Quaternion.identity);
    9.  
    10.         cameras.GetComponentInChildren<CinemachineVirtualCamera>().Follow = transform;
    11.         cameras.GetComponentInChildren<CinemachineVirtualCamera>().LookAt = transform;
    12.         cameras.transform.GetChild(2).GetComponent<CinemachineVirtualCamera>().Follow = transform;
    13.         cameras.transform.GetChild(2).GetComponent<CinemachineVirtualCamera>().LookAt = transform;
    14.      
    15.         SpawnCamerasServerRpc();
    16.     }
    17.  
    18.  
    19.     [ServerRpc]
    20.     private void SpawnCamerasServerRpc()
    21.     {
    22.         cameras.GetComponent<NetworkObject>().SpawnWithOwnership(OwnerClientId);
    23.     }
    24. }
    My shoddy programming also requires the cameras to be accessible by other scripts in the player through a public variable.

    Some help would be appreciated XOXO
     
    Last edited: Oct 19, 2023
  2. erik969

    erik969

    Joined:
    May 10, 2020
    Posts:
    8
    For added context, here's my spawn script:

    Code (CSharp):
    1. public class CharacterSpawner : NetworkBehaviour
    2. {
    3.     [SerializeField] GameObject _overlordPrefab, _minionPrefab, _camerasPrefab;
    4.  
    5.     [SerializeField] Transform _overlordSpawn;
    6.     [SerializeField] Transform[] _minionSpawns;
    7.  
    8.     public override void OnNetworkSpawn()
    9.     {
    10.         if (!IsServer) return;
    11.  
    12.         for (int i = 0; i < ServerManager.Instance.ConnectedIds.Count; i++)
    13.         {
    14.             if (i == 0)
    15.             {
    16.                 GameObject overlord = Instantiate(_overlordPrefab, _overlordSpawn.position, _overlordSpawn.rotation);
    17.                 overlord.GetComponent<NetworkObject>().SpawnAsPlayerObject(ServerManager.Instance.ConnectedIds[i]);
    18.             }
    19.             else
    20.             {
    21.                 GameObject minion = Instantiate(_minionPrefab, _minionSpawns[i].position, _minionSpawns[i].rotation);
    22.                 minion.GetComponent<NetworkObject>().SpawnAsPlayerObject(ServerManager.Instance.ConnectedIds[i]);
    23.             }
    24.         }
    25.     }
    26. }
     
  3. erik969

    erik969

    Joined:
    May 10, 2020
    Posts:
    8
    I'm confused. I moved the function in CharacterSpawner to a button and now suddenly everything works...

    Does anyone have a clue as to why spawning players breaks when done in OnNetworkSpawn but doesn't when executed manually through a button?

    EDIT: I've resorted to turning the function into a Coroutine and adding a .5 second delay. I'll mark the thread as resolved.
     
    Last edited: Oct 19, 2023