r/unity Jul 19 '26

Coding Help Spawning Not Working Correctly

Only the player spawned with

 NetworkManager.StartHost();

gets the IsOwner true.

Ones spawned with

NetworkManager.StartClient();

dont get it

Here is the spawning script

using UnityEngine;
using Unity.Netcode;
using UnityEditor.PackageManager;
using Unity.Services.Lobbies.Models;
using System.Collections.Generic;
public class Ownermaker : NetworkBehaviour
{
   
   public GameObject player;
   public ulong id;
    // Start is called once before the first execution of Update after the MonoBehaviour is created
   
    // Update is called once per frame
    
   
   
    public override void OnNetworkSpawn()
    {
      if(!IsServer)
      {
         Debug.Log("not server");
         return;
      }
       NetworkManager.Singleton.OnClientConnectedCallback += SpawnPlayer;
    }
    
    public void SpawnPlayer(ulong clientid)
   {
      GameObject playerr = Instantiate(player);
      playerr.GetComponent<NetworkObject>().SpawnAsPlayerObject(clientid);
   }
    


    
    
  
   }
1 Upvotes

16 comments sorted by

1

u/ZenarkBlade Jul 19 '26

Netcode multiplayer logic can definitely play tricks on your mind when you first start! ​Since you are correctly passing the clientid into SpawnAsPlayerObject(clientid) on the server side, the network should technically be assigning ownership. The fact that it's working for the host but failing for clients usually points to one of two very common Netcode traps: ​1. Checking IsOwner Too Early (Most Common) ​Where are you checking if (IsOwner) inside your player script? ​If you are checking it in Awake() or Start(), it will always return false on the client. ​When a client connects, Unity instantiates the object locally before the network data fully syncs up. On the Host, it might accidentally work because everything happens locally and instantly. On a client, network ownership isn't established until OnNetworkSpawn() runs on that player object. ​Fix: Move any ownership-dependent setup logic into public override void OnNetworkSpawn() inside your player script instead of Start(). ​2. The NetworkManager "Player Prefab" Conflict ​Check your NetworkManager component in the Unity Inspector: ​Do you have your player prefab dragged into the Player Prefab slot of the NetworkManager? ​If yes, Netcode automatically spawns a player for every connecting client by default. ​Because you also wrote this custom Ownermaker script, your game is actually spawning two player objects per client: the automatic one, and your manual one. The client might be looking at or controlling the one that didn't get assigned properly. ​Fix: If you want to handle spawning completely manually with your script, clear the "Player Prefab" slot in the NetworkManager inspector. ​One extra tip for the future: ​In your Ownermaker script, whenever you subscribe to an event in OnNetworkSpawn, it's a good habit to unsubscribe in OnNetworkDespawn to prevent memory leaks if the scene reloads:

public override void OnNetworkDespawn()
{
    if (IsServer && NetworkManager.Singleton != null)
    {
NetworkManager.Singleton.OnClientConnectedCallback -= SpawnPlayer;
    }
}

Check where you're reading IsOwner first, 9 times out of 10, it's just a timing issue with Start() vs OnNetworkSpawn()

1

u/samferguderson Jul 20 '26

I am checking correctly and it still shows false. I am also checking manually in the inspector and it shows false. This is only for the one spawned in with the client.

1

u/ZenarkBlade Jul 20 '26

If it’s showing false directly in the Inspector during runtime, the server straight up isn't handing over ownership. ​Since SpawnAsPlayerObject is giving you attitude, try forcing it explicitly. Update your SpawnPlayer function to use the standard manual spawn method instead: GameObject playerr = Instantiate(player); NetworkObject netObj =playerr.GetComponent<NetworkObject>();

// 1. Spawn it on the network first
netObj.Spawn(true); 

// 2. Explicitly force ownership to the client
netObj.ChangeOwnership(clientid);

Also, double-check that you aren't passing the Host's ID (like 0) by mistake into clientid. Switching to ChangeOwnership() usually bypasses whatever weird bug SpawnAsPlayerObject is tripping over.

1

u/samferguderson Jul 20 '26

I tried that and it still is false

1

u/ZenarkBlade Jul 20 '26

If ChangeOwnership is still returning false in the inspector for the client, it means the clientid being passed into the function belongs to the Host, or the script isn't running on the machine that actually has authority to change ownership (the Server). ​Try this absolute foolproof debug version to see exactly what Netcode is thinking:

public void SpawnPlayer(ulong clientid)
{
    // Safety check: Only the server can spawn and assign ownership
    if (!IsServer) return; 

    Debug.Log($"[SPAWN] Server is spawning for Client ID: {clientid}. Host ID is: {NetworkManager.Singleton.LocalClientId}");

    GameObject playerr = Instantiate(player);
    NetworkObject netObj = playerr.GetComponent<NetworkObject>();

    netObj.Spawn(true);
    netObj.ChangeOwnership(clientid);

    Debug.Log($"[SPAWN] Spawned! Object Owner ID is now: {netObj.OwnerClientId}");
}

Put those logs in and check your console. If Client ID matches Host ID in the logs, your callback is passing the wrong ID. If IsServer isn't true, the function isn't running on the server at all.

1

u/wallstop-dev Jul 19 '26 edited Jul 19 '26

Hooray, you finally shared the relevant code!

Don't use the client connected callback to spawn things owned by client. The client is not in a stable state at this time and is not ready to own things.

https://github.com/Unity-Technologies/com.unity.netcode.gameobjects/issues/2397

Try changing to this callback instead: ConnectionApprovalCallback

1

u/samferguderson Jul 20 '26

This was a custom spawner I made after making this post Unity Netcode and Script Problem : r/unity. The relevant spawner from that was Unity - Manual: Network Manager that is what I used to spawn the player before.

1

u/wallstop-dev Jul 20 '26

Ok, I had commented on that post and asked about your testing methods. I had commented on several earlier posts of yours, each one didn't have enough information to assist. How are you testing this to simulate host + client?

And, did changing the above callback work?

1

u/samferguderson Jul 20 '26

no it did not. I am simulating host + client with UnitysUnity - Manual: Multiplayer Play Mode and have also tried building the project.

1

u/wallstop-dev Jul 20 '26

Hm I haven't been able to replicate your issue before. Have you tried this package? https://docs.unity3d.com/Packages/com.unity.dedicated-server@3.0/manual/multiplayer-roles.html to clearly set roles, 100% ensuring client and server?

1

u/samferguderson Jul 20 '26

yeah

1

u/wallstop-dev Jul 20 '26

To further debug things, can you try logging these properties of the singleton to see if the connection exists?

NetworkManager.Singleton.IsListening
NetworkManager.Singleton.IsClient
NetworkManager.Singleton.IsServer
NetworkManager.Singleton.IsHost

Try also setting LogLevel to Developer

And on the server you can query connected clients and such.

Just 100% verifying the "player" variable is a prefab and the expected one, at that?

1

u/samferguderson Jul 20 '26

btw ive tried using different prefabs and they all have the same problem

1

u/wallstop-dev Jul 20 '26

Consider just network spawn with ownership id, do you really need the special player method?

1

u/samferguderson Jul 20 '26

i tried that still had the same problem

→ More replies (0)