uPools icon indicating copy to clipboard operation
uPools copied to clipboard

SharedGameObjectPool.Rent is inconsistent regarding an object's active state

Open mnicolas94 opened this issue 6 months ago • 0 comments

In my project, I have a serialization/deserialization system that instantiates prefabs and writes (deserializes) some persistent (serialized) data onto the instances. When an object is deserialized I need to ensure the execution order of steps is:

  1. Instantiation (with SharedGameObjectPool.Rent())
  2. AfterDeserialize(): a custom method within my objects
  3. Awake: if it's the first time they spawn
  4. OnEnable
  5. Start

To achieve this, I disable the prefabs before instantiation and re-enable the instance after deserialization. Something like:

public void Deserialize(GameObject prefab, SerializedData data)
{
    prefab.SetActive(false);
    var instance = SharedGameObjectPool.Rent(prefab);
    DeserializeDataIntoObject(instance, data);
    instance.AfterDeserialize();  // this is pseudocode, the AfterDeserialize method is on MonoBehaviours within the object
    instance.SetActive(true);  // back to active, this ensures Awake, Start, OnEnable are called after AfterDeserialize
}

However, if an object was previously pooled, the Rent method will always set its active state to true independently of the prefab's active state (see the marked line of code in the image).

https://github.com/annulusgames/uPools/blob/e11ce9c12c65c12f3bc35ae2ef7cacde6826e503/Assets/uPools/Runtime/SharedGameObjectPool.cs#L3

Image

This is incosistent and makes my desired execution order to not work because OnEnable is called inside obj.SetActive(true). Hence, the first time an object is instantiated, the order is:

  1. AfterDeserialize
  2. Awake
  3. OnEnable
  4. Start

Then, after all objects returned to the pool if I instantiate them again, the execution order is:

  1. OnEnable
  2. AfterDeserialize
  3. Start

So, my desired behaviour would be to reflect the prefab's active state into the pooled instances.

My workaround was to implement an almost exact copy of SharedGameObjectPool but in all Rent methods I do:

if (original.activeSelf)
{
    obj.SetActive(true);
}

Image

mnicolas94 avatar Aug 15 '25 15:08 mnicolas94