Need more information on pooling External Behaviors

krefsar

New member
I'm still having trouble understanding the workflow for pooling external behaviors for the purpose of handling the initialization performance drop in a loading screen. In my case, I have an ObjectPool set up with characters with BehaviorTree's. Is the idea to:
1) Leave the reference to external behavior tree blank at first, then
2) Set up a pool of instances of the external behavior tree that have all been initialized, then
3) When spawning a character, assign the external behavior tree reference to an instance from the external behavior pool?
4) When the character is returned to the pool (or destroyed, etc), remove the reference to the pooled external behavior?

The concept of freeing up the external behavior is making me confused. I understand it for a pool of GameObjects, but how does this work for something like External Behaviors?

Alternatively, I could do something like:
During loading, as the ObjectPool populates with the characters, quickly enable and disable their behavior so that they get initialized.
This would theoretically work, but I can't find the place where I would hook into the ObjectPool initialization! I am using the default ObjectPool component that is set up by the Opsive Setup Wizard. This option also makes sense to me, because I'm seeing that when I reuse characters from the pool, I don't have nearly the same performance hit as during the initialization.

For context, I am making a 3D Smash TV clone, which relies on many agents being active at once. You're my only hope!
 
Code:
public class ExternalBehaviorPool : MonoBehaviour
{
    public event Action OnFinishInitializing = delegate { };

    private Queue<ExternalBehavior> objects = new Queue<ExternalBehavior>();

    [SerializeField]
    private ExternalBehavior template;
    [SerializeField]
    private int startingPoolSize = 5;

    private void Start()
    {
        StartCoroutine(InitializeBehavior());
    }

    public ExternalBehavior GetExternalBehavior()
    {
        if (objects.Count == 0) {
            GrowPool();
        }

        ExternalBehavior behavior = objects.Dequeue();
        return behavior;
    }

    public void ReturnToPool(ExternalBehavior behaviorToReturn)
    {
        objects.Enqueue(behaviorToReturn);
    }
    
    private void GrowPool()
    {
        Debug.Log("Growing pool!");
        for (int i = 0; i < startingPoolSize; i++)
        {
            ExternalBehavior instance = Instantiate(template);
            instance.name += " " + i;
            instance.Init();
            objects.Enqueue(instance);
        }
    }

    private IEnumerator InitializeBehavior()
    {
        Debug.Log("Initializing behaviors...");
        GrowPool();
        yield return new WaitForSeconds(10); // some generic amount of time to wait for initialization to finish?
        OnFinishInitializing();
    }
}

# elsewhere, when spawning an enemyObj with my WaveSpawning system:
BehaviorTree behaviorTree = enemyObj.GetComponent<BehaviorTree>();
behaviorTree.DisableBehavior();
behaviorTree.ExternalBehavior = externalBehaviorPool.GetExternalBehavior();
behaviorTree.EnableBehavior();
 
Hey Justin, yeah I read through that page which is how I got this far. It seems like I'm able to deserialize, but how can I hook into the object pool initialization for my AI agents to implement a loading screen? I can't for some reason see or modify the Object pool code.
 
The ObjectPool component has Instantiate/Destroy methods similar to the GameObject object. You should instantiate the agent from the Object Pool and then assign the external tree. When you are done with it you can place the external tree back in the queue and call destroy on the agent.
 
Top