ObjectPool and Character Instantiation after Reconnect

Hello,

I've encountered an issue where, if the local player disconnects, his instantiated character gets moved to the ObjectPool. If he reconnects, it gets moved back into the scene. This works flawlessly as long as there is only one PhotonView at the root of the character. If I create a child, let's say, for example, a particle system which should cause a respawn effect, and give it a PhotonView, this child gets destroyed, and then the parent gets moved to the ObjectPool. Unfortunately, the code responsible for this is ObjectPoolBase, which is hidden inside the .dll, and I haven't been able to conclusively understand how PunObjectPool is preventing the parent from getting destroyed but not the child.

So far, so good. I thought I could just use the traditional way of destroying and instantiating, but somehow the parent always ends up in the ObjectPool and gets stuck there if I instantiate a new character upon reconnect. If I do it twice, the Unity install freezes completely.

Now, my question is: How can I either protect the children with a PhotonView from destruction as the parent is protected, or how can I disable my character as a whole from getting moved to the object pool? I would prefer the first option though since it would make integration easier.

I hope this is understandable. If not, I'll shoot a video of the problem and upload it.
 
When the object is returned to the object pool it is just deactivated and reparented under the Game GameObject as long as it was spawned originally with the object pool. Did you spawn the child with the object pool or was it added at design time? Also, the object pool doesn't go through the hierarchy so unless you are explicitly destroying it then any child objects won't be affected.
 
Last edited:
Exactly, it's being deactivated and re-parented to the "Game" GameObject. However, the children which have a PhotonView are being destroyed. This is because Photon calls a cleanup function on them after a disconnect. I found the following information in the Photon Forums:

"So, PhotonHandler.OnLeftRoom() will call LocalCleanupAnythingInstantiated unconditionally, which performs the cleaning up."

What I'm trying to highlight is that with a standard character setup, the character with the PhotonView gets moved to the ObjectPool. However, other objects within that hierarchy don't - they are destroyed.

This should clarify the situation with the particle system. I'm not personally calling a destroy function; it's executed automatically by Photon upon disconnect because a PhotonView is attached. The particle system was just one example. This issue also happens with a puppet master puppet, for instance.

In essence, any object with a PhotonView that is a child of the character prefab gets destroyed, except for the root which holds the PhotonView. I believe this is by design, as with the standard setup there's only one PhotonView at the root of the prefab. But if this design needs alteration, handling reconnects becomes very challenging.
 
Ah, I see now. For your original question:

How can I either protect the children with a PhotonView from destruction as the parent is protected,

It doesn't sound like it's possible for PUN not to do the cleanup? In that case I think that you should instantiate the particle system at runtime when the character enters the room. Right before the character is returned back to the object pool you could reparent it to null and destroy it separately. With this setup it would allow you to use the object pool for both the character and the child particle system.
 
It doesn't sound like it's possible for PUN not to do the cleanup?
Indeed, this can be accomplished by setting the room option to "RoomOptions.CleanupCacheOnLeave". That would actually be the best solution, but the ObjectPool won't allow it. When the player reconnects, the ObjectPool instantiates a copy of the Character as a child of the Game. This results in a series of errors, and if I attempt to reconnect twice, Unity crashes. It appears that some code within Opsive will reinstantiate the character, even if I change the PUN options to prevent cleanup.
Right before the character is returned back to the object pool you could reparent it to null and destroy it separately.
Unfortunately, my character has around 10 photon views for a secondary rag doll rig (Puppetmaster) and other components. So, I don't believe it would be feasible to reparent every bone to null. Furthermore, there's no way to invoke that function because by the time PUN calls "OnDisconnected", the ObjectPool has already reparented the game object and PUN has destroyed the local game objects.

In short, to resolve this issue, I need the ObjectPool code to avoid interacting with my character; otherwise, I won't be able to reconnect. However, I can't make changes to the ObjectPool since its code resides in a .dll. That's why I sought assistance here, as I'm somewhat out of options.
 
What is the error that you are getting? I think that it would be better to solve that error rather than change the logic of the ObjectPool. The ObjectPool is really basic, for example, here's what it is doing on destruction:

Code:
            instantiatedObject.SetActive(false);
            instantiatedObject.transform.SetParent(transform);

            if (m_GameObjectPool.TryGetValue(pooledObjectKey, out var pool)) {
                pool.AddLast(instantiatedObject);
            } else {
                // The pool for this GameObject type doesn't exist yet so it has to be created.
                pool = new LinkedList<GameObject>();
                pool.AddLast(instantiatedObject);
                m_GameObjectPool.Add(pooledObjectKey, pool);
            }

The ObjectPool is in an assembly because Behavior Designer 2 uses this class and it will be closed source. I am wondering though if you have any suggestions on how to make this setup more flexible.
 
You can use DontDestroyOnLoad and handle creation and destruction of player object explicitly for a quick hint without going too far in depth.
 
Hi sorry for the delay in response, so I haven't looked into DontDestroyOnLoad yet but ive been able to solve the issue with CleanupCacheOnLeave = false.

Meaning if we turn off photons auto cleanup we can do it manually as mentioned by FastSkillTeam. Further what is really nice is if we use Photons Destroy function on the parent gameobject of the character it will not reappear on reconnect automatically from the Object Pool.

Hence in conclusion handling the player objects destruction explicitly solves it.

Now regarding the flexibility, what I still cannot wrap my head around is, if I run all standard code with only one PhotonView at the characters root, why is it that upon disconnect the object doesnt get destroyed but reparented to the ObjectPool. If I could understand that I believe this could simply be replicated for the children of the root in case they also have PhotonViews attached.
 
Top