State Tree persistent MoveTo

Hey im new to state trees. I’ve spent a lot of time eating tutorials and watched epics overviews of state trees.

I am trying run a MoveTo task along with an attack target child

-Move to enemy

--attack target

--recovery

--idle(wait)

I having a bunch of issues with the attack /recovery not wanting to finish the states.

I know there are a lot of details im not including but my main question is, is this setup totally wrong anyway?

Should I be running a parallel state tree designed only for movement?

I feel like this should be simple.
I want the AI to always be moving to target and attacking to happen during the move to.
for some reason even though the state tree receives event.attack.finished which should complete attack state and transition to recovery it never transitions.

You need to constantly check for target.
If Invalid, → find nearest target.
If valid, → check if in range for an attack.
If in range → attack, else → get in range.

After attack you need to break out of the loop (New State). Run an idle, then jump back to the loop.

Better served setting up multiple states vs one long winded one.

Targeting, Moving To, Attacking, Idle

My idea for this was to have the AIController set a target and once its valid run a simple MoveToEnemy and attack when in range. That’s it.
I know my “attack” when in range isn’t set up yet but I just don’t understand why the attack target enemy state never finishes. it should constantly be going
attack>recovery
attack>recovery
but it attacks on tree start and never goes to the attack recovery.

I could do this in a behavior tree easy. I’m still in the StateTree learning phase and don’t like that something so simple is giving me issues.

I know I could do
is valid target?
move to enemy>
attack enemy>
recovery> restart loop.

but the behavior would be
once the attack starts and the player moves away the AI doesn’t move again until the attack state finishes and the loop restarts.

I did this with behavior trees using a parallel node.
I thought that since child states run along side the parent state I could achieve this same behavior.

There are so many little things that could make a state tree act funky it’d take to long to debug each scenario. But I do also have the “Move To Enemy task " not being considered for completion since I want it to always move to the enemy.

Move to needs to be allowed to finish, then immediately check range. A simple sphere trace on its location checking the result == target. If so, then Attack.


You want a fool proof loop of events that runs based on the current AI State

Overall I’d use an Enum AIState to determine action. You update the state based on results of action, then call an event that evaluates the new state.

AIState (Enum)Find Target, Engaging, Attacking, Roaming, Waiting


Here’s the basic flow as an example

Every Action executes EvaulateAIState() at the end of its logic chain.

To keep things easier to understand, i keep my tasks in the end leaf states, not in parent states, the order of the tasks being called can be confusing sometimes. Pay super close attention to your transitions, that gets me so many times. Maybe post your transition logic block, its hard to tell how your event is set up. Pay close attention to where your 'Finish Task’s are called, too. Most of my custom tasks i have a ‘DoFinishTask’ bool set up to determine whether or not to call the finish task as it can prevent other tasks in the same state from running.

Not sure if any of that helps, but your idea should be really simple to set up with StateTree. Make sure you are using the debugger to record and watch your tree stepping. I use it a lot and will catch issues with transitions right away.

Dont give up. I spent a good bit trying to get used to the ST design epic built as it’s not really inline with tradition. It’s more like the state machine in animBPs with all the transition rules flattened out into a tree. That said, the state trees are super powerful and easy to debug once you get used to them, and they can be used practically anywhere. Absolute gamechanger over BTs

Thank you. That was helpful.
I’ll post more detailed screen shots when I have time.

I think maybe the Move To task I built might be keeping the other tasks in the same state from finishing. I’m doing a test with task that finishes after a 10sec delay to see if it stalls other child states. So far the states run normally and loop just fine during the 10 second delay.
Its just the MoveToEnemy task that’s stalling the child states for some reason.

I really hate learning new systems, especially since I was used to the Behavior Trees. Although I did get confused a lot when the BTs got very complicated.

The StateTree does look way better. I just can’t debug it as easily.
I know this stuff is kind of a grind until it clicks.
++being able to run them on actors is sweet. I assume it will shrink BP EventGraphs since it can take the place of a bunch of logic. Now BPs can contain actions that get called from a StateTree.

try moving your sttmovetotarget task to a new child state before your attack target enemy state rather than running it in the parent state. Make sure you’re calling ‘Finish Task’ in that task if it’s the only task you have in that state.

You’re right about the event graphs. My BP’s using it are mostly helper support functions and the main logic is all in the STT’s

The custom Move To task directly below causes the child states to stall while AI is moving.

Ok I figured something out. The issue is with my custom built move to task. When it runs it keeps other child tasks from finishing.

I tested the exact same setup using the built in MoveTo task and everything works as it should.
Not really sure why mine is messing things up since my move to task is very simple.

Any ideas on why mine wasn’t allowing states to finish?
again, the tree is tested with built in moveTo and my custom moveTo. The tree only stalls when the AI enemy is moving to the target.
The built in moveTo allows all the child states to function normally even when the AI is moving to target.

Edit: Ok more specifically it is an issue with the “Move to Location or Actor” node. Maybe because its a latent node? idk. If I use simple move to or AI move to nodes it works fine.

when i do something like this i have a parent state as a gate, like you have here testing for target being valid, then run the child task states sequentially, using the transition On State Completed transition to Next State, when each state task finishes. You can make explicit transitions as you have now, or use Next State… really just preference but if you have to re-order stuff Next State is convenient. Also, keep in mind if you don’t have a transition defined the behavior is to run up the chain to root looking for a valid transition.

In your situation I would move the Attack Target Enemy and Attack Recovery up as siblings to Move To Enemy Target, as that is an action that happens in sequence rather than concurrently as you have it.

That’s why I recommend keeping your tasks in final “leaf” states with no children, as the order tasks get called isn’t guaranteed up the chain to root and can cause confusion. I mostly use parent states for checking variables to see if it should run it’s children and/or making event transitions to bail out of a branch.