View Full Version : [Tutorial] 3rd Person Follow Cam
DWishR
05-27-2010, 02:34 AM
Warning: The code linked to here is not currently functioning. I'll be fixing and updating it this week. Please be patient.
I posted a tutorial on my site for a 3rd person follow camera. Thought I'd link it here since this is the place for it.
Follow Camera Tutorial (http://www.DWishR.com/2010/follow-cam)
S ha d
05-27-2010, 05:47 AM
Hey ! great tut man !
Cheers ! :)
Dying
05-31-2010, 02:51 AM
very nice tutorial, it helped me understand the logic behind a following camera and will come in handy very soon on a new project, but when implemented this seems to severely mess up the players controls..
DWishR
05-31-2010, 05:00 PM
very nice tutorial, it helped me understand the logic behind a following camera and will come in handy very soon on a new project, but when implemented this seems to severely mess up the players controls..
If the custom input class isn't set up correctly then the player controls kind of like a tank (forward moves in the direction of the characters facing, moving the mouse rotates the character and not the camera).
Make sure you've set up your custom player controller class correctly and that the
InputClass=class'MG_Input' line exists in the controller's default properties (change MG_Input to whatever you named your input class). You can throw a log message into the front of the PlayerInput event to make sure it's working.
mesavage
06-01-2010, 02:11 AM
Only skimmed over the code, but I have to say, very nice layout in your tutorial and your explanation of why and how you implemented your methods will give many a head start into creating their own classes.
Cheerz
DWishR
06-19-2010, 12:06 AM
@mesavage Thanks man. Glad the explanations are valued since it's always much easier to simply post completed code.
I have found that this code does not play nice when extending from UTGame. I know you recomend not to but I want to extend UTGame because I am not a great programmer and dont want to add some of the things already implemented in UTGame.
Do you know what I would need to do to get this working with UTGame?
DWishR
09-07-2010, 05:34 AM
Has anyone tested this against the latest version of UDK? I got a comment on my site saying that it's broken. Unfortunately, I won't be able to test it for a couple weeks as I'm on vacation. Hoping I can get some confirmation here and maybe a quick fix from someone else.
Scatter
09-09-2010, 03:12 PM
i'm using the august build and i can't get it to work. have tidied up all the class extensions to match the latest build, but the compiler spits at joy.X in the input.uc. i'll post my code for each class in a sec (they're essentially clean as i'm trying to setup my camera first).
Scatter
09-09-2010, 03:16 PM
class AEMGame extends GameInfo;
DefaultProperties
{
PlayerControllerClass=Class'AEMPlayerController'
DefaultPawnClass=Class'AEMPawn'
}
class AEMPlayerController extends GamePlayerController;
DefaultProperties
{
// Camera Controller
InputClass=class'AEMInput'
CameraClass=class'AEMCamera'
}
class AEMPawn extends GamePawn;
DefaultProperties
{
}
class AEMCustomPlayer extends Player;
simulated function name GetDefaultCameraMode( AEMPlayerController RequestedBy )
{
// Can optionally query the playercontroller or gamestate to decide between different camera modes
return 'FollowCam';
}
DefaultProperties
{
}
class AEMInput extends PlayerInput within AEMPlayerController;
var(AEMInput) float turnRate;
var bool bMoveLocked;
var float HotSpotRadius;
var Rotator currCamRot;
var Vector oldJoy;
event PlayerInput( float DeltaTime )
{
local Vector move, facing, joy;
local float moveDeltaAbs;
local Rotator rot, camRot, playerRot;
super.PlayerInput(DeltaTime);
move.X = aStrafe;
move.Y = aForward;
move.Z = 0.f;
facing.X = aForward;
facing.Y = aStrafe;
facing.Z = 0.f;
joy.X = RawJoyRight;
joy.Y = RawJoyUp;
moveDeltaAbs = Abs(joy.Y - oldJoy.Y) + Abs(joy.X - oldJoy.X);
if(!bMoveLocked)
{
if( ( move.X != 0.f || move.Y != 0.f ) && moveDeltaAbs < HotSpotRadius )
bMoveLocked = true;
currCamRot = AEMCamera(PlayerCamera).CurrentCamRotation;
oldJoy = joy;
}
else if(aTurn != 0.f || moveDeltaAbs > HotSpotRadius)
{
bMoveLocked = false;
oldJoy = joy;
}
playerRot.Yaw = Rotation.Yaw;
camRot.Yaw = currCamRot.Yaw;
move = TransformVectorByRotation(camRot, move, true);
move = TransformVectorByRotation(playerRot, move, false);
aForward = move.Y;
aStrafe = move.X;
facing = TransformVectorByRotation(camRot, facing, false);
if( move.X != 0.f || move.Y != 0.f )
{
rot = RInterpTo( Rotation, Rotator( Normal(facing) ), DeltaTime, turnRate );
SetRotation(rot);
}
else bMoveLocked = false;
AEMCamera(PlayerCamera).desiredTurn = aTurn;
aTurn = 0.f;
}
DefaultProperties
{
bMoveLocked = false
turnRate = 6.f
HotSpotRadius = 0.25f
//this keeps unreal from messing with rotations
blockTurnUntilRelease = true
}
class AEMCamera extends GamePlayerCamera;
var Vector CurrentCamLocation;
var Rotator CurrentCamRotation;
var float DesiredTurn;
var(FollowCam) float FollowCamDist;
var(FollowCam) Vector FollowsZoffset;
var(FollowCam) Vector CamLookOffset;
var(FollowCam) float TurnrateRatio;
function UpdateViewTarget(out TViewTarget OutVT, float dt)
{
local CameraActor CamActor;
local Vector HitLocation, HitNormal;
local Actor HitActor;
// Default FOV on viewtarget
OutVT.POV.FOV = DefaultFOV;
// viewing through a camera actor
CamActor = CameraActor(OutVT.Target);
if( CamActor != none )
{
// in LD cinematic
CamActor.GetCameraView(dt, OutVT.POV);
// grab aspect ratio from the cameraactor
bConstrainAspectRatio = bConstrainAspectRatio || CamActor.bConstrainAspectRatio;
OutVT.AspectRatio = CamActor.AspectRatio;
// CameraActor wants to override post process
bCamOverridePostProcess = CamActor.bCamOverridePostProcess;
CamPostProcessSettings = CamActor.CamOverridePostProcess;
// set my variables to account for current targeting
CurrentCamLocation = OutVT.POV.Location;
CurrentCamRotation = OutVT.POV.Rotation;
}
// give pawn viewtarget a chance to dictate camera position
else if( Pawn(OutVT.Target) != none && Pawn(OutVT.Target).CalcCamera(dt, OutVT.POV.Location, OutVT.POV.Rotation, OutVT.POV.FOV) )
{
`log("NOTICE ME: No idea when this happens!");
CurrentCamRotation = OutVT.POV.Rotation;
CurrentCamLocation = OutVT.POV.Location;
}
// the custom camera
else
{
switch( CameraStyle )
{
case 'FollowCam':
RotationUpdate(OutVT, dt);
FollowCamTarget(OutVT, dt);
break;
}
HitActor = Trace(HitLocation, HitNormal, CurrentCamLocation, OutVT.Target.Location, false, vect(12,12,12));
if (HitActor != none)
CurrentCamLocation = HitLocation;
OutVT.POV.Location = CurrentCamLocation;
OutVT.POV.Rotation = CurrentCamRotation;
}
// lets LDs do shakes etc
ApplyCameraModifiers(dt, OutVT.POV);
}
function FollowCamTarget(TViewTarget OutVT, float dt)
{
local Vector toTarget;
local Vector CamNoZ;
local Vector TargetNoZ;
CamNoZ = CurrentCamLocation;
CamNoZ.Z = 0.f;
TargetNoZ = OutVT.Target.Location;
TargetNoZ.Z = 0.f;
toTarget = TargetNoZ - CamNoZ;
toTarget = Normal(toTarget);
CurrentCamLocation = toTarget * -FollowCamDist + OutVT.Target.Location + FollowsZoffset;
toTarget = OutVT.Target.Location - CurrentCamLocation;
CurrentCamRotation = rotator(toTarget + CamLookOffset );
}
function RotationUpdate(TViewTarget OutVT, float dt)
{
local Vector fromTarget;
local Vector desiredDir;
local float currAngle;
local float desiredAngle;
local Vector CamNoZ;
local Vector TargetNoZ;
CamNoZ = CurrentCamLocation;
CamNoZ.Z = 0.f;
TargetNoZ = OutVT.Target.Location;
TargetNoZ.Z = 0.f;
fromTarget = CamNoZ - TargetNoZ;
if(fromTarget.X != 0) currAngle = Atan(fromTarget.Y / fromTarget.X);
else currAngle = Pi/2;
if(fromTarget.X < 0) currAngle -= Pi;
desiredAngle = currAngle + DesiredTurn / TurnrateRatio;
desiredDir.Y = Sin(desiredAngle);
desiredDir.X = Cos(desiredAngle);
CurrentCamLocation = OutVT.Target.Location + (desiredDir*VSize(fromTarget));
}
DefaultProperties
{
FollowCamDist=416.f
DesiredTurn=0.f
TurnrateRatio=10240.f
FollowsZoffset=(X=0, Y=0.f, Z=160.f)
CamLookOffset=(X=0. Y=0, Z=100)
DefaultFOV=70.f
}
Scatter
09-09-2010, 03:22 PM
currently the compiler reports bad expression errors for:
*camera.uc
bCamOverridePostProcess = CamActor.bCamOverridePostProcess;
*input.uc
joy.X = RawJoyRight;
LazySnake61
09-10-2010, 04:03 AM
what does 'transform vector by rotation' do?
Scatter
09-10-2010, 06:15 AM
ok, i've resolved the *input.uc issue with the joy variable (i missed part of a declaration, so it was my fault not the code).
but bcamoverridepostprocess is still spitting out a bad command or expression error in the compiler for *camera.uc
DWishR
09-10-2010, 06:32 AM
@Scatter I would just comment out that if block then, and let the game sort it out for now. I'll get on it next week when I'm back at home. Thanks so much for looking into that.
@LazySnake How's your 3d math? Short answer: rotates the vector according to the rotator (rotation matrix). For example, a vector pointing in the positive x direction rotated 90 positive degrees around the z-axis would then be pointing in the positive y direction.
Scatter
09-10-2010, 09:28 AM
yeah, i have. and it compiles just fine. meant to post that in here a couple of hours ago.
LazySnake61
09-10-2010, 11:02 AM
maths pretty bad but thanks.
Scatter
09-11-2010, 12:13 AM
ok, i'm finding that (in the august release at least) you really need to be extending the udk base classes rather than the top level classes to get much of anything going. it looks like the udk classes contain most of the initialisation, base declarations and references to required ini's.
the only alternative is to bring most of what's in the udk class files into the top level of your game classes, which is kinda redundant.
having a major problem with getdefaultcameramode function in this tutorial. if i place it in the pawn class - which is where the udn seems to indicate it belongs - i get a redefinition of function differs from original error from the compiler.
am going through all of my classes again now as i think my extension flow is all over the place and causing me unnecessary grief. basically all of the code i posted above is mostly unworkable bollocks due to this. :(
will post new (hopefully working :D ) code asap.
DWishR
09-11-2010, 05:15 PM
Yeah, after looking through the patch notes I realize that they've moved quite a bit around since I made this tutorial (there were no UDKBase or UDK[whatever] classes).
I really hope in creating the UDK prefix classes that they've made it easier to start from base FPS functionality and not just base engine functionality or full Unreal functionality. We'll see!
LazySnake61
09-11-2010, 05:32 PM
Its working but player mesh is not visible.
Powered by vBulletin® Version 4.2.0 Copyright © 2013 vBulletin Solutions, Inc. All rights reserved.