Conditional Abort callback method?

Scott Hong

New member
I want to do custom processing when the task is terminated by force due to Conditional Abort.
What callback method is called when the task is killed?
 
There is not currently a callback when conditional aborts happen. The runtime source is available so you could make the change there but I also have it on my list to add.
 
It's been a few years but Is there a plan to add this in officially? I think this would be a super useful feature as our state our entities could become indeterminate If trees are aborted mid execution.

Use case example
Consider the following use case: When a branch of a Behavior Tree is started, we set a state parameter to "Attacking". At the end of the sequence, there is a task to set the state back to Idle (or whatever). In the case where the tree is aborted via. a conditional abort, or if the branch fails, the state parameter is still 'Attacking'. it would be super useful to reset this when the tree is aborted.


Additional example
This GD talk mentions a 'SetProrityOnFail' which would solve for some of the case but a more general solution would be welcome.

As per the talking point in the GDC sesison, I feel some sort of execute on abort callback would quite useful.



Quick and dirty hack in Behavior Designer to support this
As a naive implementation, , I override the Sequence and Selector Tasks to achieve the functionality. Any task, that is a child (or sub child) of the SelectorTask, extending AbortCallback, that has Started but not ended, will have its OnAbortCallback method called when the branch is Conditionally Aborted.

I don't feel this is the best solution as it specific to the composite tasks and would have bo be reimplemented in each concrete composite task. All Composites would need to be replaced with the new composites.



C#:
  public abstract class AbortCallback : Action
  {

    protected abstract TaskStatus AbortCallbackOnUpdate( );

    protected abstract void AbortCallbackOnStart( );

    protected abstract void OnAbortCallback( );

    public override void OnStart( )
    {
      base.OnStart( );
      m_Triggered = true;
      AbortCallbackOnStart( );
    }

    public sealed override TaskStatus OnUpdate( )
    {
      return AbortCallbackOnUpdate();
    }

    public void NotifyAbort( )
    {
      if ( m_Triggered )
      {
        Debug.Log ( $"Reset Abort task + {NodeData.Comment}" );
        OnAbortCallback( );
      }
    }


    public void ResetCallback( )
    {
      m_Triggered = false;
    }

  }



C#:
  public class SelectorWithAbortCallback : Selector
  {

    public override void OnConditionalAbort(int childIndex)
    {
      //-- it seems this CurrentChildIndex() value is 1 index some times and zero index some times.
      int currentChildIndex = CurrentChildIndex( );
      if ( currentChildIndex > 0 )
      {

        Debug.LogWarning ( $"+++Selector:OnConditionalAbort ({this.gameObject.GetScenePath( )}) -> currentChildIndex={currentChildIndex} childIndex={childIndex} childcount={children.Count}" );


       //-- get the active child task and recursively depend looking for any tasks that extend AbortCallback and recursively traversing any children that are themselves parents.
        AbortResetNode ( children[ CurrentChildIndex( ) - 1 ] );

        //-- call super (yuck)
        base.OnConditionalAbort ( childIndex );


      }
    }

    private void AbortResetNode( Task p_Child )
    {
      if ( p_Child is ParentTask parentTask )
      {
        var parentTaskChildren = parentTask.Children;
        for ( int i = 0; i <parentTaskChildren.Count ; i++ )
        {
          AbortResetNode ( parentTaskChildren[ i ] );
        }
      }

      if ( p_Child is AbortCallback abortCallback )
      {
        abortCallback.NotifyAbort( );
      }
    }

  }

Looking deeper at the runtime implementation as per Justin's suggesion, I feel it would be a bit scary to add/modify this code (BehaviorManager.cs) as it seems quite complex.

1. are you still looking to implement some form of this Conditional Abort callback?
2. If not, could you provide some quick pointers to where this could be implemented inside BehaviorManager.cs


As usual, thanks again for the support and insight!
 
Last edited:
Since this initial post I started on v2 of Behavior Designer but that has been delayed due to the lack of progress with Unity's DOTS implementation. Fortunately they have started to release more DOTS updates again so I hope to start on v2 later this year when DOTS hits version 1.0. I had this on my list for a v2 feature.

In v1 there is a reevaluate conditional aborts method and it's here where I would start to look at the callback. When a conditional abort triggers it interrupts all of the other tasks and you could add your callback in this area.
 
Top