I need to delete a specific actor when the character has finished moving, for that I don’t know what else to use than the “On Move Finished” execution pin from the “Move to Location or Actor” node.
The problem is that when I have 2 characters moving at the same time, the object deleted will be the wrong one as the reference I’m using is based on the latest moved character.
So I need a way to retrieve that reference to the character that has stoped moving from the “Async Task” pin, if it is possible.
](filedata/fetch?id=1786888&d=1594489398)
Am I doing something wrong ?
It looks like that when movement is done the task gets killed, which is annoying because I need to read the reference value at the moment movement is done !
Is there a way to prevent the task from getting killed immediately ?
Because I need to know the reference to the Pawn/Character that has stoped moving.
What should I do then ?
I don’t even know if i’m using the good function. I didn’t find anything that allowed me to get the character that is being moved…
Edit : After a few testing it looks like “get controlled pawn” is the right function for what I need, it show me the reference of the character being moved. But I need to get it at the moment the unit stop moving but before the “AITask” get pending killed.
When movement is done for that 2nd character BEFORE the 1st character has finished moving it will delete successfully the green path line of the 2nd character :
This is because I am using the reference of the latest character ordered to move.
I need to find a way to get the reference of that 1st character when it is done moving so that I can order his green path line to be destroyed at the right time.
To be honest, I wouldn’t have done this way. I would have given a controller to each character.
Anyway, considering the way you setup things, the only way I see in identifying the character that ended its movement is through its velocity and last update velocity.
Unless you’re going to have only 2 characters. In that case, a separated “Move to Location or Actor” to each one.
The “Unit AI” is the controller. It is controlling a pawn. You know which pawn you’re controlling. Tie “get controlled pawn” to the Unit AI variable, and that’s the controlled pawn.
If this code runs in some global spot, and the value of “Unit AI” changes between invocations, you might want to just put the “move to point” and result handling into the Unit AI controller itself, so you just call a custom function on the Unit AI that takes care of it. That might make it easier to keep track of what’s going on.
Because you’re controlling multiple units, you want one record of the state and control flow for each unit. The easiest way to do that is to put the smarts into the AIController for the moved Pawn.
I have decided to put it in the character blueprint, because I have never touched ai controllers.
Is there a particular advantage to do it inside the ai controller instead of in the character’s blueprint ?
In the player controller : ](filedata/fetch?id=1786979&d=1594505409)
In the character’s blueprint :
An AI controller doesn’t really care what the character looks like, and how it animates, or what special particle effects it has.
E g, you may have a “glowing lava monster” and a “ghostly ghost” and a “small gnome” which have different character blueprints, because they have different effects and animations, but the AIController can still control all of them – either because it only uses the Character interface, or because you expose a new interface on each of those characters with functions like “start attack.”
The rule is that “if it has an obvious, visual effect on the screen, it goes in the character, else if it reads the player or AI intents and makes decisions, it goes into the controller.”
The Character really is an extension of the visual mesh, but shouldn’t be imbued with any smarts. Think of it as an action figure. Think of the AI controller (and the player controller) as the “remote control” that drives these Characters around, and consider that a single class of controller may very well be used for many characters (or many pawns, if you don’t like the Character interface.)
You can download all the Paragon characters, and see that they have different skeletons, different animations, and different effects for each character – each of those have a different character blueprint. However, you can make one player controller that drives around any one of those characters.
(The fact that the default blueprint starter kits put reading the control input into the Character instead of in the Controller is a crime against the engine, IMO. The first thing I would do when starting a new project is to select-all, delete, all the event handlers in the Character/Pawn, and put the control logic into the player controller subclass.)
I see the logic of the final answer here, though it feels like bad design to have the AIController giving itself orders instead of the PlayerController giving them… surely the AIController’s job is to follow orders, not to give itself orders.
I wonder why they chose not to have a pin at least returning the reference to the Pawn that was moved on operation finish/failure? The async task has to have that reference, so it would seem like no extra overhead to have it return the Pawn. It would be much neeter to simply handle the whole order including it’s completion in the PlayerController.
I don’t understand. (Also, way to necro a thread 4 years later …)
The whole point of an AI Controller is to automatically generate orders to the pawn it controls, whereas the whole point of a Player Controller is to let the player generate orders to the pawn it controls. That’s what they’re for.
It’s ok to comment on old threads, that’s one of the beauties of the internet.
So what should I use instead of PlayerController if it is giving orders to many pawns, such as in an RTS situation? Not every game is one player controlling one pawn. Even if the Unreal starter projects all lean that way, I’m sure it wasn’t their intention to only support that. As far as I’m aware, PlayerController is still the class designed for that job isn’t it?
In an RTS situation you dont possess the pawns, you give them commands that the AI carries out.
So the player commands ‘Move Here’ and the AI figures out how to path there and move the pawn. It can still have a callback which would be a custom event you create which can than return the pawn that moved
Yes, that is indeed the pattern I was using. The player controller isn’t possessing multiple pawns, I wouldn’t have thought it can. It only posseses a camera Pawn at game start.
The player controller was calling the MoveToFoo() methods on the pawns possessed by AIControllers. I’ve had to move the MoveToFoo() call into the AIController itself though as it seems to be the only way to maintain the reference to the Pawn that’s just finished being moved when that method completes. That part is what was bugging me as I’d rather that was all contained in the PlayerController being the class that is meant to be managing the Pawns/AIControllers, and that would avoid one extra Event callback as this kickstarts a series of event calls that goes up to GameMode for server processing and back to PlayerController as it is.
I’ve resigned to do it that way now, but it would be nice if the MoveToFoo() methods gave a reference to the pawn that just finished moving when returning on the finished execution pin.
No a command needs to be generic, you can tell a unit to move, attack, use an ability etc
the MoveTo Function is the execution of that command, the player doesnt care about the execution, this is important because Units may execute in different ways, you may have a unit that flies or swims etc
they also may just be doing different things, attacking, harvesting, moving etc
Hmmm… I might be able to get behind that design logic. So you think the AIController should accept more generic commands and handle the low level implementation of that internally? I assume you mean the AIController rather than the Pawn?