Chapter One – Creating the Isometric camera

February 18th, 2010 Leave a comment Go to comments

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 = LocVector(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…

 

chap1_iso_visuals

 

 

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

 

 

 

Update me when site is updated
Share and Enjoy:
  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • Slashdot
  • PDF
  • Twitter
  1. shaheen
    December 20th, 2009 at 23:28 | #1

    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’

  2. Hotdot
    December 25th, 2009 at 16:50 | #2

    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 !

  3. AnTeevY
    December 27th, 2009 at 12:48 | #3

    thanks for the tutorial. do you have any idea why my robot player doesn’t show up? everything else works fine.

  4. flo
    December 28th, 2009 at 15:14 | #4

    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?

  5. Hotdot
    December 29th, 2009 at 16:03 | #5

    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.

  6. Stuff
    January 2nd, 2010 at 17:49 | #6

    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.

    • Hotdot
      January 2nd, 2010 at 22:35 | #7

      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.

  7. MaximilianPS
    January 25th, 2010 at 06:32 | #8

    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 !

  8. Bevins
    February 17th, 2010 at 12:16 | #9

    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?

  9. Hotdot
    February 18th, 2010 at 01:57 | #10

    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.

  10. Tim
    February 24th, 2010 at 21:45 | #11

    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.

    • Hotdot
      February 26th, 2010 at 20:11 | #12

      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.

  11. Alex.Fang
    March 3rd, 2010 at 23:43 | #13

    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)

    • Hotdot
      March 9th, 2010 at 16:50 | #14

      sometimes you need to use the udk unreal frontend. The nfringe compilation does some strange stuff sometimes.

  12. Alex.Fang
    March 4th, 2010 at 09:01 | #15

    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 ?

    • Hotdot
      March 9th, 2010 at 16:51 | #16

      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 :)

  13. Henrique
    March 26th, 2010 at 17:30 | #17

    Sorry bother you…, but the camera it’s not working with March update (everithing compiles just fine).

  14. Justin
    March 28th, 2010 at 20:42 | #18

    Can use break point to debug the code?

  15. Hotdot
    March 29th, 2010 at 01:37 | #19

    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.

  16. March 29th, 2010 at 08:31 | #20

    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.

  17. Hotdot
    March 29th, 2010 at 16:29 | #21

    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.

  18. DragonXTC
    May 10th, 2010 at 00:06 | #22

    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!

  19. Master Shadow
    May 12th, 2010 at 14:54 | #23

    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)

  20. KlaarX
    June 2nd, 2010 at 08:37 | #24

    You forgot to say that we need to add

    DefaultProperties
    {
    CameraClass=class’IsometricCamera’
    }

    in IsometricGamePlayerController.uc

  21. Nipsting
    June 13th, 2010 at 20:16 | #25

    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

  22. tarboxb
    June 15th, 2010 at 06:22 | #26

    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.

  23. June 23rd, 2010 at 19:10 | #27

    Ok, Got everything working up to this point except camera zooming.

    Isnt it sposed to zoom in/out when mousewheel scrolling?

  24. June 23rd, 2010 at 19:32 | #28

    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

  25. wolfhammer
    July 13th, 2010 at 00:17 | #29

    Hi, Everything compiled and worked fine but I am still in first person view. why can’t i get into isometric view?

  26. crashonly
    July 29th, 2010 at 09:36 | #30

    @KlaarX
    Thanks for this! Finally got my camera to work because of you <3

  27. Rokit
    August 9th, 2010 at 19:39 | #31

    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.

  28. Dn2
    August 10th, 2010 at 18:49 | #32

    @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.

  1. No trackbacks yet.