[Ai/C++] Help implementing route data for route patrol ai

Background:
I’m starting to create a simple 3D game with UE4 and am trying to implement simple route patrol behavior for my enemy characters. I’m used to programming in C++, although I haven’t yet figured out all of UE4’s nuances. I don’t intend to use blueprints for the moment.

Progress:
So far, I have added a “Route” actor and a “RouteNode” actor.

Each RouteNode contains a transform and other useful information (like whether to stop or not and if so then how long). The reason that it’s a transform rather than just a vector is because I will probably also use the rotation information for indicating which direction to face after stopping.

Each Route contains a dynamic array of RouteNodes.

I will set the initial Route in each enemy character’s data, which will be used by the AI for knowing where and how to patrol (for now, they will basically just move to each RouteNode in the Route in order).

The Issues:
Here are the problems I am currently facing:

  1. Being able to use the editor’s translate tool to manipulate each RouteNode’s transform. At first I tried just adding a FTransform as a UPROPERTY to the RouteNode actor. I soon noticed that I wasn’t able to use the editor’s translate tool to manipulate it. I looked around, but couldn’t find any way of hooking up the translate tool to this property. Also, I don’t really get how it works, but it seems like actors (like the TargetPoint) that have a RootComponent are given a transform that is able to be manipulated via the editor. I’m not sure if this is the best way, but is there a way to automatically add a RootComponent when creating a RouteNode data via the editor, perhaps by adding a bit of code to the actor’s constructor? Being able to automatically add an icon or something would be pretty neat too. How does the TargetPoint do it? I would just use a TargetPoint if I could, but I also need the extra RouteNode specific properties that I am adding.
  2. This is less of an issue at the moment, but would there happen to be a more elegant workflow for creating the route data set than creating all the nodes and dragging them all into the Route data’s array one at a time? It seems like having some sort of tool where you could just click on the route and then click on the environment to add nodes to the appropriate part of the route could save a lot of time. Also being able to remove nodes from the route while at the same time properly adjusting the size of the route’s dynamic array would be nice. If we end up making and adjusting a lot of routes, then spending the time to create a tool like this seems like it would be worth the effort. However, I don’t even know where to begin. How do you make a tool like this for the UE4 editor?

I think I’m on the right track here, but if it seems like I am taking a completely inappropriate approach to implementing route patrol behavior for UE4 then please let me know.

Thanks!

First of all I suggest you grabbed full UE4 sources from the github repo, since there’s a lot to learn from :slight_smile:

The translate tool in the editor - it basically operates on actor root component’s transform. You can set your root component in actor’s constructor (lots and lots of engine actors does that, like ACharacter). You can in fact reuse TargetPoint - just derive from it! :smiley:

One very useful function you can override is AActor::PostEditChangeProperty which gets called whenever you change properties on an actor instance in the editor.

Regarding easier route-building you could use USelection::SelectObjectEvent to get notified when an route node actor is selected in the level and just link with the previous selected node. Dig around SelectObjectEvent and you’ll find other useful functions :slight_smile:

Cheers,

–mieszko

I’m in the middle of starting something similar to this, and I was wondering if it would be better ( and possible) to use FNavigationPath objects and make them available in the editor?
The idea would be to get designers to create paths in areas that then could be assigned as current path directly, would this be feasible?

There’s UNavigationPath that would be a good start of such solution, but there’s too much related stuff missing to recommend this approach.

I would recommend deriving TargetPoint like MieszkoZ said. I have something going on similar to this but with a generated spline that acts like a path :slight_smile:

Thanks! I didn’t realize that I could change the constructor to use FObjectInitializer as an argument. Rookie mistake!

Changing the constructor to this adds the RootComponent automatically:

ARouteNode::ARouteNode(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) { USceneComponent* SceneComponent = ObjectInitializer.CreateDefaultSubobject(this, TEXT("SceneComp")); RootComponent = SceneComponent;