I need to make NPC in my game be able to start new action only after previous one is over.
For examle NPC walks to certain point in level, makes slow 90° turn, then walks to another point etc.
I need every action to start exactly after previous has finished.
In blueprints ther’s AI MoveTo Node, and it has a “On Success” and “On Fail” outputs, which are being instigated when movement concludes.
What I’m trying to do is to write and implement in c++ functions/classes that would have similar “delayed” calls to what should follow next.
I had my thoughts of Tick function, but I’m not sure if it is what I really need, and believe there should be easyer way to do this.
It would be very appreciated if someone could point me in right direction or what’s even better, give me a good tutorial to read.
I am not an expert on this, but here is what I found:
In C++ the AIController seems to provide what you need:
You can call different MoveTo methods depending on what you need this one and this one.
Instead of the OnSuccess and OnFailure Nodes you have to override the OnMoveCompleted method. This methods is called by the engine when the move is finished, together with a FPathFollowingResult which has a Result Type that holds the information you need to determine if it was a success your failure.
So what you would do is implement the OnMoveCompleted method, and branch on the result like this for example:
and so on. Now these are a lot of links, but you can just always return to the AIController Documentation to keep track of what you are doing. I hope this gives you a good idea of what you have to do!
Good god, I was trying to dig so hard and missed that this method is called automatically, even though I’ve looked through it! Thank you so much for pointing me out in right direction!
That solves my question in case I have AIController tasks, but I might have other non AI tasks for my NPCs, for example play some animation (cutscene or, I don’t know, sound). Is there a way to create some method inside my classes, that would be called at certain point the way OnMoveCompleded() is called? (I’m thinking of Tick() again lol)
Well you could certainly do that in the tick function. Another possibility may be to split the move in two moves, one to the point where you want the trigger to happen, and one to the end point. You would then have to keep track in your OnMoveCompelted if you are at an “intermediate” trigger point, or really at the end. Doesn’t seem to complicated either way.
#3. Receive Results Through The Function OnMoveCompleted
void MyClass::OnMoveCompleted(FAIRequestID RequestID, EPathFollowingResult::Type Result)
{
switch (Result)
{
case EPathFollowingResult::Success:
break;
case EPathFollowingResult::Blocked:
break;
case EPathFollowingResult::OffPath:
break;
case EPathFollowingResult::Aborted:
break;
case EPathFollowingResult::Skipped_DEPRECATED:
break;
case EPathFollowingResult::Invalid:
break;
}
}