Best way to perform an action only after moving to location

For clarification before we begin, this is Unreal 5.3

I’m trying to design a system that lets me move a character around the world and perform various actions automatically according to a list of commands (I.E. built-in cutscene logic). I’ve already designed the macro that only activates the next command after the previous one completes, but I’m struggling to find the best way to make sure the player character is at the specific location I ordered them to before executing the next command.

Here is how the current commands should work: the player receives an array of commands to execute, this array is iterated across and individual commands are parsed by a simple switch on an enum, the commands are executed in full, then (and only then) does the next item in the array get processed. Ideally.

The Simple Move To Location node, however, executes its pin immediately after starting the navigation, and while the Move To Location or Actor node doesn’t do that, it does require an entirely separate AI controller (I don’t know why, I presume because it uses tasks, which is kinda annoying that Simple Move takes a Controller and Move To takes an AIController). I did find another post here suggesting that a timer can be used to query when the player has arrived, but I’m worried this might not play nice with the way my macro is set up, which probably isn’t true but I figured I’d ask before I go about doing it and getting frustrated.

I also don’t think I’m setting this up correctly, it works (the player moves) but if I add any debug strings I don’t see anything printed to the console.

So, my question: what is the best way to ensure the player is at the location they’re walking to before executing the next command? Is it timers and I’m just being paranoid about how stuff works? I did get burned recently learning that the For Each node doesn’t work the way I expected, which is what started this whole mess. I’m willing to dip into C++ as well, at least a little bit.

Smart Object is your friend…

if you cant use the MoveTo with callbacks then yes you just have to poll on tick/timer however you also have to check fail conditions or your loop will get stuck.

if this is the extent of your system its not too hard to get working however it doesnt scale well. a better way would be to have each task be an ‘object’ and each object knows how to run and when its complete. so rather than a switch statement you just constructobjectofclass (moveto, turnto) etc

this is similiar to how behaviour trees/state trees and GAS work. in fact i’d probably recommend a state tree for your system

What kind of actions are you trying to perform after the move? Are you trying to interact with an object (like clicking a chair to go sit in)? Or doing random stuff like telling player to go here and dance?

Little work around…

Create an actor with a small sphere collision that overlaps the pawn and calls a “Current Command” event on the pawn. Have the pawn spawn this actor locally on begin play.

Teleport this actor to the goal location after you call Simple Move to Location. When the pawn reaches the goal it’ll trigger the actors overlap.

You should enable and disable the collision as needed, so there aren’t any hitches.

Disable collision by default. Enable it just before teleporting it to goal locations. On BeginOverlap disable it, then call pawn command event.

It’s primarily sprites that will have extremely limited actions like turning and walking, similar to early generation Pokemon overworld sprites, so “dancing” would just be something like turning or doing a flipbook animation in place. Though I did want the ability to trigger events on other actors in the world, if only to avoid timing issues.

The suggestion from @Auran131 about state trees might be something I’ll look into, my only concern with that is whether or not it’d require me to add an AI Controller to the character (documentation doesn’t mention it, but documentation doesn’t mention a lot of things and is sometimes just wrong).

This’ll have to be something I look more into, thanks for the advice.

To do anything specific at a clicked location (like playing a flipbook), Rev’s idea to move an invisible actor with a trigger box on it to call a character function on begin overlap might be the easiest.

Or if you only use click to move and don’t have any gamepad or keyboard controls to directly move up/down/left/right you could just give player char an ai controlller, and have the player controller just possess a spectator actor with a camera on it, and pass the fancy ai moveto commands along to the ai pawn. This would obviously confuse certain native commands like getplayerpawn, but as lonhg as the player controller keeps a ref to the remote control ai pawn, you should still be able to daisy chain it to other things (like ui) which might care about character.

Oh, and if you haven’t tried it already, I’d recomend checking out the PaperZD plugin. It lets you make anim blueprints for sprite chars like the ones used by 3d chars, so you don’t have to manually set flipbooks all over the place or clutter character graph with state machines and such, With that alone you could probly skip half the command logic by just making the anim bp change to an idle and look around flipbook or something when velocity hits 0.