Customising The Player View
Customising the Player View
Before we get into the real meat of how to fix the player views we need to understand the code that is already there. Grasping the link between the posessed pawn (stored in the Pawn attribute) and the current view target (held in the ViewTarget attribute) is essential to obtaining the desired effects. Before we go any further lets recap on a few of the attributes of the PlayerController.
- Pawn
- This is the Pawn that the player has possessed. A possessed pawn is controlled by the player. The pawn class occupied by the player makes callbacks to the PlayerController in use to determine what should happen when the player attempts to make the pawn perform an action (run forwards, change weapon etc).
- ViewTarget
- The view target is used to determine what the player sees. Nominally the view target is the actor displayed at the center of the current view. The most important thing to remember about the view target is that it does not have to be the same object at the possessed pawn.
- Rotation
- This is the rotation of the PlayerController class itself, as set by the SetRotation() function. This is invariably set by the PlayerMove() functions of the PlayerController class. This is used by the CalcBehindView() and CalcFirstPersonView() functions in the determination of the view rotation.
In order to set the player view to that of your chosing you will need to perform the following steps.
- Create a new game type class and reference your player controller within the PlayerControllerClassName property.
- Create a player controller class that will implement your shiny view.
- Override the PlayerCalcView() function in the player controller class to set the view you want.
Create a Game Type Class
Assuming that your new game type is going to be based on a deathmatch game, you could use the following code. The important thing to note is the mechanism by which the custom PlayerController class is referenced.
class ViewTestGame extends xDeathMatch; DefaultProperties { PlayerControllerClassName="ViewTest.ViewTestPlayerController" // This is the important line }
Simply save the code as /UT2003/ViewTest/Classes/ViewTestGame.uc and you should be well away. You will also need to create a ViewTest.int file.
Creating the Player Controller Class
This is where the real work is done. Since we have already created our game class and named the player controller class we are going to create we had better keep the same name. The following code will allow us to play around.
class ViewTestPlayerController extends xGame.xPlayer; var Actor myTarget; var bool targetIsMyTarget; // The player view is determined by this function. function event PlayerCalcView(out actor ViewActor, out vector CameraLocation, out rotator CameraRotation ) { Super.PlayerCalcView( ViewActor, CameraLocation, CameraRotation ); } // Locates the dummy view target object set up on the map - in my case I used a blue flag decoration. function PostBeginPlay() { local actor newTarget; Super.PostBeginPlay(); foreach AllActors(class'Actor', newTarget, 'newView') { myTarget = newTarget; SetViewTarget( newTarget ); break; } } // The following function allows us to switch between a view target of the player pawn and the dummy view target. exec function ViewTest() { if ( targetIsMyTarget ) { SetViewTarget( myTarget ); } else { SetViewTarget( Pawn ); } targetIsMyTarget = !targetIsMyTarget; }
Overriding the PlayerCalcView() Function
I'm not going to provide any code in here (well, maybe a bit) as setting the rotation and location of the view is as easy as setting the output variables CameraRotation and CameraLocation. I will say that the purpose of the ViewActor output variable is still a bit of a mystery - but it might be there to support setting the view the player sees when the player has died or other similar function. The following guidelines seem to hold true.
- In order to fix the view rotation and still allow the possessed pawn to be controlled you can set the CameraRotation to a fixed value and set the ViewTarget to the possessed pawn.
- It's generally better to use the Rotation property of the controller than either the Pawn.Rotation or ViewTarget.Rotation properties as this takes network issues into account.
- The ViewTarget can be any object of type Actor.
- The player can only possess Pawns
- Explicitly set bBehindView to true to remove the floating player weapon (if it appears in thrid person view).
Related Pages
- PlayerController – A discussion on Player Controllers and how to make them do what you want.
Questions and Discussion
EntropicLqd: I realise that there is some duplication between this page and the PlayerController page but I'll worry about that when I'm happy with the entire piece. The information overload section isn't quite complete as I've not finished commenting the code.
Information Overload Section
Here's a quick run down of some of the things I did while working out how it all worked. A lot of it is fairly redundant, but nonetheless was somewhat amusing.
A Quick Experiment
In order to explore the default behaviour of the ViewTarget and Pawn we shall created a small map with a single player start and a static decoration. I gave the static decoration a tag of newView and placed it near the player start, facing it. I then went on to create my own game type (called ViewTestGame), and my own player controller class. The code is fairly self explanatory and shown above.
OK, if you can be bothered to repeat the experiment (or even if you can) here's what you'll find.
Prior to the game starting you'll see that the view is centered on the decoration. This is because the PostBeingPlay() function sets the view target of the controller to be that of the decoration. However, once in the game you'll be playing as normal and you'll be able to run around the map in both first person and third person (using the behindview console command) views.
When viewing the player from the first person, position your player such that the decoration is "looking" at you. Then enter the command ViewTest at the console. You should see the view change and with luck you'll be able to see your player. If you can't see your player use the view test to toggle the view back to the first person perspectivew of your player and reposition yourself so you can be seen. You should notice three things.
- You still have complete control over your player pawn, you can make him look up and down, run, jump, fire weapons, everything that you would normally be able to do.
- Your view into the world is completely fixed in the direction the decoration happens to be facing. You cannot change the view at all (although altering the FOV will work).
- Not only can you see your player pawn, but you can also see the weapon your player currently has selected floating next to the player. As the pawn moves around the weapon also moves around with it – sort of.
Now switch to the third person perspective by entering behindview 1 at the console. You should notice the following things.
- Your view has pulled back slightly.
- The floating weapon has vanished into thin air.
- Your view now rotates as you look around with the mouse.
- You still have full normal control over the player pawn.
It's all interesting stuff as it gives us a basis for working through the code and figuring out what's going on. The view the player sees is ultimately controlled by the PlayerCalcView() function. Control this and you can make them look anywhere you want to.