How do I get an instance of a playercontroller and a pawn class?

So what I want to do is basically setup a custom playercontroller inside my gamemode and then make it possess a custom pawn/character on the start of the game. (By “custom” I mean one that I have made into a seperate class.)

I am aware that I have to declare the classes in the header file but I cannot figure out how to initialize them.

In order to use your custom classes, you can set the default playercontroller and pawn classes in the GameMode’s constructor, e.g.

AYourGameMode::AYourGameMode(const FObjectInitializer &ObjectInitializer)
	: Super(ObjectInitializer)
{	
	// Set default classes to use
	DefaultPawnClass = AYourCharacter::StaticClass();
	PlayerControllerClass = AYourPlayerController::StaticClass();
}

In order to store references to these, you can override the following functions:

header:

// Also add includes
...
#include "PWNPlayerCharacter.h"
#include "PWNPlayerController.h"

// Override SpawnPlayerController
virtual APlayerController* SpawnPlayerController(ENetRole RemoteRole, FVector const& SpawnLocation, FRotator const& SpawnRotation) override;	
    
// Override RestartPlayer
virtual void RestartPlayer(class AController* NewPlayer) override;

// A reference to your PlayerController
UPROPERTY()
AYourPlayerController* YourPlayerController; 

// A reference to your Character
UPROPERTY()
AYourCharacter* YourCharacter;

cpp:

APlayerController* AYourGameMode::SpawnPlayerController(ENetRole RemoteRole, FVector const& SpawnLocation, FRotator const& SpawnRotation)
{
	APlayerController* pc = Super::SpawnPlayerController(RemoteRole, SpawnLocation, SpawnRotation);
	
	// Try to cast to our PC Type
	YourPlayerController = Cast<AYourPlayerController>(pc);
	return pc;
}

void AYourGameMode::RestartPlayer(AController* NewPlayer)
{
	Super::RestartPlayer(NewPlayer);

	// Record expedient reference to our character
	YourCharacter = Cast<AYourCharacter>(NewPlayer->GetPawn());
}

Naturally there are multiple other ways to achieve this as well.

Thanks for your reply.

I get the first part about setting the default classes but I cannot I’m getting confused about the rest.
I’m not that familiar with C++ or UE4 so could you please elaborate on it?

Also I thought if you could do something like this:

Put this in the header of the gamemode:

AYourCharacter *yourCharacter;
AYourPlayerController *yourController;

Then initialize them (which I don’t know how) and then in the cpp:

yourController->Possess(yourCharacter);

The Engine will spawn the Default PlayerController, set in the GameMode automaticly. It will also spawn and posses a pawn if the DefaultPawn is not NULL. If you want to change this behavior, you need to override the Spawn function inside the GameMode. And i guess that is what staticvoidlol is doing.

He overrides the “SpawnPlayerController” and “RestartPlayer” function, which are doing the things i mentioned above.

He is calling the “Super::” Version of the functions, which is the normal implementation from Epic inside of the parent classes (so that you don’t stop the engine from spawning the classes) and adds the 2 commented lines, where he just sets the variables “YourPlayerController” and “YourCharacter” to the spawned ones.

PS: If you only want to spawn your custom classes, you only need to set them as the default classes. No need to override something. Include the header files of the two classes in the header file of the gamemode and do the DefaultPawnClass thing that staticvoidlol posted.

Yes, eXi explains this very nicely. I’ve also updated my original post to show how you declare the references (as you already seem to know how to do) and also to include your “includes” of these classes, as they won’t be referenced in the GameMode by default.

So to summarise, you can latch on to the built-in Epic functionality of spawning the controller and pawn and possessing them - you just let these routines run and afterwards you set your specific references in these overridden functions.

P.S. Overriding RestartPlayer() instead of SpawnDefaultPawnFor() to create the character reference is intentional, as in recent builds, SpawnDefaultPawnFor() is not marked as virtual anymore, so you can’t really override it easily.

Thanks for the reply.

So I took your code and put it into my GameMode and tt gave me 2 errors saying

APlayerController *AControllerTestGameMode::SpawnPlayerController(ENetRole RemoteRole, const FVector &SpawnLocation, const FRotator &SpawnRotation Override SpawnPlayerController

Error: member function declared with ‘override’ does not override a base class member

And that Super::SpawnPlayercontroller only takes two arguments: SpawnLoaction and SpawnRotation.

I removed the

ENetRole RemoteRole

part from

APlayerController* AYourGameMode::SpawnPlayerController(ENetRole RemoteRole, FVector const& SpawnLocation, FRotator const& SpawnRotation)

and

RemoteRole

from

Super::SpawnPlayerController(RemoteRole, SpawnLocation, SpawnRotation);

and it worked.

I’m not really sure what the part I remove was supposed to do?

Also how would you change the playercontroller or character afterwards?

Oh ok - I see in the official documentation SpawnPlayerController() does not have RemoteRole in its signature. I suspect we’re using different engine versions (I’m on the 4.8.0-preview-1 branch).

In any case, if you kept the “override” keyword at the end of the function declaration and it’s compiling without problems, then it should be fine.

Yeah that must be it, because I’m using 4.7.6.

How do you change the playercontroller and character during the game?

And would it be possible to do something like this so you don’t have to set defaultpawnclass and playercontrollerclass:

Header:

AYourCharacter *yourCharacter;
AYourPlayerController *yourController;

(Then initialize them(which I dunno how))

Cpp (possibly in BeginPlay()):

yourController->Possess(yourCharacter);

And if so how would yo initialize them?

If you’re in the gamemode you can use RestartPlayer after setting the new pawn / controller classes.

Thanks for you reply.
Could you please give me a code example?

AYourGameMode::YourFunction()
{
DefaultPawnClass = AYourCharacter::StaticClass();
PlayerControllerClass = AYourController::StaticClass();

        YourController = SpawnPlayerController(spawnLoc, spawnRot);
        RestartPlayer(YourController);
}

Thanks.

Is it possible to do without changing the defaultpawnclass and the playercontrollerclass?

Have you looked through the source code of GameMode.cpp?

Maybe checked out the functions like SpawnPlayerController and RestartPlayer?

Do you have any ideas you’d like to try?

I have 3 ideas that I can suggest, and it’s not because I just magically know Unreal - I had to go and read through the source code to try and figure out what it does.

I don’t want to sound rude, but I’d strongly suggest that you at least try to do something yourself before asking others to provide code for you. What you’re doing here makes you come across as lazy. Generally people are very eager to help out, but no-one’s going to code your project for you for free.

So, if you had to take a shot at it, what would you do? Let me know and I’ll help out if you get stuck.

Well looking at source code is not something I think I can do since I’m rather new to c++ in general.

The reason why I made this question to begin with was that I had spent days searching the internet thin, but I could find litlle no documentation about the subject. (Also in general I don’t think Epic provides much documentation about what stuff does (at least to an extent where a complete newbie can make much use of it)).

Between all questions I have tried myself, and what has mostly confused me is why this doesn’t work:

AMyPlayerController * controller = new AMyPlayerController();
AMyCharacter * character = new AMyCharacter();

controller->Possess(character);

Because from what I understand that is how you would usually initialize instances of classes in c++. (If this had worked it would be simple to change characters and controllers.)

(Also I did find out myself how to change character and controller):

void AControllerTestGameMode::BeginPlay()
{
 	CurrentCount = 1;
	PlayerControllerClass = AMyPlayerController2::StaticClass();
	DefaultPawnClass = AMyCharacter2::StaticClass();
 	RestartPlayer(playercontroller2);
	SwapPlayerControllers(playercontroller, playercontroller2);
}

And then:

    	if (CurrentCount == 0)
    	{
    		character = Cast<AMyCharacter>(NewPlayer->GetPawn());
    	}
    	else if (CurrentCount == 1)
    	{
    		character2 = Cast<AMyCharacter2>(NewPlayer->GetPawn());
    	}

in

void AControllerTestGameMode::RestartPlayer(AController* NewPlayer)

and same just with controller in

APlayerController* AControllerTestGameMode::SpawnPlayerController(FVector const& SpawnLocation, FRotator const& SpawnRotation)

However I hoped that the answer I would get to the code example on how to do it would be an example that did not use the PlayerControllerClass and the DefaultPawnClass, because I assumed you couldn’t do it that way in multiplayer.

Ok fair enough - I hear you about being new to C++ and Unreal in general, I was in that same boat a year ago, but you can pick it up fairly quickly if you make an effort. That’s the main reason why I strongly suggest that you read the source code - even if it doesn’t all make sense right now. The syntax and specifics will become fairly familiar after a while.

As for the Unreal codebase, yes, they do some things differently from bare C++ because they’ve built massive amounts of functionality into the system (like reflection, garbage collection, generics etc) and there is a lot of template usage as well. So for many things you’ll need to figure out the Unreal way of doing it - however, as I’ve said, it becomes familiar fairly quickly.

As for the multiplayer part of your question: do you mean that for multiplayer you would be using different Pawns/Controllers depending on which avatar/class the player chooses? Multiplayer is another whole subsystem which I haven’t even looked at (I’m only focusing on single player).

edit:

I think a good example would be to look at Unreal Tournament 4’s source code on GitHub to see how they’re handling multiple controller/character classes.

I am not a big newbie in C++ but there are code syntax that i never seen in my life :smiley: And he just should look at the content examples. The FPS shooter is a great example for how to do it.

After realizing that both the character and playercontroller were deriving from AActor I figured you could just use SpawnActor and then SwapPlayerControllers to swap the original Playercontroller (set up with the code you provide to me earlier) with the new one and it worked!

I have had a quick look at the source code and it looks way simpler than I imagined (especially because Epic has put in alot of comments explaining the code) and it seems like the way to go as far as learning the engine is concerned.

About the multiplayer part yes that is indeed what I mean.

Cool man, glad you’re making progress.

Just a quick note, PlayerControllers seem very lightweight in UE4 - i.e. most of the functionality has been moved into the Pawn/Character classes, so you could probably get away with using a single PlayerController type and just swapping out Pawns/Characters.

Good luck!