Task selector only runs CurrentChildIndex() once

seired

New member
Hi, first I want to thank you for making Behavior Trees, it's making my development process a lot easier.

That aside, I'm trying to make a custom Task selector like the one included in the MiniGauntlet sample. I'm changing the nextTaskIndex value with a static field from another class to keep it loosely coupled, for now at least, later I will use events. The problem is that CurrentChildIndex() is only running when the tree starts, I added a Debug.Log inside the method in your TaskTriggerSelector and it behaves like an Update method, but mine only runs once, am I missing something? I already checked the static value and I'm sure the value is getting updated, Here's my task:

Code:
using UnityEngine;
using BehaviorDesigner.Runtime;
using BehaviorDesigner.Runtime.Tasks;
namespace GC.Behavior
{
    [TaskCategory("GC/Composite")]
    public class CustomTaskSelector : Composite
    {
       
        private int nextTaskIndex = 0;
        public override int CurrentChildIndex()
        {
            // The next task index will be 0 unless a collision or trigger event has occurred
            Debug.Log("updating");
            if (TestScript.Value)
            {
                nextTaskIndex = 1;
                return nextTaskIndex ;//Once true it should change to log task
            }
            else
            {
                nextTaskIndex = 0;
                return nextTaskIndex;
             } 
        }

        public override void OnChildExecuted(TaskStatus childStatus)
        {
            // Set the next task index back to 0 immediately after the child has executed to prevent a non-idle task from running multiple tiles
            nextTaskIndex = 0;
        }
      
        //Ignore this, I will use it later for an event based update
        public void TaskChanger(PlayingStatus ps)
        {
            if (ps==PlayingStatus.Failure)
            {
                nextTaskIndex = 1;
                Debug.Log(nextTaskIndex);
            }
            else
            {
                nextTaskIndex = 0;
                Debug.Log(nextTaskIndex);
            }
          
        }
    }
}

My tree looks like this:
tree.png

I'm displaying a line when the boolean is true, once it's completed it gets back to IdleGC but nothing happens, it always stays running IdleGC

Another question, I was testing how conditional tasks behave and I was updating the TaskStatus with an event, I subscribe to it inside OnStart() and I unsubscribe with OnBehaviorComplete() but the method is called multiple times, as if it were being triggered multiple times, I mean, it doesn't really matter since the TaskUpdate value is being updated correctly, but why does that happen? am I doing something wrong again?

Thanks in advance.
 
Last edited:
For non-parallel tasks CurrentChildIndex will only run when the next child task has to be selected. Since you have an idle task it'll always return a status of running and never have to go to the next task. I think a better task example to look at is the Utility Selector task - this task will reevaluate every tick and determine if it should abort the child task.

Another question, I was testing how conditional tasks behave and I was updating the TaskStatus with an event, I subscribe to it inside OnStart() and I unsubscribe with OnBehaviorComplete() but the method is called multiple times, as if it were being triggered multiple times, I mean, it doesn't really matter since the TaskUpdate value is being updated correctly, but why does that happen? am I doing something wrong again?
OnStart may be triggering multiple times because of a conditional abort - if the conditional task aborts another branch then it'll run OnStart before executing that branch. OnBehaviorComplete will only run when the behavior tree has completed its execution - maybe you have restart when complete enabled so the tree automatically restarts?
 
For non-parallel tasks CurrentChildIndex will only run when the next child task has to be selected. Since you have an idle task it'll always return a status of running and never have to go to the next task. I think a better task example to look at is the Utility Selector task - this task will reevaluate every tick and determine if it should abort the child task.

I thought I'd made it work in the MiniGauntlet scene a few minutes ago but It turns out I hadn't committed the changes to the prefab, I'll try your advice, thanks!
 
Last edited:
Top