A simple explanation.
I hope it will bring some clearance on the topic of rotation transitions.
Probably this is not the right place for this, so I apologize if that is the case.
How UDK works:
The underlying engine makes all the calculations necessary to output the proper graphics at decent frame rate.
Thus if you want to modify geometry or transformations at run time the best way to do it is to set the start and end points of a transformation and let the engine handle it.
This is in general how things are done in UDK and UnrealScript.
Setting Pawn rotation in the Platformer Gem:
The rotation of the pawn is controlled by the "strafe" input and the camera/mouse vertical movement.
In class "SPG_PlayerController" in function "PlayerWalking^PlayerMove" (the function PlayerMove is in state PlayerWalking) the player acceleration(movement and speed of the player) is set according to the playerinput strafe value.
As such, on a platformer on the PC it has 2 possible values (+90 degrees, -90 degrees).
The resulting vector is after that applied also on the rotation of the Pawn (switching to function "UpdateRotation").
In "UpdateRotation" the vertical offset of the weapon is calculated by the camera/mouse vertical offset : DeltaRot.Pitch = PlayerInput.aLookUp;).
Then the Pawn "FaceRotation" is called. As we have a custom PlayerPawn class it's function is used instead of the general Pawn function (SPG_PlayerPawn.FaceRotation).
This is the spot we need to look in in order to change the way the Pawn rotates.
The code below calculates a smooth transition between angles (percentage value between start and end based on a step).
Code:
Lerp(CurrentYaw, DesiredYaw, TurnRate * DeltaTime);
So we're calculating the next percentage angle from our current Yaw towards desired Yaw based on the turn speed(TurnRate) and the time since the last frame (DeltaTime).
Here is the "magic" trick.
A few lines above we can see
Code:
DesiredYaw = NewRotation.Yaw;
Now, we know that our "Yaw" comes from the strafe input so when we move to the right it's +90 degrees (which is 16384 in UDK degrees). When we rotate to the left it's -() degrees ( -16384 ).
So the Lerp function calculates from -16384 to 16384 when we rotate right, and from 16384 to -16384 when we rotate left.
Knowing this the rotation angles are always from -16384 to 16384 (which is facing away from the camera).
To change the rotation so that the Pawn does it facing TOWARDS the camera we need to make all rotation values to be between +90 degrees to +270 degrees.
So we just add the folowing in "FaceRotation" function of our "SPG_PlayerPawn", right after the line "DesiredYaw = NewRotation.Yaw;"
Code:
if(NewRotation.Yaw < 0)
{
// increase the desider angle by 360 degrees thus turning the rotation to the opposite direction
DesiredYaw += 65536;
}
Resulting code (SPG_PlayerPawn.FaceRotation):
Code:
simulated function FaceRotation(Rotator NewRotation, float DeltaTime)
{
local Rotator FacingRotation;
// Set the desired yaw the new rotation yaw
if (NewRotation.Yaw != 0)
{
DesiredYaw = NewRotation.Yaw;
if(NewRotation.Yaw < 0)
{
// increase the desider angle by 360 degrees thus turning the rotation to the opposite direction
DesiredYaw += 65536;
}
}
// If the current yaw doesn't match the desired yaw, then interpolate towards it
if (CurrentYaw != DesiredYaw)
{
CurrentYaw = Lerp(CurrentYaw, DesiredYaw, TurnRate * DeltaTime);
}
// If we have a valid aim offset node
if (AimNode != None)
{
// Clamp the current pitch to the view pitch min and view pitch max
CurrentPitch = Clamp(CurrentPitch + NewRotation.Pitch, ViewPitchMin, ViewPitchMax);
if (CurrentPitch > 0.f)
{
// Handle when we're aiming up
AimNode.Aim.Y = float(CurrentPitch) / ViewPitchMax;
}
else if (CurrentPitch < 0.f)
{
// Handle when we're aiming down
AimNode.Aim.Y = float(CurrentPitch) / ViewPitchMin;
if (AimNode.Aim.Y > 0.f)
{
AimNode.Aim.Y *= -1.f;
}
}
else
{
// Handle when we're aiming straight forward
AimNode.Aim.Y = 0.f;
}
}
// Update the facing rotation
FacingRotation.Pitch = 0;
FacingRotation.Yaw = CurrentYaw;
FacingRotation.Roll = 0;
SetRotation(FacingRotation);
}
Conclusion:
When you want to change something follow these simple steps:
- analyze how things currently work
- search for something similar in the code-base to see if it's not already implemented
- find a suitable solution that works "The UDK way" (changing start or end values, or change Boolean flags, or change states)
- find the exact spot where you need to implement it (the exact function/property of the proper object)
I hope this was helpful for those of us, that are new to intermediate in UDK coding and modifications.
Bookmarks