Why does PlayerController "own" the yaw pitch and roll, but the Character "owns" its location?

Hi folks,

I’m new to UE4 and am trying to understand some basics concepts around controlling a character pawn. I’m fumbling around trying to implement some character movement logic. I’m going for the basic WASD to move the character forward, back, side to side - like in pretty much every basic first person shooter. I also want the mouse input to rotate the character around.

I’ve got my own custom PlayerController and Character classes.

Adding the code to move the character around - front, back, sideways - seems to all go in the character class itself. There is a method in there called AddMovementInput that appears to modify the position for me. This also makes me think that the character class “owns” its own location. That makes sense because there could be more than one character class at a time, each at different locations, right?

Adding the code to rotate the character has similar methods for controlling rotation - AddControllerYawInput, AddControllerPitchInput, AddControllerRollInput. Simply looking at the names of the functions suggests that the yaw pitch and roll are “owned” by the player controller. Looking at the docs and comments for the functions further backs that up: “Add input (affecting Yaw) to the Controller’s ControlRotation, if it is a local PlayerController.” So it would seem, to me, that the yaw pitch and roll are values “owned” by the player controller, right?

As a beginner, this confuses me. I’m just confused by the fact that the location is stored in the character itself but the rotation doesn’t seem to be?

Could somebody please help break this down for me and explain how I should “think about” character or pawn movement? I’m just unclear on it and it’s kind of causing me to get hung up on the topic.

Thanks!

1 Like

Its a good question.

The Character inherits from Pawn, which inherits from Actor, which has a GetTransform, which it gets from transform of its RootComponent.

A Transform includes position and orientation.
So basically everything rendered in the world has a transform.

On the other hand, the Controller is focused on representing the human player and can possess and control pawns.

Part of control is the Control Rotation.
It is sometimes the pitch yaw and roll of the camera.

You might control a car, boat, plane, or monkey.
Your control rotation is often used to update the controlled Pawn transform.

It is not always direct, eg you might lerp the pawn rotation to match controller rotation over time.

As you are doing - you typically handle the input in the Controller and use it to modify the Character.

Thank you both, @franktech and @OptimisticMonkey. I’m pretty sure I have a better understanding of how to think about the controller interactions, now.

After looking at the AActor class, I see that it has a location and rotation that it keeps track of. The ACharacter class inherits this, too. From within my character class, I seem to be able to directly modify the actor’s rotation using SetActorRotation.

So, I’m assuming that when I instead use SetControllerYawInput that the Character class has some code in it somewhere that sees the Controller’s rotation data changes and then in turn modifies the Character’s own rotation data. I’ve not yet looked at the Character class code, but I’d expect to see in there, somewhere, some code that does this.

Edit:

I think I found where the controller tells the pawn which rotation to be using …

https://github.com/EpicGames/UnrealEngine/blob/release/Engine/Source/Runtime/Engine/Private/PlayerController.cpp#L916

I just want to add my two cents to this thread for others who find it because I see a lot of similar threads around, with helpful people gently missing the point of the question.

If you are in any other game engine other then Unreal (unity, godot, etc) there is no concept of the “PlayerController”. A script would just take input and apply changes directly to its attached transform (which controls position, rotation & scale). Also, a camera is simply an object that sits in the world and renders what is in front of it, there is no “camera owner”. All these ideas of “who controls the view” are Unreal specific. For Input, any script that wants to listen to the input can do so, it does not get “captured” and there is no ownership, other then what the programmer adds. I see a lot of posts with Unreal people talking past the question at hand (often trying to be very helpful I should note!) but often missing the point of the question because they are so used to Unreal that they miss things that are confusing to people coming from outside Unreal.

I think the original question is still very valid. There seems to be a distinction made between movement and rotation. For example, with a FloatingPawnMovement component, I can add an input vector, however there doesn’t seem to be rotation controls. Usually (such as in Unity), I would handle the rotation of the object and the movement of the object together, in the same place, but Unreal creates a hard distinction between them, seemingly forcing me to handle the rotation in the PlayerController while allowing the actual movement to be applied to either the Controller or the Pawn itself. It seems to be just accepted as gospel by the Unreal community but it is very confusing if you are not used to the architecture. I can’t seem to find any good reason for this distinction either, other then it is just the way it is done.

What I would like to do would be to handle the rotation at the Pawn level, so that different pawns would, for example, rotate at different rates. Like, if my PC possess a Tank pawn, it should rotate differently then a “human” pawn. Perhaps I am missing something obvious here but this seems like a common use case.

I’m not trying to knock the Unreal community, they are often trying really hard to explain things, just pointing out that it is easy to miss the forest for the trees when working with Unreal, and trying to understand why design decisions were made a particular way. Many of the concepts make sense when you understand them but just be aware this is mostly very specific to UE so confusing to us noobs from outside it.

You don’t have to use that system at all. CharacterMovement can turn off the bools that control whether the controller rotation affects the Character or not.

As to why this system exists (and many people create a similar system in other engines, as well), there are both replication and aesthetic reasons, and probably others too. PlayerControllers replicate much differently than Pawns, and you want to have the player’s input handled as fast as is possible, whereas said input may not actually affect the Pawn at all. As well, in something like a FPS game, your Pawn may completely ignore Roll rotation, or rather than causing a direct rotation of the pawn, it causes the head to tilt up/down instead of the entire player pawn.

There are fairly significant advantages to having the rotation driven in Controller over Pawn, in that the Controller is often needing to drive that rotation, or query that rotation, as well. So for the most part, it’s probably better to have it where it is used frequently, and mirror it to the Pawn.

There are probably other reasons I can’t think of as well. But mostly, it’s because the Controller Rotation doesn’t actually mirror the Pawn rotation in many cases.

1 Like

Thanks for elaborating.

As well, in something like a FPS game, your Pawn may completely ignore Roll rotation, or rather than causing a direct rotation of the pawn, it causes the head to tilt up/down instead of the entire player pawn.

So basically what you are saying is the Controller would rotate (including the camera maybe?) but the pawn would only use of those axis to follow the rotation of?

Thanks for explaining. I think it is just a matter of getting used to the way UE likes to do things.

Hi and thanks for the response. I think I am starting to get a handle on it and I appreciate you taking the time to answer my long winded questions/rants.

So just to clarify, are you suggesting I could capture the input in the Pawn directly, then just use GetPlayerController to access the controller and set the Controller rotation directly using this reference?

I think what was most confusing is just conceptually understanding how all the parts are implicitly linked. For comparison, a camera in Unity is just a stationary object that renders what is in front of itself does nothing until you tell it to do something. The camera in UE is intimately connected to a particular player, pawn and controller. The architecture totally makes sense once you understand what it is doing, especially (as you said) for changing vehicles, multiplayer, etc it is just a bit of a learning curve understanding what all the default behavior is doing if you are not used to there being any default behavior!

In Unity, it doesn’t supply really any of that default behavior. For multiple cameras for instance, I would have to enable /disable cameras manually or set a priority if you have multiple cameras) to set which one is active (there are more techniques, but in general). The camera doesn’t have any knowledge or direct connection to the Player itself unless I attach it to the Player prefab (similarly to how you would attach the Camera to the Pawn as a Component).

As I begin to understand how UE does things, it generally makes a lot of sense, I just don’t know if all the default behavior (spawning, cameras, pawns and controllers) is really that obvious for someone who is not experienced with it. It was really confusing as a noob as I was not expecting anything to happen and it was hard to identify/track down the implicit behavior. Unity is more of a blank slate, were UE is like, here is an existing game skeleton with systems in place, edit it to do what you want.