Skip to content
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

A phenomenon that occurs only in HOST mode + customizing the client processing logic with NetworkClient.RegisterPrefab #3962

Closed
abraxas126 opened this issue Dec 30, 2024 · 1 comment · Fixed by #3963

Comments

@abraxas126
Copy link

abraxas126 commented Dec 30, 2024

public class GameNetwork_Manager : NetworkManager
{
    public static void Register_prefabAndHandle()
    {
        for (int i = 0; i < instance.register_spawnAndHandle.Count; i++)
        {
            NetworkClient.RegisterPrefab(instance.register_spawnAndHandle[i].prefab
                , Pool_Object_Head.Instance.HandleTake, Pool_Object_Head.Instance.HandleInto);
        }
    }
}

I would perform the above registration logic before StartHost & StartClient. However I found out that when using NetworkServer.UnSpawn(), HOST is not executing NetworkClient.unspawnHandlers because:

internal static void RegisterMessageHandlers(bool hostMode)
{
   // host mode client / remote client react to some messages differently.
   // but we still need to add handlers for all of them to avoid
   // 'message id not found' errors.
   if (hostMode)
   {
       RegisterHandler<ObjectDestroyMessage>(OnHostClientObjectDestroy);
       RegisterHandler<ObjectHideMessage>(OnHostClientObjectHide);
       RegisterHandler<NetworkPongMessage>(_ => { }, false);
       RegisterHandler<SpawnMessage>(OnHostClientSpawn);
       // host mode doesn't need spawning
       RegisterHandler<ObjectSpawnStartedMessage>(_ => { });
       // host mode doesn't need spawning
       RegisterHandler<ObjectSpawnFinishedMessage>(_ => { });
       // host mode doesn't need state updates
       RegisterHandler<EntityStateMessage>(_ => { });
   }
   else
   {
       RegisterHandler<ObjectDestroyMessage>(OnObjectDestroy);
       RegisterHandler<ObjectHideMessage>(OnObjectHide);
       RegisterHandler<NetworkPongMessage>(NetworkTime.OnClientPong, false);
       RegisterHandler<NetworkPingMessage>(NetworkTime.OnClientPing, false);
       RegisterHandler<SpawnMessage>(OnSpawn);
       RegisterHandler<ObjectSpawnStartedMessage>(OnObjectSpawnStarted);
       RegisterHandler<ObjectSpawnFinishedMessage>(OnObjectSpawnFinished);
       RegisterHandler<EntityStateMessage>(OnEntityStateMessage);
   }

   // These handlers are the same for host and remote clients
   RegisterHandler<TimeSnapshotMessage>(OnTimeSnapshotMessage, false); // unreliable may arrive before reliable authority went through
   RegisterHandler<ChangeOwnerMessage>(OnChangeOwner);
   RegisterHandler<RpcMessage>(OnRPCMessage);
}

There is no NetworkClient.unspawnHandlers execution logic inside the 2 methods that HOST executes in response to ObjectDestroyMessage and ObjectHideMessage.
The HOST owns a client, which means that it cannot respond to the delegate methods carried by custom-registered network prefabs when UnSpawn

MrGadget1024 added a commit that referenced this issue Dec 30, 2024
…awnInternal

- Fixes #3962
There may be a custom unspawn handler for the prefab and NetworkClient::OnHostClientObjectDestroy doesn't invoke it and can't because it's already out of spawned dictionary.
@miwarnec
Copy link
Collaborator

fixed: 8b84e92

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants