I don’t want to relly on autospawn player prefab function, I want to do that manually. Also my player prefab also has custom INetworkPrefabInstanceHandler
registered for this prefab. When NetworkManager
spawn prefab for me custom InstanceHandler
works. But when I spawn prefab manualy like so
InstantiateAndSpawn()
or via SpawnAsPlayerObject()
On localHost in editor it works, but on device I see this error:
NetworkBehaviour index 0 was out of bounds for …
I looked into source code to copy from NetworkConnectionManager
but this functions there internal
internal void CreateAndSpawnPlayer ( ulong ownerId )
{
if (NetworkManager.DistributedAuthorityMode && NetworkManager.AutoSpawnPlayerPrefabClientSide)
{
var playerPrefab = NetworkManager.FetchLocalPlayerPrefabToSpawn();
if (playerPrefab != null)
{
var globalObjectIdHash = playerPrefab.GetComponent<NetworkObject>().GlobalObjectIdHash;
var networkObject = NetworkManager.SpawnManager.GetNetworkObjectToSpawn(globalObjectIdHash, ownerId, playerPrefab.transform.position, playerPrefab.transform.rotation);
networkObject.IsSceneObject = false;
networkObject.SpawnAsPlayerObject(ownerId, networkObject.DestroyWithScene);
}
}
}
Explain for me please the right way to spawn playerPrefab
manually, Thanks!
What is the device you’re seeing the error on, and is it on the host or the client? Does it work if you run both host and client locally?
There’s a couple of posts mentioning the error here and here that might help.
There’s a middle-ground too!
You can make a player prefab that contains nothing but a NetworkObject, and a NetworkBehaviour script of yours which decides when and where to spawn the actual player prefab.
That means you forgoe the part where you need to device WHEN and HOW to spawn the player object yourself. Rather the player object is already spawned but just an empty shell used as a “manager” object. Doing it this way is quite convenient because you’ll never run into the situation where a client doesn’t actually have an instantiated (valid) player object. This makes things like dying (*) and respawning a whole lot easier to implement as well.
- = or changing the player’s presence in any way like becoming a ghost or temporarily “in another place”
If I do StartHost in the editor it works, If I start debug where server and client in different unity editor instances (Unity 6 feature) its spawn the error. Error appears on Server only. My target Platfrom to test on device is Android
Can you share your prefab handler code. I didn’t encounter this error when playing with prefab handlers previously but will take another look a bit later.
There is a fix here for prefab handlers that’s worth trying in case it’s related. It’s not released yet but is on the develop branch.
public class ZenjectNetCodeFactory : INetworkPrefabInstanceHandler
{
private readonly GameObject _prefab;
private readonly DiContainer _diContainer;
public ZenjectNetCodeFactory(GameObject prefab, DiContainer diContainer)
{
_prefab = prefab;
_diContainer = diContainer;
}
public NetworkObject Instantiate(ulong ownerClientId, Vector3 position, Quaternion rotation)
{
GameObjectCreationParameters parameters = new()
{
Name = $"{_prefab.name} | Owner: {ownerClientId}",
Position = position,
Rotation = rotation
};
return _diContainer.InstantiateNetworkPrefab(_prefab, parameters);
}
public void Destroy(NetworkObject networkObject)
{
Object.Destroy(networkObject.gameObject);
}
}
public static class ContainerExtension
{
public static NetworkObject InstantiateNetworkPrefab(this DiContainer container, GameObject prefab,
GameObjectCreationParameters creationParameters = null)
{
bool state = prefab.activeSelf;
prefab.SetActive(false);
var gameObject = container.InstantiatePrefab(prefab, creationParameters ?? GameObjectCreationParameters.Default);
prefab.SetActive(state);
gameObject.SetActive(state);
var networkObject = gameObject.GetComponent<NetworkObject>();
return networkObject;
}
}
I’ve tested this locally with mppm and I’m not seeing an error. Your code is a lot more elaborate than mine and would be hard to replicate, can you cut it down to bare bones and see if you still have the issue?
You could also try the develop branch to check whether or not you see the same problem there.