Control multiple pawns

Hi Guys,

I’m trying to figure out how to control multiple pawns within the game.

So what I want to do is, I want to start playing with a character in 3rd person view. While running through the level I want to be able to “enter” another pawn, things like a vehicle or something. So spawning a new pawn woundn’t be an option, since the pawn already exists within the level.

I just could control the input with one playerController, which doesn’t seem as “clean” to me. Since I would have to do alot of “switch / case” staements to figure out which pawn I’m actually controlling and what to do next.

My idea is to implement a playercontroller for every pawn. What I would have to do then, is to “posses” the pawn with the respective controller, which is quite easy, and I would have to hook up the new playercontroller. Exactly this is my problem. How would I declare that new playercontroller as the active one?

Or is there another way to implement what I want to do?

Thanks in advance.

Cheers Edregol

So I came a little further. UPlayer has a Method called “switchController” which I could use. However, I am failing at initializing my second playercontroller. Since a playercontroller does not have a default constructor, I do not know how to hand over the playercontroller.

My first one gets “magically” initialized by settings its class as default controller in the gamemode class.

I’ve already tried things like:

UQuizQuestion* NewQuestion = NewObject<UQuizQuestion>();
    
UQuizQuestion *question = UQuizQuestion::StaticClass()->GetDefaultObject<UQuizQuestion>();
    
UQuizQuestion *question = new UQuizQuestion(FPostConstructInitializeProperties::FPostConstructInitializeProperties());

Any Ideas?

Hey, I think this is a logic problem. There’s no need to switch controllers, that would make things much more complicated!? Why not make an interaction sphere component for the character, and identify/store whats in range of the character?

Thats exactly what I am doing. But I have to switch controls to the new pawn wich is within the interaction sphere.
First option would be: Put IF/THEN/ELSE into your controllers movment methods to differentiate the pawn, which is, in my oppinion, very ugly. Depending on how many diffent pawns you plan to control those statements tend to get very long and the code gets difficult to read.

But this is exactly what they are doing in the Unreal Turnament code, which saddens me a bit. To be fair, they are only differentiating between UTCharacter and a SpectatorPawn.
There is a small piece of code which handels driving within the UTCharacter class, but this doesn’t do much. So not much to get within that code regarding my problem.

Second option would be: Implement a playercontroller per pawn and swap controllers as needed. Thats what I want to do. But I cant figure out how.

Where are you going to implement save games?

I’ve made an actor class thats the base class for things that I can interact with. Admittedly it’s different, because I’m not taking possession of those objects in game, but the way the character interacts with different objects is very different. Each object is being reached through the base class. could you not do something like that? you’d have to build on top of the basic pawn…

I didn’t think about saving just jet.

It’s not that hard to get the pawn I want to control. I already managed to accomplish that. The problem is to pass on the input commands in the right way. And by right I mean, in a way which is flexible enough to build upon it.

Later on I might want to control a stationary turret as well a a flying/hovering vehicle. Each of those have diffent input handlings. I can’t imagine that putting another “else if” into the corresponding movement method of the controller is the answer to that.

The thing is, since the pawns are handled diffent, lets think of a normal character and a vehicle, I just can’t put the inputs through, at least not all of them. I have to know which pawn I am controlling and handle the inputs accordingly. Which means, the move forward method of the controller has to react diffrent depending on the pawn I am currently controlling.

To possess the pawn isn’t the problem. I would be able to know which pawn I am controlling within the controller itself. But currently I just can have only one controller, thats the thing.
I think it would be better to use seperate controllers for each pawn.

Would that not be in the movement component of the object you’re possessing? If I possess a default pawn i can fly around, if it’s a character I walk around. I haven’t changed the input settings of my game at all.

Your right, but if I don’t hook up the inputs which call the corresponding method within the pawns movementComponent the pawn just doesn’t react even if the movementComponent implements a method.

Some pseudo code:

in my playercontroller class I have a method wich handles moving forward:

   (W is pressed therefore this method gets called)
    moveForward (float amount)
    {
         call pawn->movePawnForward(amount)
    }

This works fine as long as I am controlling pawns which implement “movePawnForward”

but if I have a flying vehicle which implements thrustInput instead. That method woun’t be called when Im pressing “W”

so one option would be:
playercontrollerclass:

(W is pressed therefore this method gets called)
moveForward (float amount)
    {
          if possessed pawn = StandardPawn
         {
             call pawn->movePawnForward(amount)
         }
         else if possessed pawn = flyingpawn
         {
             call flyingpawn->thrustInput(amount)
         }
         (add another else if for each pawn which implements other
 methods than that)     
    }

Thats something I want to avoid.

but the class you’re controlling should have a SetUpPlayerUnputComponent function. That includes things like:
InputComponent->BindAxis(“MoveForward”, this, &AClass::MoveForward);
or
InputComponent->BindAction(“ZoomIn”, IE_Pressed, this, &AClass::ZoomIn);

You could bind any number of input commands in the Edit - Project Settings - Input section of your project…

InputComponent. Not sure what UnputComponent is :wink:

So, not only can you bind inputs to different functions, per class, each classes implementation of “moveforward” could be completely different, because when your controller possesses the class, it’s using that classes implementation…

Well, thats embarrassing. I forgot to set up the keybindings in the input tab in the editor. -.- With this done you just possess the pawn an the controls are hooked up. Sorry for that :frowning:

Thanks for pointing that out robbie :slight_smile:

No worries and no need to be embarrassed!

Why don’t you just put all of the input parameters inside each pawn class, then you have one player controller per player,
and the player controller posses each pawn, which will have all of the inputs for that pawn stored inside the pawn class itself. That is how I did it, I had player controllers switch pawns over the network too.

I’m not sure why you are putting the pawn specific controls inside the playercontroller

Thanks for answering slayeruk.
My problem was thinking way too complex as well as forgetting to map the inputs within the editor.
The approach you’ve describled is the way to go, at least in my opinion. I did it the same way after realizing what I did wrong :wink: