- Home /
MLAPI spawn player prefab
I am trying to load PlayerPrefabs manually. My game starts in a MainMenu scene, first player hosts, server starts, a new scene loads, player prefab spawns in and everything seems to work fine. When I join as a client, I can't get the second player prefab to spawn, but I do connect and see the 1st player moving around. I am running this script in an object placed in the scene.
public class GameSceneManager : NetworkBehaviour
{
private void Start()
{
// get spawn points
_spawnPoints = GameObject.FindGameObjectsWithTag("playerSpawn");
SpawnPlayerServerRpc();
}
private Transform GetSpawnPoint()
{
if (_spawnPoints.Length == 0) { return null; }
if (NetworkManager.Singleton.IsHost)
{
return _spawnPoints[0].transform;
}
else
{
ulong id = NetworkManager.Singleton.LocalClientId;
int count = (int)(id - 1);
return _spawnPoints[count].transform;
}
}
[ServerRpc]
public void SpawnPlayerServerRpc(ulong clientId)
{
Transform spawn = GetSpawnPoint();
GameObject go = Instantiate(_playerPrefab, spawn.position, spawn.rotation);
go.GetComponent<NetworkObject>().SpawnAsPlayerObject(OwnerClientId);
ulong objectId = go.GetComponent<NetworkObject>().NetworkObjectId;
SpawnClientRpc(objectId);
}
[ClientRpc]
private void SpawnClientRpc(ulong objectId)
{
NetworkObject player = NetworkSpawnManager.SpawnedObjects[objectId];
}
I get this error: Trying to destroy object 0 but it doesn't seem to exist anymore! UnityEngine.Debug:LogWarning (object) MLAPI.Spawning.NetworkSpawnManager:OnDestroyObject (ulong,bool) (at Library/PackageCache/com.unity.multiplayer.mlapi@0.1.0/Runtime/Spawning/NetworkSpawnManager.cs:660) MLAPI.NetworkObject:OnDestroy () (at Library/PackageCache/com.unity.multiplayer.mlapi@0.1.0/Runtime/Core/NetworkObject.cs:366)
Answer by FranktheGame · May 26, 2021 at 03:27 PM
I got it working. If anyone else is having same issue or just curious, what I did not understand was that the GameObject I was trying to spawn from, was a NetworkObject that was owned by the Host(1st player to log on), so even if I used NetworkManager.Singleton.LocalClientId; it would return the Host clientId instead of the new player that was calling it. I just called the method and sent the localId from another script that was MonoBehaviour (not a NetworkObject), I know this needs work, but it's working for now:
public class NetworkPlayerSpawner : NetworkBehaviour
{
[SerializeField] private GameObject _playerPrefab = null;
void Start()
{
// get spawn points
_spawnPoints = GameObject.FindGameObjectsWithTag("playerSpawn");
}
private Transform GetSpawnPoint()
{
// Stop if there are no spawn points in the seen
if (_spawnPoints.Length == 0) { return null; }
// get number of players
if (NetworkManager.Singleton.IsHost)
{
return _spawnPoints[0].transform;
}
else
{
ulong id = NetworkManager.Singleton.LocalClientId;
int count = (int)(id - 1);
return _spawnPoints[count].transform;
}
}
[ServerRpc(RequireOwnership = false)]
public void SpawnPlayerServerRpc(ulong clientId)
{
// Get Spawn. Stop if there are no spawn points in the seen
Transform spawn = GetSpawnPoint();
if (spawn == null) { Debug.Log("No Spawn Points in Scene!"); return; }
// Spawn on Client
GameObject go = Instantiate(_playerPrefab, spawn.position, spawn.rotation);
Debug.Log("clientId = " + clientId);
go.GetComponent<NetworkObject>().SpawnAsPlayerObject(clientId);
ulong objectId = go.GetComponent<NetworkObject>().NetworkObjectId;
SpawnClientRpc(objectId);
}
// A ClientRpc can be invoked by the server to be executed on a client
[ClientRpc]
private void SpawnClientRpc(ulong objectId)
{
NetworkObject player = NetworkSpawnManager.SpawnedObjects[objectId];
}
}
and I just called the method from another script on Start (when the player loads into the scene)
void Start(){
ulong id = NetworkManager.Singleton.LocalClientId;
_networkPlayerSpawner.SpawnPlayerServerRpc(id);
}
Answer by NocSchecter · Sep 27, 2021 at 10:55 PM
Hello!
Could you tell me use a part of your code but all my players are instantiated in the first value of my list containing the spawnpoints.
Do you have the code on the client side? when a client chooses where to position itself instead of the server doing it?
I think you have to give write permission to the client to change the position variable. Or do a check if it is client or server then change the position value.
Your answer
Follow this Question
Related Questions
Trying to spawn players in multiple starting positions 1 Answer
Unity networking tutorial? 6 Answers
Controlling a network game? 0 Answers
Unity NetworkTransformChild - Syncing the Child of a Child 0 Answers