-
Notifications
You must be signed in to change notification settings - Fork 437
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
NGO v1.12.0 & v1.11.0 does not trigger OnNetworkDespawn function on NetworkObjects associated with Disconnecting Clients on the Server side when INetworkPrefabInstanceHandler is used. #3190
Comments
Hi, @Ermelious, Hmmm... it looks like you are not checking the returned value for the public static async Task RegisterSpawnableToNetworkManager(SpawnableData spawnableData)
{
await spawnableData.PreloadAssetReference();
// Add the custom handler for the specified prefab
if (!NetworkManager.Singleton.PrefabHandler.AddHandler(
spawnableData.assetReferenceHandle.Result,
new NetcodeSpawnableHandler(spawnableData)
))
{
// Not sure what type spawnableData.assetReferenceHandle.Result is. Assuming it is a GameObject.
var spawnableNetworkObject = spawnableData.assetReferenceHandle.Result.GetComponent<NetworkObject>();
Debug.Log($"Failed to register handler for {spawnableData.assetReferenceHandle.Result} with a GlobalObjectId value of {spawnableNetworkObject.PrefabIdHash}!");
}
} |
Hi Noel, I was the one who replied to the above thread. I've had a look at this again and I think the reason it looks like OnNetworkDespawn is not called is due to the prefab handler's Destroy method being called before the object is despawned for the disconnecting client (and when the client owns the object). For host owned objects the despawning happens before the call to Destroy. So in the Destroy method if you're returning the object to a pool and make it inactive it doesn't trigger the OnNetworkDespawn call. This is in 1.12.0, in 2.x the call order is correct but the Destroy method is called twice. I've attached a couple of test scenes which I hope will makes things clearer. In one I use Boss Room's object pool which throws an exception in 2.x as it tries to return the object to the pool twice. |
@ezoray Looking at the code-base in v1.12.0, I am not seeing that same order of operations that you are describing. Within the NetworkSpawnManager Then I started to think that it was when the client disconnected itself but in both the NetworkSpawnManager for v1.x if (destroyGameObject && gobj != null)
{
if (NetworkManager.PrefabHandler.ContainsHandler(networkObject))
{
NetworkManager.PrefabHandler.HandleNetworkPrefabDestroy(networkObject);
}
else
{
UnityEngine.Object.Destroy(gobj);
}
} For example purposes, while running Unity 6 with NGO v2.2.0 I would connect a client to a running host, hit the space bar to spawn a bunch of NetworkObjects from the pool, then I would disconnect the client (hitting the X button in the top right) and this is what the console log looks like: The example I provided has some additional settings to help you debug various scenarios. The two of interest are "Use Pool For Spawn" (when enabled it pulls from the pool as opposed to instantiating when disabled) and "Return To Pool" (when enabled it returns the objects to the pool as to destroying when disabled). For example: The ObjectPoolSystem also provides you with the ability to easily obtain a reference to it like this: public class SpawnManager : NetworkBehaviour
{
[Tooltip("Links the network prefab assigned to an ObjectPoolSystem in order to get the ObjectPoolSystem instance to use.")]
public GameObject PrefabToSpawn;
private ObjectPoolSystem m_ObjectPoolSystem;
private List<ObjectLifeTimeHandler> m_ObjectLifeTimeHandlers = new List<ObjectLifeTimeHandler>();
protected override void OnNetworkPostSpawn()
{
if (IsServer)
{
m_ObjectPoolSystem = ObjectPoolSystem.GetPoolSystem(PrefabToSpawn);
}
base.OnNetworkPostSpawn();
} Where you just have to set the network prefab on another component to use as a way to finding the ObjectPoolSystem that is pooling that network prefab (avoids having to do any weird references and such). It also organizes the object instances under the ObjectPoolSystem's GameObject while they are despawned so you don't get a bunch of disabled objects in your active scene (i.e. for organization purposes and makes it easier to see the objects getting pulled from and put back into the pool). Finally, it provides a way to make sure all ObjectPoolSystems have instatiated their pools before proceeding. The only thing I can think of is that the BossRoom component uses an void ActionOnDestroy(NetworkObject networkObject)
{
Destroy(networkObject.gameObject);
}
m_Prefabs.Add(prefab);
// Create the pool
m_PooledObjects[prefab] = new ObjectPool<NetworkObject>(CreateFunc, ActionOnGet, ActionOnRelease, ActionOnDestroy, defaultCapacity: prewarmCount); Which could be the culprit behind the duplicate destroys. The ObjectPoolSystem just uses a Either case, try out the example I provided and see if you can replicate the issue? |
Description
NGO v1.12.0 & v1.11.0 does not trigger OnNetworkDespawn function on NetworkObjects associated with Disconnecting Clients on the Server side when INetworkPrefabInstanceHandler is used.
Reproduce Steps
Upgrade to NGO v2.1.1
It doesn't seem like I'm the only one experiencing this issue (Additionally the Destroy function in INetworkPrefabInstanceHandler is being called twice per NetworkObject, refer to the thread for more details):
https://discussions.unity.com/t/onnetworkdespawn-ondestroy-from-networkbehaviour-does-not-get-executed-on-the-hosting-client-when-using-inetworkprefabinstancehandler/1578473/6
Expected Outcome
OnNetworkDespawn should execute on the Server for NetworkObjects associated with the Disconnecting Clients.
My code:
Screenshots
Environment
The text was updated successfully, but these errors were encountered: