GetController() returns nullptr while GetPlayerController() works properly

I’m writing an ACharacter derived class.

Calling GetController() in either BeginPlay() or overidden EndPlay() methods returns a nullptr, while calling GetWorld()->GetFirstPlayerController() properly returns the controller of my character.

GetController() works ok in all other methods called during the life of my character.

Why can’t I simply get my pawn’s controller using GetController() if APlayerController is a child of AController? Isn’t it true that an upcasted APlayerController will give me the AController possessing my character?

1 Like

Makes perfect sense. Your Character doesn’t have a Controller at Character::BeginPlay, you can only get your Characters Controller after OnPossessed(). When you get Endplay() the Character most likely has been Unpossessed, so no Controller there either.
“GetWorld()->GetFirstPlayerController()” is giving you the login Controller, this Controller may or may not have a Character possessed, depends on when you call it.

1 Like

So the controller I get from GetWorld()->GetFirstPlayerController() and GetController() is not the same object? Does that mean my character is being possessed by 2 controllers at the same time? If so, what is the difference between the login Controller and the Controller I’m receiving from GetController()?

I assume you are using a 1P/3P standard FPS template for your project, some things are handled automatically and you get some initial setup done. When you start(login) you get a PlayerController and a PlayerState object, at this point there is no Character but as the PlayerController(child of Controller) handles the UI you can do login widget etc.
At some point the Gamemode spawns your Character and runs BeginPlay, again you have no Controller set here yet. Soon after the Character(Pawn) is possessed by your PlayerController and you can access it with GetController().

So for a standalone game you have one Controller that is a PlayerController but if you try to get it from inside the Character you need to do that after the Character is possessed, only then will the Character have the Controller property set.

Everything is perfectly clear to me now. Thank you!

The documentation is mostly a collection of header comments, better is to actually take some time to read the engine code for the functions. As you get into networking/multiplayer with controllers things get even more complex. The best networking documentation i know is this one : http://cedric-neukirchen.net/2017/02/14/multiplayer-network-compendium/

1 Like

IsLocalController and IsLocalPlayerController do the same thing when the target is a PlayerController but if it is an AiController then IsLocalPlayerController always returns false.

IsLocallyControlled is used on Possessed pawns and it simply calls IsLocalController. If Un-possessed it always returns false.

Hey! How can I set this up so that it works just like the 1P/3P template when starting from a blank project? So that I could call GetPlayerController() in a constructor and it will work from the outset? Are there some docs on this?