I’m trying to solve this seemingly simple issue, which became a headache of mine. I check mostly all the forum question for this, but most of the time I found that people set the LockAILogic false in a blueprint. Now, this is not feasible for me, because I write the tasks in C++.
What I found out, is the MoveTo node in behaviour tree is not cancellable. Which is fine. So I made my own. But that is probably more complicated than it should be, and it still doesn’t produce the abort correctly.
Custom MoveToLocation, where I save the movement result code and check it when the OnMoveComplete is finished (This is something I would really love to avoid). It can work perfectly well with a single Pedestrian, but cause a lot of other issues when multiple is presented, which makes me question that a Task is instanced to all running NPC-s or exists as one? Potentially keeping the task alive by keeping references are also not a good idea, but this is all I got. It is a mess right now, but this is also my 20th reiteration of the process, so right now I couldn’t care less. Still no abort, tho! I used StopMovement() which is worked, but only for the movement. It would not help if Pedestrian is in the Waiting state or something else. Without the StopMovement() the NPC goes to the location and after that it will trigger a new state.
I would like to find a solution where I set the BehaviorState and it triggers a re-evaluation of the tree aborting the currently running task, and find the next valid node, without constantly ticking around.
What am I missing?
My behaviour tree is badly structured and missing some service or something?
The custom move location is the problem? I would like to avoid the blueprints if that’s possible.
Is there a better way to handle custom move to? Nor MoveToLocation and MoveToActor worked as it should. I mean, it works because it moves to a place. But It needs to be completed somehow and send a Success from this task.
Is this problem even solvable with C++? (This last one is rhetoric… no need to answer that. )
Also before this approach I made an FSM completely from scratch from code, it worked fine, but was so complicated and huge, that it became a nightmare to maintain.
So I solved half of the issues with the movement by using node instancing. Still no aborting.
UBTT_MoveToLocation::UBTT_MoveToLocation()
This is the constructor for the UBTT_MoveToLocation task. It sets the bCreateNodeInstance flag to true, ensuring that a unique instance of this task is created for each behavior tree execution.
So, digging inside the UBehaviorTreeComponent code, I managed to find a function called RequestBranchEvaluation. Using it on my own wrapper, where I set the state, it aborts the current task. The only problem remained is that it does not abort immediately.
Ok, so it didn’t immediately abort, because I had a Wait task after Move to Location and in the RequestEvaluation I sent a Success, which triggered the Wait and after it continued the execution.