Conditional Abort on event

OJuer

New member
Hi,

I am using conditional abort to have my behavior tree wait after it receives an event "GetHit". This works fine, but only once, and I want the branch to restart every time the event is sent. If I send another "GetHit" event while the Wait Task is running, it will have no effect. I cannot set the conditional abort to "both", because then the Wait will be aborted by "GetHit" no longer being true the frame after it was received. How do I go about this? I feel like it should be easy and I cannot see the forest for all the trees. Thank you

1594207915799.png
 
Conditional aborts execute when there is a change, so if the task returns Failure from Success or Success from Failure. The Has Received Event task will set eventReceived to true when the event is received, and then reset it after the task has ended. So in order to get the abort to trigger again Has Received Event should be executed through the normal tree traversal and have OnStart/OnEnd called.
 
Hm, I am not sure I understand you completely. What I want is that everytime I send GetHit, I want Wait to start again, whether it is already running or not. The lower-priority abort will not restart the wait when I send an event while the wait task is running. The "both" abort will stop the wait immediately, because the HasReceivedEvent Task is reevaluated to false. So I am still not clear on how to achieve this.
 
Ahh, I see now. I don't think that you'll be able to get that with the built in Has Received Event task.

One way to accomplish this would be to create a new Has Received Event task that works similar to the existing task, except it doesn't reset the eventReceived variable when OnStart/OnEnd is called. The flag should only be reset after OnUpdate has been called. This will then allow you to use a Both abort type.
 
Not sure if that would work, because the conditional abort will run OnUpdate while Wait is running and that will then return Failure and abort the Wait, no?
I have solved it now with two branches and a simple but useful Task I built before called Cooldown that runs a Coroutine internally. I combine this with a Conditional Task that checks whether the Coroutine is running. By the way, Task could offer an overload StopCoroutine(Coroutine coroutine), because it does offer the overload StartCoroutine() that returns a Coroutine object.

1594292715852.png

Code:
[Serializable]
public class Cooldown : Action
{
    [SerializeField] private SharedFloat _cooldownSeconds;
    private Coroutine _cooldownCoroutine;
    public bool IsCoolingDown { get; private set; }

    public override TaskStatus OnUpdate()
    {
        if (_cooldownCoroutine != null) Owner.StopCoroutine(_cooldownCoroutine);
        _cooldownCoroutine = StartCoroutine(CooldownCoroutine());
        return TaskStatus.Success;
    }

    private IEnumerator CooldownCoroutine()
    {
        IsCoolingDown = true;
        yield return new WaitForSeconds(_cooldownSeconds.Value);
        IsCoolingDown = false;
    }
}
 
Top