MAIN TUTORIAL
Hey there, I thought I'd post a tutorial on creating a third person game, the scripting involved and such. I know I would've liked something like this when I started scripting so hopefully it'll be useful to you! Please feel free to comment/critique/tear this apart below.
So first off, this tutorial is assuming that you're a beginner who wants to create a third person game independent of UT with your own custom scripts, so I'll briefly go over a little bit of everything: setting up a new game, scripting, and other stuff like that. If you already know something, just skip over it.
Setting up a new game:
If you don't fancy these names, they're just to help you remember what they do and you can change them to whatever you like, it's the stuff inside that counts.
Scripting:
YourGameInfo.uc is the script that basically tells the UDK the basics about your game: what Player Controller to use, what pawn to use etc. Open up YourGameInfo.uc and insert the following code:
That's it for the Game Info script. Next we'll create the pawn. Unfortunately, this tutorial isn't entirely free of UT assets, as we'll be using a character mesh and animset from UT for lack of anything else. You can easily replace these with your own, though, if you get around to creating your own character and animations. The pawn is basically your character. It sets what your character looks like, how it collides with objects, how it's lit, and how it animates.
Go ahead and paste the following code into YourGamePawn.uc
Most of these various values are pretty self explanatory, and you can either Google them, post here, or fiddle about with them if you can't figure out what they do.
Now we'll continue to the custom Player Controller. (Getting into the tasty stuff!) I've commented the code below to provide an explanation of everything that's going on.
Now that we have the Player Controller worked out, we can move on to what most people are here for: the camera.
This camera script incorporates zoom interpolation (smoothing) as well as a third person orbiting viewpoint. I'll lay this section out in three parts (each section should follow right after each other in the YouGameCamera.uc script.)
First, we need to initialize the class instance and declare our variables:
A couple of things here. First of all, I've declared a variable outside of the function here in order to keep it static so that it doesn't re initialize each program loop. This just means my value will only change when I specifically tell it to. This sort of variable needs to be declared with the syntax, var variable_type variable_name; Second, I've set my FreeCamDistance to a default value so it doesn't start at some random value it grabbed out of memory.
After this, we'll set up our view target and various settings to let our pawn override the camera style if need be.
This is just pretty much taken from the camera.uc script, so there are a couple of things in there that are probably a bit unnecessary for what we're doing, but I've left them in there anyway.
Next, we'll implement our actual camera styles. We're using a switch-case method here. Basically, the compiler enters the code where it finds a match to the CameraStyle, and exits if it hits a "break." Remember, our default state is ThirdPerson.
Now that our scripting is finished, all that's left is to tell UDK to use our custom game type.
Note: Please back up your config files before editing them. You'll probably be sorry if you don't.
You'll need to go in to UDKGame\config and edit DefaultEngine.ini, and DefaultGameUDK.ini (make sure to turn of read-only on these files. In DefaultEngine.ini you'll need to edit:
In DefaultGameUDK.ini you'll need to edit:
Now for a couple of notes: First off, please note that this ini editing is quite basic and does not change any behavior related to how UDK builds packages, or includes packages when you "make" the game from the front end. For more advanced ini editing please check out tutorials such as The Ball for more information. Second, for your custom maps and content you'll need to create a folder "YourGame" under UDKGame\Content.
Now you're almost all finished. The last step is to open the UDK Launcher and click "make." Voila, your game should be playable in editor and from the launcher now!
SHOULDER CAMERA TUTORIAL EXTENSION
Warning: Over-the-shoulder camera section may contain mathematics
Alright, to get an over-the-shoulder camera working, we need to make a few changes to the above scripts. YourGameInfo and YourGamePawn both stay the same, so we'll be concentrating the changes in the player controller and especially the camera script.
Step one: Custom keybinding
First, we need to bind a key to switch camera views. For this, I use the left shift key. I have it activate the camera on a press, return to third person on release. Go into UDKGame\Config, and add the following to UDKInput.ini:
This tells the UDK that we want left shift to call a command (which we'll define in our player controller script) called ShoulderCam when the button is pressed, and ReturnCam when it is released.
Step two: PlayerController
We're going to make the following edits to YourGamePlayerController.uc:
First we need to declare an additional variable. This should go directly under the class declaration.
This variable will store our previous camera distance so that when we switch back to the normal camera, we'll be at our original setting.
The next lines of code should be tacked directly on the end of the player controller script:
That's all we need in YourGamePlayerController. Now we move on to the fun part: Camera implementation.
Step three: Camera Scripting
There are numerous small edits to make in YourGameCamera, so I'll post a completed script at the end.
Declaring variables
We're going to need 6 new static variables in our camera script. These should be declared as follows beneath our declaration of Dist
Under defaultproperties make the following addition:
Now we move down to our switch/case structure. We're going to need to add another case for our shoulder camera. Add the following under "case 'FreeCam' :"
Now, with the addition of those new variables, we're going to have to declare what they should be for each of our cameras. Modify the if statement "if (CameraStyle == 'ThirdPerson')" to read:
No we add an if statement for our new camera style under the prior if statement:
Now we need to add in the effect of the z offset on our camera location. Add the following line of code after "Loc += FreeCamOffset >> Rot;"
Now we'll make sure nothing "jumps," and everything is silky smooth. We'll add three more lerps--one for each of our variables that get changed with the camera style. Under the lines:
Enter the additional lines:
Now, this next part is where our math comes in. We can't just tell the UDK to offset our camera on the x and y axes, since then, when our character turned around, our offsets would still be in the same direction, and it would be the exact opposite of what we want for that rotation.
The problem lies in the fact that we're working in world coordinates, so any offset we make will be in global, rather than local, character coordinates.
We solve this by mapping our character offset from character coordinates to world coordinates using a little trigonometry.
Add the following two lines of code under "Pos = Loc - Vector(Rot) * Dist;" (this should be directly under our lerp code)
Those two lines tell the UDK to offset the camera in a direction off of the pawn rather than in a global direction. The numbers after Rot.Yaw convert from UnrealUnits to radians. If you're familiar with trigonometry and vectors, you probably won't find this too complicated. If you're not familiar with that stuff, don't worry about it, just use it as is and learn it later.
That takes care of all the changes we need in the YourGameCamera.uc Here's the completed script to give you an idea of what it looks like all put together:
Now you're finished. Just compile your script from the front end or your favorite method, and voila, (sort of) instant shoulder cam!
Good luck, cheers, and thanks!
JT
Hey there, I thought I'd post a tutorial on creating a third person game, the scripting involved and such. I know I would've liked something like this when I started scripting so hopefully it'll be useful to you! Please feel free to comment/critique/tear this apart below.
So first off, this tutorial is assuming that you're a beginner who wants to create a third person game independent of UT with your own custom scripts, so I'll briefly go over a little bit of everything: setting up a new game, scripting, and other stuff like that. If you already know something, just skip over it.
Setting up a new game:
- Create a folder "YourGame" (or whatever you'd like to call your game) inside ..[UDK-yyyy-mm]/development/src (yyyy-mm is just the date of the release you have).
- Inside of that, create a folder called "Classes."
- Inside of Classes, create four .uc files: YourGameInfo.uc, YourGamePawn.uc, YourGameCamera.uc, and YourGamePlayerController.uc.
If you don't fancy these names, they're just to help you remember what they do and you can change them to whatever you like, it's the stuff inside that counts.
Scripting:
YourGameInfo.uc is the script that basically tells the UDK the basics about your game: what Player Controller to use, what pawn to use etc. Open up YourGameInfo.uc and insert the following code:
Code:
class YourGameInfo extends GameInfo; //This line tells UDK that you want to inherit all of the functionality of GameInfo.uc, and add your own. The name after "class" must match the file name. DefaultProperties //Self explanatory { bDelayedStart=false PlayerControllerClass = class 'YourGame.YourGamePlayerController' //Setting the Player Controller to your custom script DefaultPawnClass = class 'YourGame.YourGamePawn' //Setting the Pawn to your custom script }
Go ahead and paste the following code into YourGamePawn.uc
Code:
class YourGamePawn extends GamePawn; //Again, naming conventions apply here. Your script is extending the UDK script DefaultProperties { Components.Remove(Sprite) //Setting up the light environment 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) //Setting up the mesh and animset components Begin Object Class=SkeletalMeshComponent Name=InitialSkeletalMesh CastShadow=true bCastDynamicShadow=true bOwnerNoSee=false LightEnvironment=MyLightEnvironment; BlockRigidBody=true; CollideActors=true; BlockZeroExtent=true; //What to change if you'd like to use your own meshes and animations 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 //Setting up a proper collision cylinder Mesh=InitialSkeletalMesh; Components.Add(InitialSkeletalMesh); CollisionType=COLLIDE_BlockAll Begin Object Name=CollisionCylinder CollisionRadius=+0023.000000 CollisionHeight=+0050.000000 End Object CylinderComponent=CollisionCylinder } //This lets the pawn tell the PlayerController what Camera Style to set the camera in initially (more on this later). simulated function name GetDefaultCameraMode(PlayerController RequestedBy) { return 'ThirdPerson'; }
Now we'll continue to the custom Player Controller. (Getting into the tasty stuff!) I've commented the code below to provide an explanation of everything that's going on.
Code:
class YourGamePlayerController extends GamePlayerController; DefaultProperties { CameraClass = class 'YourGameCamera' //Telling the player controller to use your custom camera script DefaultFOV=90.f //Telling the player controller what the default field of view (FOV) should be } simulated event PostBeginPlay() //This event is triggered when play begins { super.PostBeginPlay(); `Log("I am alive!"); //This sends the message "I am alive!" to thelog (to see the log, you need to run UDK with the -log switch) } //Functions for zooming in and out exec function NextWeapon() /*The "exec" command tells UDK to ignore what the defined function of NextWeapon is, and use our function declaration here. We'll go over how to change the function of keys later (if, for instance, you didn't want you use the scroll wheel, but page up and down for zooming instead.)*/ { if (PlayerCamera.FreeCamDistance < 512) //Checks that the the value FreeCamDistance, which tells the camera how far to offset from the view target, isn't further than we want the camera to go. Change this to your liking. { `Log("MouseScrollDown"); //Another log message to tell us what's happening in the code PlayerCamera.FreeCamDistance += 64*(PlayerCamera.FreeCamDistance/256); /*This portion increases the camera distance. By taking a base zoom increment (64) and multiplying it by the current distance (d) over 256, we decrease the zoom increment for when the camera is close, (d < 256), and increase it for when it's far away (d > 256). Just a little feature to make the zoom feel better. You can tweak the values or take out the scaling altogether and just use the base zoom increment if you like */ } } exec function PrevWeapon() { if (PlayerCamera.FreeCamDistance > 64) //Checking if the distance is at our minimum distance { `Log("MouseScrollUp"); PlayerCamera.FreeCamDistance -= 64*(PlayerCamera.FreeCamDistance/256); //Once again scaling the zoom for distance } }
This camera script incorporates zoom interpolation (smoothing) as well as a third person orbiting viewpoint. I'll lay this section out in three parts (each section should follow right after each other in the YouGameCamera.uc script.)
First, we need to initialize the class instance and declare our variables:
Code:
class YourGameCamera extends Camera; // initializing static variables var float Dist; DefaultProperties { FreeCamDistance = 256.f // } function UpdateViewTarget(out TViewTarget OutVT, float DeltaTime) { //Declaring local variables local vector Loc, Pos, HitLocation, HitNormal; local rotator Rot; local Actor HitActor; local CameraActor CamActor; local bool bDoNotApplyModifiers; local TPOV OrigPOV;
After this, we'll set up our view target and various settings to let our pawn override the camera style if need be.
Code:
// 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;
Next, we'll implement our actual camera styles. We're using a switch-case method here. Basically, the compiler enters the code where it finds a match to the CameraStyle, and exits if it hits a "break." Remember, our default state is ThirdPerson.
Code:
switch(CameraStyle) { case 'Fixed' : // No update, keeps previous view OutVT.POV = OrigPOV; break; case 'ThirdPerson' : //Enters here as long as CameraStyle is still set to ThirdPerson case 'FreeCam' : Loc = OutVT.Target.Location; // Setting the camera location and rotation to the viewtarget's Rot = OutVT.Target.Rotation; if (CameraStyle == 'ThirdPerson') { Rot = PCOwner.Rotation; //setting the rotation of the camera to the rotation of the pawn } //OutVT.Target.GetActorEyesViewPoint(Loc, Rot); if(CameraStyle == 'FreeCam') { Rot = PCOwner.Rotation; } Loc += FreeCamOffset >> Rot; //Linear interpolation algorithm. This is the "smoothing," so the camera doesn't jump between zoom levels if (Dist != FreeCamDistance) { Dist = Lerp(Dist,FreeCamDistance,0.15); //Increment Dist towards FreeCamDistance, which is where you want your camera to be. Increments a percentage of the distance between them according to the third term, in this case, 0.15 or 15% } Pos = Loc - Vector(Rot) * Dist; /*Instead of using FreeCamDistance here, which would cause the camera to jump by the entire increment, we use Dist, which increments in small steps to the desired value of FreeCamDistance using the Lerp function above*/ // @fixme, respect BlockingVolume.bBlockCamera=false //This determines if the camera will pass through a mesh by tracing a path to the view target. HitActor = Trace(HitLocation, HitNormal, Pos, Loc, FALSE, vect(12,12,12)); //This is where the location and rotation of the camera are actually set OutVT.POV.Location = (HitActor == None) ? Pos : HitLocation; OutVT.POV.Rotation = Rot; break; //This is where our code leaves the switch-case statement, preventing it from executing the commands intended for the FirstPerson case. 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 ); }
Note: Please back up your config files before editing them. You'll probably be sorry if you don't.
You'll need to go in to UDKGame\config and edit DefaultEngine.ini, and DefaultGameUDK.ini (make sure to turn of read-only on these files. In DefaultEngine.ini you'll need to edit:
Code:
Lines 6, 7 and 8, Map=UTFrontEnd.udk LocalMap=UTFrontEnd.udk TransitionMap=EnvyEntry.udk Change the value of the first two entries to the map you'd like to start on, and if you like, change the third entry to your own custom loading screen map. Add: +EditPackages=YourGame under [UnrealEd.EditorEngine] on line 15
Code:
Lines 5, 6 and 7, DefaultGame=UTGame.UTDeathmatch DefaultServerGame=UTGame.UTDeathmatch PlayerControllerClassName=UTGame.UTPlayerController Change the first two entries to YourGame.YourGameInfo, and the third entry to YourGame.YourGamePlayerController.
Now you're almost all finished. The last step is to open the UDK Launcher and click "make." Voila, your game should be playable in editor and from the launcher now!
SHOULDER CAMERA TUTORIAL EXTENSION
Warning: Over-the-shoulder camera section may contain mathematics
Alright, to get an over-the-shoulder camera working, we need to make a few changes to the above scripts. YourGameInfo and YourGamePawn both stay the same, so we'll be concentrating the changes in the player controller and especially the camera script.
Step one: Custom keybinding
First, we need to bind a key to switch camera views. For this, I use the left shift key. I have it activate the camera on a press, return to third person on release. Go into UDKGame\Config, and add the following to UDKInput.ini:
Code:
Line 29 add: Bindings=(Name="LeftShift",Command="ShoulderCam | OnRelease ReturnCam")
Step two: PlayerController
We're going to make the following edits to YourGamePlayerController.uc:
First we need to declare an additional variable. This should go directly under the class declaration.
Code:
var float PreDist;
The next lines of code should be tacked directly on the end of the player controller script:
Code:
exec function ShoulderCam() // Declaring our ShoulderCam function that we bound to { `Log("Shoulder Camera"); // Yet another log... PreDist = PlayerCamera.FreeCamDistance; //Storing our previous camera distance... YourGameCamera(PlayerCamera).CameraStyle = 'ShoulderCam'; //Type casting our camera script to access the variable CameraStyle } exec function ReturnCam() //This is called on release of left shift { `Log("Main Camera"); PlayerCamera.FreeCamDistance = PreDist; // Restoring the previous camera distance YourGameCamera(PlayerCamera).CameraStyle = 'ThirdPerson'; // Restoring the previous camera style }
Step three: Camera Scripting
There are numerous small edits to make in YourGameCamera, so I'll post a completed script at the end.
Declaring variables
We're going to need 6 new static variables in our camera script. These should be declared as follows beneath our declaration of Dist
Code:
var float TargetFOV; //Lerp target for field of view var float Z; //Current Z axis offset var float TargetZ; //Lerp target for Z offset var float Offset; //Current amount of XY offset var float TargetOffset; //Lerp target for XY offset var float pival; // pi
Code:
pival = 3.14159; //The aprox. value of pi
Code:
case 'ShoulderCam' : //Our shoulder camera case
Code:
if (CameraStyle == 'ThirdPerson') { Rot = PCOwner.Rotation; //setting the rotation of the camera to the rotation of the pawn TargetZ = 0; //We don't want any z axis offset TargetFOV = 90; //We want to have our field of view set to the default 90 degrees TargetOffset = 0; // No xy offset either }
Code:
if (CameraStyle == 'ShoulderCam') { Rot = PCOwner.Rotation; //We still want to use the rotation of the character as our camera rotation FreeCamDistance = 64; //We'll go in for a close up TargetFOV = 60.f; //And we'll have a nice zoom effect for aiming TargetZ = 32; //We'll pop the camera up above the head... TargetOffset = 32; //And pop it out over the shoulder }
Code:
Loc.Z += Z; // Setting the Z coordinate offset for shoulder view
Code:
if (Dist != FreeCamDistance) { Dist = Lerp(Dist,FreeCamDistance,0.15); }
Code:
if (Z != TargetZ) //Lerping z offset { Z = Lerp(Z,TargetZ,0.1); } if (DefaultFOV != TargetFOV) //Lerping FOV { DefaultFOV = Lerp(DefaultFOV,TargetFOV,0.1); } if (Offset != TargetOffset) //Lerping xy offset { Offset = Lerp(Offset,TargetOffset,0.1); }
The problem lies in the fact that we're working in world coordinates, so any offset we make will be in global, rather than local, character coordinates.
We solve this by mapping our character offset from character coordinates to world coordinates using a little trigonometry.
Add the following two lines of code under "Pos = Loc - Vector(Rot) * Dist;" (this should be directly under our lerp code)
Code:
Pos.X += Offset*sin(-Rot.Yaw*pival*2/65536); Pos.Y += Offset*cos(Rot.Yaw*pival*2/65536);
That takes care of all the changes we need in the YourGameCamera.uc Here's the completed script to give you an idea of what it looks like all put together:
Code:
class YourGameCamera extends Camera; // initializing static variables var float Dist; var float TargetFOV; var float TargetZ; var float Z; var float TargetOffset; var float Offset; var float pival; DefaultProperties { FreeCamDistance = 256.f pival = 3.14159; } function UpdateViewTarget(out TViewTarget OutVT, float DeltaTime) { //Declaring local variables 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' : // No update, keeps previous view OutVT.POV = OrigPOV; break; case 'ThirdPerson' : //Enters here as long as CameraStyle is still set to ThirdPerson case 'FreeCam' : case 'ShoulderCam' : // Over the shoulder view Loc = OutVT.Target.Location; // Setting the camera location and rotation to the viewtarget's Rot = OutVT.Target.Rotation; if (CameraStyle == 'ThirdPerson') { Rot = PCOwner.Rotation; //setting the rotation of the camera to the rotation of the pawn TargetZ = 0; TargetFOV = 90; TargetOffset = 0; } if (CameraStyle == 'ShoulderCam') { Rot = PCOwner.Rotation; FreeCamDistance = 64; TargetFOV = 60.f; TargetZ = 32; TargetOffset = 32; } //OutVT.Target.GetActorEyesViewPoint(Loc, Rot); if(CameraStyle == 'FreeCam') { Rot = PCOwner.Rotation; } Loc += FreeCamOffset >> Rot; Loc.Z += Z; // Setting the Z coordinate offset for shoulder view //Linear interpolation algorithm. This is the "smoothing," so the camera doesn't jump between zoom levels if (Dist != FreeCamDistance) { Dist = Lerp(Dist,FreeCamDistance,0.15); //Increment Dist towards FreeCamDistance, which is where you want your camera to be. Increments a percentage of the distance between them according to the third term, in this case, 0.15 or 15% } if (Z != TargetZ) { Z = Lerp(Z,TargetZ,0.1); } if (DefaultFOV != TargetFOV) { DefaultFOV = Lerp(DefaultFOV,TargetFOV,0.1); } if (Offset != TargetOffset) { Offset = Lerp(Offset,TargetOffset,0.1); } Pos = Loc - Vector(Rot) * Dist; /*Instead of using FreeCamDistance here, which would cause the camera to jump by the entire increment, we use Dist, which increments in small steps to the desired value of FreeCamDistance using the Lerp function above*/ // Setting the XY camera offset for shoulder view Pos.X += Offset*sin(-Rot.Yaw*pival*2/65536); Pos.Y += Offset*cos(Rot.Yaw*pival*2/65536); // @fixme, respect BlockingVolume.bBlockCamera=false //This determines if the camera will pass through a mesh by tracing a path to the view target. HitActor = Trace(HitLocation, HitNormal, Pos, Loc, FALSE, vect(12,12,12)); //This is where the location and rotation of the camera are actually set OutVT.POV.Location = (HitActor == None) ? Pos : HitLocation; OutVT.POV.Rotation = Rot; break; //This is where our code leaves the switch-case statement, preventing it from executing the commands intended for the FirstPerson case. 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 ); }
Good luck, cheers, and thanks!
JT
Comment