Now that we have an idea of how to setup a top-down camera and a grid overlay, it's time to clean things up and drop the Unreal Tournament functionality. We don't need an avatar running around while we're displaying a map and we want to be able to move independently of CSG and meshes in the level.
Make a backup copy of the files we've created so far. You'll have to save the copy outside the /Development/Src directory, otherwise the FrontEnd will try to compile them as well.
I'll outline the changes below if you want to follow along. Otherwise, links to archives of both versions are below.
BattleMapMain.uc
All we're doing here is changing the object we're extending from, to the base GameInfo class. We'll no longer be playing an Unreal Tournament match when we start a level:
Changing the base class again, as well as dropping the first person mesh fix (since there won't be any) and supplying an empty pawn. We also set a few properties to enable the pawn to move freely around the level. Essentially, we put the pawn in "flying" mode instead of "walking" mode. That allows us to move vertically as well as horizontally, and effectively zooms and pans the level.
Replace the entire BattleMapPawn.uc code with the following:
All we're doing here is removing the laser sight code. Delete the following three lines:
A lot of changes here. First, change the base object:
This is a new class to handle the camera. The base PlayerController object doesn't include the same functionality as UTPlayerController, so we're moving our top-down camera code here.
All we're doing is moving the camera position and POV after the real UpdateViewTarget "does its thing". We also want to force ApplyCameraModifiers() which handles things like camera shake. Because the camera will be so far from the source, the engine may try to skip that processing.
We wrap our changes in a check to see if we're in CinematicMode. We don't want to change the camera if we are. This allows us to do things like fly-throughs of a big room before a boss fight:
Lastly, we just need to change the base object of our PlayerInput class:
(Note: If you zoom in using the C key and the camera suddenly shifts and "sticks" for a few seconds, what's happening is that your pawn is dying. You've hit the Kill-Z for the level, just as if your avatar had run off a cliff. The camera should reset in a few seconds. In our own levels, we'll set Kill-Z low enough to compensate for the camera height.)
The original top-down UT mode source files
The new BattleMap mode source files
Make a backup copy of the files we've created so far. You'll have to save the copy outside the /Development/Src directory, otherwise the FrontEnd will try to compile them as well.
I'll outline the changes below if you want to follow along. Otherwise, links to archives of both versions are below.
BattleMapMain.uc
All we're doing here is changing the object we're extending from, to the base GameInfo class. We'll no longer be playing an Unreal Tournament match when we start a level:
class BattleMapMain extends GameInfo;BattleMapPawn.uc
...
Changing the base class again, as well as dropping the first person mesh fix (since there won't be any) and supplying an empty pawn. We also set a few properties to enable the pawn to move freely around the level. Essentially, we put the pawn in "flying" mode instead of "walking" mode. That allows us to move vertically as well as horizontally, and effectively zooms and pans the level.
Replace the entire BattleMapPawn.uc code with the following:
class BattleMapPawn extends Pawn;BattleMapHUD.uc
DefaultProperties
{
//this is just an empty skeletal mesh to prevent log errors
Begin Object Class=SkeletalMeshComponent Name=WPawnSkeletalMeshComponent
End Object
Mesh=WPawnSkeletalMeshComponent
Components.Add(WPawnSkeletalMeshComponent)
bCollideWorld=false
bCollideActors=false
WalkingPhysics=PHYS_Flying
LandMovementState=PlayerFlying
AirSpeed=+01200.000000
}
All we're doing here is removing the laser sight code. Delete the following three lines:
// laser sight from pawn to reticleBattleMapPlayerController.uc
bmPlayerController.Pawn.GetActorEyesViewPoint(pawnEyeLocation, pawnEyeRotator);
Draw3DLine(pawnEyeLocation, mouseOrigin, RedColor);
A lot of changes here. First, change the base object:
class BattleMapPlayerController extends PlayerControllerDelete the following blocks. These manipulated the behavior of the UT pawn:
config(Game);
// This basically locks the camera to the pawn's location, and adds CameraZOffset to the Z of the camera.Add the following block. This handles the "flying" mode that we enabled in BattleMapPawn.uc:
simulated event GetPlayerViewPoint( out vector out_Location, out Rotator out_Rotation )
{
...
}
// Force WASD to be NWSE, so use world rotation instead of pawn rotation
state PlayerWalking
{
...
}
// This makes our weapons aim to the pawn's rotation, not the controller's rotation
function Rotator GetAdjustedAimFor(Weapon W, vector StartFireLoc)
{
...
}
// Turn the pawn toward the cursor
function UpdateRotation( float DeltaTime )
{
...
}
// Force WASD to be NWSE, so use world rotation instead of pawn rotationFinally, replace the DefaultProperties section. We dropped our CameraZOffice parameter and added a reference to a new camera object we're going to create:
state PlayerFlying
{
function PlayerMove(float DeltaTime)
{
local vector X,Y,Z;
//GetAxes(Rotation,X,Y,Z);
GetAxes(WorldInfo.Rotation,X,Y,Z);
Pawn.Acceleration = PlayerInput.aForward*X + PlayerInput.aStrafe*Y + PlayerInput.aUp*vect(0,0,1);;
Pawn.Acceleration = Pawn.AccelRate * Normal(Pawn.Acceleration);
if ( bCheatFlying && (Pawn.Acceleration == vect(0,0,0)) )
Pawn.Velocity = vect(0,0,0);
// Update rotation.
UpdateRotation( DeltaTime );
if ( Role < ROLE_Authority ) // then save this move and replicate it
ReplicateMove(DeltaTime, Pawn.Acceleration, DCLICK_None, rot(0,0,0));
else
ProcessMove(DeltaTime, Pawn.Acceleration, DCLICK_None, rot(0,0,0));
}
}
DefaultPropertiesBattleMapCamera.uc
{
//this makes us stop immediately instead of decelerating
bCheatFlying=true
InputClass=class'BattleMap.BattleMapPlayerInput'
CameraClass=class'BattleMap.BattleMapCamera'
}
This is a new class to handle the camera. The base PlayerController object doesn't include the same functionality as UTPlayerController, so we're moving our top-down camera code here.
All we're doing is moving the camera position and POV after the real UpdateViewTarget "does its thing". We also want to force ApplyCameraModifiers() which handles things like camera shake. Because the camera will be so far from the source, the engine may try to skip that processing.
We wrap our changes in a check to see if we're in CinematicMode. We don't want to change the camera if we are. This allows us to do things like fly-throughs of a big room before a boss fight:
class BattleMapCamera extends Camera;BattleMapPlayerInput.uc
var int CameraZOffset;
// let it do it's fancy thing, then just set our own LOC and FOV
function UpdateViewTarget(out TViewTarget OutVT, float DeltaTime)
{
local vector Loc, Pos;
local rotator Rot;
super.UpdateViewTarget(OutVT, DeltaTime);
if (!PCOwner.bCinematicMode)
{
Rot = rotator(vect(0,0,-1));
Loc = PCOwner.Pawn.Location;
Loc.Z = Loc.Z + CameraZOffset;
Pos = Loc - Vector(Rot);
OutVT.POV.Location = Pos;
OutVT.POV.Rotation = Rot;
OutVT.POV.FOV = DefaultFOV;
}
ApplyCameraModifiers(DeltaTime, OutVT.POV);
}
DefaultProperties
{
CameraZOffset=6000
DefaultFOV=35
}
Lastly, we just need to change the base object of our PlayerInput class:
class BattleMapPlayerInput extends PlayerInput within BattleMapPlayerController;Now when you launch the game, the Necropolis level should start behaving more like a D&D dungeon map. Use the WASD keys to pan the map and Space or C to zoom in and out. Hit G to turn on the grid and resize it with the mouse wheel.
...
(Note: If you zoom in using the C key and the camera suddenly shifts and "sticks" for a few seconds, what's happening is that your pawn is dying. You've hit the Kill-Z for the level, just as if your avatar had run off a cliff. The camera should reset in a few seconds. In our own levels, we'll set Kill-Z low enough to compensate for the camera height.)
The original top-down UT mode source files
The new BattleMap mode source files