Chapter One – Creating the Isometric camera
Creating a new perspective
Now that we have our player controller ready we should be able to tack something bigger. Lets add a custom camera to our game. This tutorial is aimed at doing an isometric game, since UDK doesn’t support this camera type it will be a good training exercise for you.
Create a new script file named IsometricCamera. Change the “extends Object” to “extends Camera”. I will then ask you to copy the following function inside your script file. Put it right under the class declaration, you should end up with the following :
class IsometricCamera extends Camera;
/*****************************************************************
*
* TUTORIAL FUNCTION
*
* This function was extended from camera. Your pawn will request
* a camera type when its created with function GetDefaultCameraMode,
* Force it to 'Isometric'. This change is small and doesnt hinder the
* in-game use of other buil-in camera types.
*
* This is a skeletal function provided to be simple and to the point
* to get an iso camera, add more or extend from another parent class
* if you miss anything from GameCamera.
*
*
*****************************************************************/
function UpdateViewTarget(out TViewTarget OutVT, float DeltaTime)
{
local vector Loc, Pos, HitLocation, HitNormal;
local rotator Rot;
local Actor HitActor;
local CameraActor CamActor;
local bool bDoNotApplyModifiers;
local TPOV OrigPOV;
// store previous POV, in case we need it later
OrigPOV = OutVT.POV;
// Default FOV on viewtarget
OutVT.POV.FOV = DefaultFOV;
// Viewing through a camera actor.
CamActor = CameraActor(OutVT.Target);
if( CamActor != None )
{
CamActor.GetCameraView(DeltaTime, OutVT.POV);
// Grab aspect ratio from the CameraActor.
bConstrainAspectRatio = bConstrainAspectRatio || CamActor.bConstrainAspectRatio;
OutVT.AspectRatio = CamActor.AspectRatio;
// See if the CameraActor wants to override the PostProcess settings used.
CamOverridePostProcessAlpha = CamActor.CamOverridePostProcessAlpha;
CamPostProcessSettings = CamActor.CamOverridePostProcess;
}
else
{
// Give Pawn Viewtarget a chance to dictate the camera position.
// If Pawn doesn't override the camera view, then we proceed with our own defaults
if( Pawn(OutVT.Target) == None ||
!Pawn(OutVT.Target).CalcCamera(DeltaTime, OutVT.POV.Location, OutVT.POV.Rotation, OutVT.POV.FOV) )
{
// don't apply modifiers when using these debug camera modes.
bDoNotApplyModifiers = TRUE;
switch( CameraStyle )
{
case 'Fixed' : // do not update, keep previous camera position by restoring
// saved POV, in case CalcCamera changes it but still returns false
OutVT.POV = OrigPOV;
break;
case 'ThirdPerson' : // Simple third person view implementation
case 'FreeCam' :
case 'FreeCam_Default':
Loc = OutVT.Target.Location;
Rot = OutVT.Target.Rotation;
//OutVT.Target.GetActorEyesViewPoint(Loc, Rot);
if( CameraStyle == 'FreeCam' || CameraStyle == 'FreeCam_Default' )
{
Rot = PCOwner.Rotation;
}
Loc += FreeCamOffset >> Rot;
Pos = Loc - Vector(Rot) * FreeCamDistance;
// @fixme, respect BlockingVolume.bBlockCamera=false
HitActor = Trace(HitLocation, HitNormal, Pos, Loc, FALSE, vect(12,12,12));
OutVT.POV.Location = (HitActor == None) ? Pos : HitLocation;
OutVT.POV.Rotation = Rot;
break;
case 'Isometric':
// fix Camera rotation
Rot.Pitch = (-55.0f *DegToRad) * RadToUnrRot;
Rot.Roll = (0 *DegToRad) * RadToUnrRot;
Rot.Yaw = (30.0f *DegToRad) * RadToUnrRot;
Loc.X = PCOwner.Pawn.Location.X - 64;
Loc.Y = PCOwner.Pawn.Location.Y - 64;
Loc.Z = PCOwner.Pawn.Location.Z + 156;
Pos = Loc - Vector(Rot) * FreeCamDistance;
OutVT.POV.Location = Pos;
OutVT.POV.Rotation = Rot;
break;
case 'FirstPerson' : // Simple first person, view through viewtarget's 'eyes'
default : OutVT.Target.GetActorEyesViewPoint(OutVT.POV.Location, OutVT.POV.Rotation);
break;
}
}
}
if( !bDoNotApplyModifiers )
{
// Apply camera modifiers at the end (view shakes for example)
ApplyCameraModifiers(DeltaTime, OutVT.POV);
}
//`log( WorldInfo.TimeSeconds @ GetFuncName() @ OutVT.Target @ OutVT.POV.Location @ OutVT.POV.Rotation @ OutVT.POV.FOV );
}
Now add the following inside the DefaultProperties block :
DefaultProperties
{
DefaultFOV=90.f
}
This will set the default Field of view or how wide the camera see. When you change this, it’s akin to changing the camera lens on a photographer’s camera.
This function was copy/pasted from the Camera class. Since we extend from this class and we are not calling super.UpdateViewTarget, we are simply changing the entire behaviour of the function. Here we did not have any choices because there is no way for us to extend inside the switch( CameraStyle ) from the parent class. Lets examin what it does :
Camera Isometric rotation
// fix Camera rotation
Rot.Pitch = (-55.0f *DegToRad) * RadToUnrRot;
Rot.Roll = (0 *DegToRad) * RadToUnrRot;
Rot.Yaw = (30.0f *DegToRad) * RadToUnrRot;
Now here we fix the camera angles into a fixed angle that is more or less isometric. The reason we need the multiplications is because the Rotator type which contains Pitch,Yaw and Roll support an Integer for defining rotation. I found that weird at first but you get the hang of it rapidly.
Camera Offset
// fix Camera position offset from avatar.
Loc.X = PCOwner.Pawn.Location.X – 64;
Loc.Y = PCOwner.Pawn.Location.Y – 64;
Loc.Z = PCOwner.Pawn.Location.Z + 156;
This sets default camera start position from the pawn (player avatar).
//Set zooming.
Pos = Loc – Vector(Rot) * FreeCamDistance;
This will be used to control the camera zoom in/out with scroll wheel. What it does is to use the current camera rotation as direction vector and then multiply it by the FreeCamDistance. By default this value is 256.0f, you can look it up CTRL+SHIFT+F ( FreeCamDistance ) will search for all references to this variable.
Plug in the camera in the player controller
Again creating a new file without wiring it, will see no changes in the game perspective. To add the new camera system, add the following entry to the default properties of the IsometricGamePlayerController : CameraClass=class‘IsometricCamera’.
Build the solution and hit the play button in visual studio and you should have a suprise !
Troubleshooting
As you can see the camera has not changed perspective, we are still in first person mode. Why ? This is rather simple : Your default avatar (Pawn class) is by default requesting a first person perspective. What we will do is create our own pawn class to clear this problem.
Creating a new Pawn
First create a new unreal script and name it MyPawn. Change the class extends from Object to GamePawn. Copy the following function which will tell our pawn to use the Isometric Camera :
simulated function name GetDefaultCameraMode( PlayerController RequestedBy )
{
return ‘Isometric’;
}
To wire the new MyPawn class to the game, you will have to change the default properties of the GameInfo class. Your IsometricGameInfo class should now look like this :
class IsometricGameInfo extends GameInfo;
DefaultProperties
{
bDelayedStart=false
PlayerControllerClass=class‘IsometricGamePlayerController’
DefaultPawnClass=class‘MyPawn’
}
The variable bDelayedStart is very important here. The reason we set it to false is that in a normal Unreal tournament game, the player is set into waiting camera by default and the pawn will not be spawn until the game start event. Since we have not implemented such a scheme, we simply say : Do not delay us and spawn us immediately.
Compile and hit play, now you should have a pleasant surprise !
EDIT FROM FEEDBACKS (Jan 02, 2010) : If you read the comments you may see that some people had problems setting up the pawn visual asset, put these defaultproperties if the stock game does not work, for curious reasons for some it works, others do not see the default pawn from the extended class.
defaultproperties
{
Components.Remove(Sprite)
Begin Object Class=DynamicLightEnvironmentComponent Name=MyLightEnvironment
ModShadowFadeoutTime=0.25
MinTimeBetweenFullUpdates=0.2
AmbientGlow=(R=.01,G=.01,B=.01,A=1)
AmbientShadowColor=(R=0.15,G=0.15,B=0.15)
LightShadowMode=LightShadow_ModulateBetter
ShadowFilterQuality=SFQ_High
bSynthesizeSHLight=TRUE
End Object
Components.Add(MyLightEnvironment)
Begin Object Class=SkeletalMeshComponent Name=InitialSkeletalMesh
CastShadow=true
bCastDynamicShadow=true
bOwnerNoSee=false
LightEnvironment=MyLightEnvironment;
BlockRigidBody=true;
CollideActors=true;
BlockZeroExtent=true;
PhysicsAsset=PhysicsAsset'CH_AnimCorrupt.Mesh.SK_CH_Corrupt_Male_Physics'
AnimSets(0)=AnimSet'CH_AnimHuman.Anims.K_AnimHuman_AimOffset'
AnimSets(1)=AnimSet'CH_AnimHuman.Anims.K_AnimHuman_BaseMale'
AnimTreeTemplate=AnimTree'CH_AnimHuman_Tree.AT_CH_Human'
SkeletalMesh=SkeletalMesh'CH_LIAM_Cathode.Mesh.SK_CH_LIAM_Cathode'
End Object
Mesh=InitialSkeletalMesh;
Components.Add(InitialSkeletalMesh);
}
NOTE FOR ADVANCED USERS: If you are using UT classes for extending UTgame, you will have to override CalcCamera also, so the pawn does not override camera control. (this has been noted by users not following exactly the tutorial’s base classes…

Now that was easy ! With that newly created camera we can now set on to new heights and make a mouse cursor for moving the pawn around ! For the present mouse moves the rotation of the pawn and WASD translate the pawn relative to its rotation. We will tackle player input later, for now lets display a mouse cursor. While we are here, lets make this mouse cursor follow the ground and use a nice 3d mesh.
Download solution and source file for chapter 1.
Chapter 2 – Getting the mouse into the fray
hi,
Im getting compile error with MyPawn.uc and this is my code
”
class MyPawn extends GamePawn;
simulated function name GetDefaultCameraMode( PlayerController RequestedBy )
{
return ‘Isometric’;
}
”
the error im getting is bad or missing expression on ’return’
You are supposed to use Single quotes as the return of the functions asks for a string constant. Ask in the forum for further help on this subject, it is supposed to compile, if you have problem, download the source and check against them to see if you mistyped something.
cheers !
thanks for the tutorial. do you have any idea why my robot player doesn’t show up? everything else works fine.
do not see my pawn when i follow these instructions.
when I copy the default properties from the MyPawn class of the downloaded solution everything works.
Maybe you should mention to copy these default properties or am I misin something different?
I used default properties and everything worked. If you do not have a pawn visible, be sure to have the “bDelayedStart=false” property in the controller. Be sure to have overdid the GetDefaultCameraMode function to get isometric. If something does’nt show up check again if you mistyped some of the above code. I may have missed something, if its the case tell me so I can modify the source accordingly.
First and foremost, thank you for the awesome tutorial. I’m still going through it, but so far, it’s been extremely helpful!
Secondly, I too did not see the pawn going through these steps. The problem was that there was no part in the tutorial that set up the “DefaultProperties” of the “MyPawn” class. Anyone having problems should check out “DefaultProperties” in MyPawn.uc (from the downloaded code), it sets up a light source and loads a mesh/skeleton.
I have added an Edit section with the code from the downloadable solution. Sorry for those that had problems with default setup, as the UDK is still labeled as BETA, maybe it his a problem some has and others dont.
Another problem is when we switch to firstperson.
by default our pawn, is visible, but if i switch view, and look down, i can see my pawn !
Having a problem compiling after adding the IsometricCamera.uc. Getting a bad command on bCamoverridePostProcess I have double checked my typing, and also used the version you have here. I have the Feb release of UDK, any Ideas?
Bevins : There was a code change in the February 2010 BETA camera.uc, so bCamoverridePostProcess went away and was replaced, I modified the source on the page and in all final chapter’s source for download. The code is now officially tested against FEB BETA release.
Thanks for the tutorial but I downloaded the source and copy/pasted it into UTGame/Classes with no modifications. I am getting the error
IsometricCamera.uc(50) : Error, ‘CamOverridePostProcessAlpha’ : Bad command or expression.
Be sure to use the latest february BETA release for UDK, there was a fix in the camera class camera.uc. The code is no longuer compatible with january and december 09 releases.
Thanks for the tutorial~
I am so confused,why the UDK just told me “Script Outdated need to be rebuild”over and over again?
And When I compiled IsometricCamera.uc ,it says:
Erorr,Bad Class Definition ”/’Camera’/2222/2222
Plz help with me~
(my UDK version:Ferbruary Beta 2010)
sometimes you need to use the udk unreal frontend. The nfringe compilation does some strange stuff sometimes.
I also get the problem about :
“IsometricCamera.uc(50) : Error, ‘CamOverridePostProcessAlpha’ : Bad command or expression.”
My UDK version is Ferbruary 2010 BETA.
How Can I Solve This Stuff ?
This is because there was a change in the february’s code, this is supposed to be fixed in the tutorial, or maybe I missed a spot. Download the source and compare the camera class, it should be pretty obvious
Sorry bother you…, but the camera it’s not working with March update (everithing compiles just fine).
Can use break point to debug the code?
Henrique : I installed the march SDK today and verified that the last chapter on bot navigation worked. Everything works like in feb version. Can you explain what is not working ?
Justin : If you use nFringe yes you can debug and break. Although I find that debug support is rather random sometimes.
Hey there,
Thanks for this tutorial, I went and did it the “hard way” though, extending UTGame, UTPawn and UTPlayerController
I had to do alot more than just override CalcCamera though.
After a day or two of frustration I got to this:
http://i65.photobucket.com/albums/h208/InfernoNL/yayfinally.jpg
Obviously not bug proof but it’s a start!
I’m wondering if you could further describe how to get this succesfully working?
Would you be willing to take a look at my code as well, maybe it can be put up here as well, for those wanting to go the more “advanced” way and not directly follow the tutorial.
send it to me via roychr to gmail dot com ill take a look at it and maybe expand a small tutorial on how to hook everything in UTGame.
Thanks for the tutorial, Ive gotten some of the basics of work with UDK reading this. However like Henrique I am not able to get this to work with the April build. Just to make sure I didn’t mistype something I downloaded your chapter 1 source and after changing the directory pathing information in the solution file I achieved the same result as my own code did. It just seems to be stuff in the free floating camera mode. Regardless Thanks for the the efforts, hopefully you can assist me as I’d really like to move forward in your tutorial!
I’m also not able to get it to work with the April 2010 beta release.
None of the “Log(“”); functions output anything to the console and once I put in the final piece of code and try to debug, I get a UDK.exe has stopped working error.
Last few lines of the console are
ScriptLog: Couldn’t spawn player controller of class None
Warning: Login failed: Engine.GameMessage.FailedSpawnMessage
Critical: appError called: Could not spawn player
Critical: Windows GetLastError: The system cannot find the file specified. (2)
You forgot to say that we need to add
DefaultProperties
{
CameraClass=class’IsometricCamera’
}
in IsometricGamePlayerController.uc
If you are having problems with the pawn floating in the air above the ground making shadows look funny, add
Begin Object Name=CollisionCylinder
CollisionRadius=+0021.000000
CollisionHeight=+0044.000000
End Object
CylinderComponent=CollisionCylinder
To MyPawn.uc defaultproperties
Hi guys, I’m new to UDK and UScript but have programmed for 6 years in languages like Python and C++, I haven’t been using C++ in quite a while though and it’s really tricky to get used to this language but I’m sure I can do it, anyway, I was looking for some help, I did this tutorial and everything works fine except when I try to zoom in with the mouse wheel it wont work, I am making a third person hack and slash game and I need to have the camera closer to the player, either variable zoom or fixed but definitely closer. Thanks for the help, I really appreciate it.
Ok, Got everything working up to this point except camera zooming.
Isnt it sposed to zoom in/out when mousewheel scrolling?
Ok, One more thing, I moved the camera around (very fricking cool) and noticed the player model seems to be a tiny bit off the ground still. How can I make him fall down onto it fully? really enjoying these tutorials btw.thanks
Hi, Everything compiled and worked fine but I am still in first person view. why can’t i get into isometric view?
@KlaarX
Thanks for this! Finally got my camera to work because of you <3
Hey, thanks for this tutorial. Really cool. I was also getting an error from the return ‘Isometric’ line in MyPawn. I downloaded the source and saw there were some extra lines added to the top of IsometricCamera.uc:
simulated event PostBeginPlay()
{
super.PostBeginPlay();
`Log(“Custom Camera up”);
}
After that it worked.
@DuckSauce
is your code or the information on how to this this up yet? im about to try it myself but im not a coded so im not sure where to start.