SharedGameObjectPool.Rent is inconsistent regarding an object's active state
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:
- Instantiation (with SharedGameObjectPool.Rent())
- AfterDeserialize(): a custom method within my objects
- Awake: if it's the first time they spawn
- OnEnable
- 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
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:
- AfterDeserialize
- Awake
- OnEnable
- Start
Then, after all objects returned to the pool if I instantiate them again, the execution order is:
- OnEnable
- AfterDeserialize
- 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);
}