Extending controller

Hello, I’m trying to extend the controller from unreal engine.
The goal is, that I can later create controllers for the player and for my AI that share some functionality, using PlayerController and AIController from the engine.
However I’d like to avoid writing directly into the controller source code from unreal, since I’m not aware of how to avoid conflicts with engine updates.
What options do I have to achieve this? I’d also like to add that I’m new to c++ and therefore may haven’t seen some of the simple solutions.

Thanks in advance for your help :slight_smile:

  1. Create a c++ class using the engine. I would pick Actor as parent class. Call this class CommonCtrlStuff (or whatever). Code whatever you need.
  2. Create a c++ class with AIController as parent, #include CommonCtrlStuff.h. Create a c++ class with PlayerController as parent, #include CommonCtrlStuff.h.

Your two latter classes should now have access to all the functionality you defined in CommonCtrlStuff.

If you’re into ECS, you could pick ActorComponent in step 1.

I used this trick (BlobComponent class #include BlahComponent.h) and it’s working fine.

Wow that was a fast response :smiley:
Does your method work too if I want to have common variables and if i want to later access the controller without having to cast them twice?

I tested it and since i couldn’t manage to put this actor that you suggested in a common parent class, while avoiding to change the source code, it didn’t work as intended.

Further I tried to directly generate a child named AExtendedController of “AController” from unreal. From this class I generated AExtendedPlayerController (I know the name may be a bit long but it’s easier to understand like this^^) and copied the content from unreals’ APlayerController, replaced the names and compiled. The problem there was that the following #includes didn’t work. #include "EnginePrivate.h, #include "IHeadMountedDisplay.h, #include "IMotionController.h. That may be the reason why I got a ton of compiler errors of undefined classes and functions.
Now my question. Is my attempt in general a stupid way to do this? If not why do these #includes make problems?

What functionality do you need to share?

Is it something that could be on a character instead?

Is it something that could be achieved via an interface, such as the IGenericTeamAgentInterface?

An Interface, Actor Component or a static function library is probably the best approach.

It should contain an inventory including the whole functionality as well as the needed variables. Stats such as MaxHealth, MaxStamina etc.
I want to have them in the controller to keep them in the case of death or a map travel. So no sadly it’s not possible to put them in the character.

With interface do you mean the same thing that exists in blueprints as interface? I used blueprints before but c++ is new to me.

As mentioned above the solution with an Actor Component doesn’t seem right for me since it would still require me to differ between AI and Player. Same goes for a function library i think?

Inventory / Health stuff doesn’t look like something that should be stored with a Controller… that feels like a design fault that’s asking for trouble. You can write additional code that handles death / map travel etc. Those sorts of variables are typically stored with a Pawn, since the Pawn is the object they affect really, not the controller. The pawn also doesn’t really care if it’s controlled by AI or not.

I use Actor Components when I want to append functionality to an engine class. In my case I have Vehicles that extend ‘Pawn’, and engine Characters that also extend ‘Pawn’. Rather than duplicate common functionality between the vehicle and the character, I just give both of them an Actor Component that contains that functionality and any vars I need. In my case, that’s things such as health, inventory, ammo, gameplay properties etc.

Interesting I always thought controller was a good place since it is persistent. But I am no professional so it’s nice to learn new stuff :slight_smile:
But why do you choose an Actor Component instead of creating an Object based class?

UObject-derived classes are not replicated.

The Controller shouldn’t be used because the controller may be used for different pawns.
Lets say you have Pawn A and Pawn B.
You play with Pawn A and lose Health (which is stored in your controller).
If you change the Pawn to Pawn B, the Health stays the way it is. This means Pawn A and Pawn B share the same Health.

I totally forgot that I should keep the replication in mind.
But many thanks to you guys, I really appreciate your effort to help me. :slight_smile:

Additionally, it’s worth noting that clients only know about their controller - they don’t create controllers for other players :slight_smile:

As TheJamsh mentioned, controller isn’t really the place to store such things, but if you really need a persistent one, a separate actor component or object is a good idea (especially for replications reasons).

For information about C++ interfaces, check out this wiki entry:
Interfaces in C++