Skip to content

Host's PlayerObject becomes null after Despawning a transferred client PlayerObject (DontDestroyWithOwner) #3938

Description

@T-Huckle

Description

The PlayerObject of the host appears to be nulled out when a different object (of the same type) gets despawned and has is also owned by the host.

Reproduce Steps

Have a network object that gets marked with
GetComponent<NetworkObject>().DontDestroyWithOwner = true;

In my setup, my player object was not set as the default player object. Instead I explicitly spawned with SpawnAsPlayerObject

When the client disconnects - set a delayedDespawn coroutine, then despawn that object. After which, the hosts PlayerObject becomes null

private IEnumerator DelayDespawnCoroutine(PlayerController pc, PlayerController hostPc) {
// Host is always ID 0
Debug.Log("Host player number: " + NetworkManager.Singleton.ConnectedClients[0].PlayerObject?.GetComponent<PlayerController>().PlayerNumber);
yield return new WaitForSeconds(5);
var obj = pc.GetComponent<NetworkObject>();
if (obj != null && obj.IsSpawned) {
// Orphaned Network Object now as the same OwnerClientId as the host
Debug.Log($"Despawning object with OwnerClientId: {obj.OwnerClientId}");
// We see this print out the hosts PlayerNumber (1 in this scenario)
Debug.Log("Host player number: " + NetworkManager.Singleton.ConnectedClients[0].PlayerObject?.GetComponent<PlayerController>().PlayerNumber);
// We see this print out the playerNumber of the disconnected client (3 in this scenario - these are different object)
Debug.Log("Despawning Player Number: " + pc.PlayerNumber);
//Despawn and destroy the NetworkObject obj.Despawn(true);
// No Longer prints out 1 as PlayerObject has now become null.
Debug.Log("Host player number: " + NetworkManager.Singleton.ConnectedClients[0].PlayerObject?.GetComponent<PlayerController>().PlayerNumber);
}
else {
Debug.Log("No despawn: ");
Debug.Log(obj);
}
}

Actual Outcome

Image

Host loses a reference to its PlayerObject

Expected Outcome

The NetworkObject succesfully despawns and the Host's PlayerObject remains the same

Environment

  • OS: Windows 11
  • Unity Version: 6000.3.8f1
  • Netcode Version: 2.11.0
  • Netcode Topology: Client-Server

Additional Context

Can work around by reassigning the PlayerObject


obj.Despawn(true);
if (NetworkManager.Singleton.ConnectedClients.TryGetValue(0, out var hostClient) &&
hostClient.PlayerObject == null) {
hostClient.PlayerObject = hostPc.GetComponent<NetworkObject>();
Debug.Log("Restored host PlayerObject after despawn");
}

I believe the issue is here in NetworkSpawnManager inside OnDespawnObject.

if (networkObject.IsPlayerObject)
{
RemovePlayerObject(networkObject, destroyGameObject);
}

or inside RemovePlayerObject

 if (m_PlayerObjectsTable.ContainsKey(playerObject.OwnerClientId))
{
m_PlayerObjectsTable[playerObject.OwnerClientId].Remove(playerObject);
if (m_PlayerObjectsTable[playerObject.OwnerClientId].Count == 0)
{
m_PlayerObjectsTable.Remove(playerObject.OwnerClientId);
}
}

Should check to make sure that m_PlayerObjectsTable[playerObject.OwnerClientId] == playerObject

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    priority:mediumThis issue has medium priority and may take some time to be resolvedstat:importedStatus - Issue is tracked internally at Unitytype:bugBug Report

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions