1
0
KF2-Dev-Scripts/GameFramework/Classes/GamePlayerCamera.uc
2020-12-13 18:01:13 +03:00

372 lines
9.8 KiB
Ucode

/**
* Copyright 1998-2013 Epic Games, Inc. All Rights Reserved.
*/
class GamePlayerCamera extends Camera
config(Camera)
native(Camera);
// NOTE FOR REFERENCE
// >> IS LOCAL->WORLD (no transpose)
// << IS WORLD->LOCAL (has the transpose)
/**
* Architectural overview
* GamePlayerCamera is an override of the Engine camera, and is the master camera that the player actually looks through. This camera
* will lean on whatever GameCameraBase(s) it is currently using to calc the final camera properties.
* GameCameraBase is a base class for defining specific camera algorithms (e.g. fixed, specatator, first person, third person). Certain
* instances of these can contain another layer of "modes", e.g. ...
* GameThirdPersonCameraModeBase is a base class for defining specific variants of the GameThirdPersonCamera.
*
* */
/////////////////////
// Camera Modes
/////////////////////
/** Implements typical third person camera. */
var(Camera) editinline transient GameCameraBase ThirdPersonCam;
/** Class to use for third person camera. */
var(Camera) protected const class<GameCameraBase> ThirdPersonCameraClass;
/** Implements fixed camera, used for viewing through pre-placed camera actors. */
var(Camera) editinline transient GameCameraBase FixedCam;
/** Class to use for third person camera. */
var(Camera) protected const class<GameCameraBase> FixedCameraClass;
/** Which camera is currently active. */
var(Camera) editinline transient GameCameraBase CurrentCamera;
/////////////////////
// FOV Overriding
/////////////////////
/** Should the FOV be overridden? */
var transient bool bUseForcedCamFOV;
/** If bUseForcedCamFOV is true, use this angle */
var transient float ForcedCamFOV;
/////////////////////
// Interpolation
/////////////////////
var transient bool bInterpolateCamChanges;
var transient private Actor LastViewTarget;
/** Indicates if we should reset interpolation on whichever active camera processes next. */
var transient private bool bResetInterp;
/////////////////////
// Camera Shakes
/////////////////////
/** Scalar applied to all screen shakes in splitscreen. Normally used to dampen, since shakes feel more intense in a smaller viewport. */
var() protected const float SplitScreenShakeScale;
///////////////////////
//// Shaky-cam management
///////////////////////
///** The pawn that was last used to cache the animnodes used for shakycam. Changing viewtarget pawns will trigger a re-cache. */
//var private transient Pawn ShakyCamAnimNodeCachePawn;
///** AnimNode names for the "standing idle" camera animation. */
//var() private const array<name> StandingIdleSequenceNodeNames;
///** Cached refs to the standing idle animations. */
//var private transient array<AnimNodeSequence> StandingIdleSequenceNodes;
/////////////////////
// Etc
/////////////////////
// dealing with situations where camera target is based on another actor
var transient protected Actor LastTargetBase;
var transient protected matrix LastTargetBaseTM;
cpptext
{
virtual void AddPawnToHiddenActorsArray( APawn *PawnToHide );
virtual void RemovePawnFromHiddenActorsArray( APawn *PawnToHide );
virtual void ModifyPostProcessSettings(FPostProcessSettings& PPSettings) const;
};
/**
* Internal. Creates and initializes a new camera of the specified class, returns the object ref.
*/
protected function GameCameraBase CreateCamera(class<GameCameraBase> CameraClass)
{
local GameCameraBase NewCam;
NewCam = new(Outer) CameraClass;
NewCam.PlayerCamera = self;
NewCam.Init();
return NewCam;
}
protected native function CacheLastTargetBaseInfo(Actor TargetBase);
function PostBeginPlay()
{
super.PostBeginPlay();
// Setup camera modes
if ( (ThirdPersonCam == None) && (ThirdPersonCameraClass != None) )
{
ThirdPersonCam = CreateCamera(ThirdPersonCameraClass);
}
if ( (FixedCam == None) && (FixedCameraClass != None) )
{
FixedCam = CreateCamera(FixedCameraClass);
}
}
// reset the camera to a good state
function Reset()
{
bUseForcedCamFOV = false;
}
/**
* Internal. Polls game state to determine best camera to use.
*/
protected function GameCameraBase FindBestCameraType(Actor CameraTarget)
{
local GameCameraBase BestCam;
// if not using a game-specific camera (i.e. not 'default'), we'll let the engine handle it
if (CameraStyle == 'default')
{
if (CameraActor(CameraTarget) != None)
{
// if attached to a CameraActor and not spectating, use Fixed
BestCam = FixedCam;
}
else
{
BestCam = ThirdPersonCam;
}
}
return BestCam;
}
/**
* Available for overriding.
*/
function bool ShouldConstrainAspectRatio()
{
return FALSE;
}
/**
* Query ViewTarget and outputs Point Of View.
*
* @param OutVT ViewTarget to use.
* @param DeltaTime Delta Time since last camera update (in seconds).
*/
function UpdateViewTarget(out TViewTarget OutVT, float DeltaTime)
{
local Pawn P;
local GameCameraBase NewCamera;
local CameraActor CamActor;
// Don't update outgoing viewtarget during an interpolation
if( PendingViewTarget.Target != None && OutVT == ViewTarget && BlendParams.bLockOutgoing )
{
return;
}
// Make sure we have a valid target
if( OutVT.Target == None )
{
`log("Camera::UpdateViewTarget OutVT.Target == None");
return;
}
P = Pawn(OutVT.Target);
// decide which camera to use
NewCamera = FindBestCameraType(OutVT.Target);
// handle a switch if necessary
if (CurrentCamera != NewCamera)
{
if (CurrentCamera != None)
{
CurrentCamera.OnBecomeInActive( NewCamera );
}
if (NewCamera != None)
{
NewCamera.OnBecomeActive( CurrentCamera );
}
CurrentCamera = NewCamera;
}
// update current camera
if (CurrentCamera != None)
{
// we wait to apply this here in case the above code changed currentcamera on us
if (bResetInterp && !bInterpolateCamChanges)
{
CurrentCamera.ResetInterpolation();
}
// Make sure overridden post process settings have a chance to get applied
CamActor = CameraActor(OutVT.Target);
if( CamActor != None )
{
CamActor.GetCameraView(DeltaTime, OutVT.POV);
// Check to see if we should be constraining the viewport aspect. We'll only allow aspect
// ratio constraints for fixed cameras (non-spectator)
if( CurrentCamera == FixedCam && CamActor.bConstrainAspectRatio )
{
// Grab aspect ratio from the CameraActor
bConstrainAspectRatio = true;
OutVT.AspectRatio = CamActor.AspectRatio;
}
// See if the CameraActor wants to override the PostProcess settings used.
CamOverridePostProcessAlpha = CamActor.CamOverridePostProcessAlpha;
if( CamOverridePostProcessAlpha > 0.f )
{
CamPostProcessSettings = CamActor.CamOverridePostProcess;
}
}
CurrentCamera.UpdateCamera(P,self,DeltaTime, OutVT);
if( CameraStyle == 'FreeCam_Default' )
{
Super.UpdateViewTarget(OutVT, DeltaTime);
}
}
else
{
// let the engine handle updating
super.UpdateViewTarget(OutVT, DeltaTime);
}
// check for forced fov
if (bUseForcedCamFOV)
{
OutVT.POV.FOV = ForcedCamFOV;
}
// adjust FOV for splitscreen, 4:3, whatever
OutVT.POV.FOV = AdjustFOVForViewport(OutVT.POV.FOV, P);
// set camera's location and rotation, to handle cases where we are not locked to view target
SetRotation(OutVT.POV.Rotation);
SetLocation(OutVT.POV.Location);
`if(`__TW_)
// Do not call UpdateCameraLensEffects() here. It is called from the
// overridden function in KFPlayerCamera after the FOV has been adjusted
`else
UpdateCameraLensEffects( OutVT );
`endif
// store info about the target's base, to handle target's that are standing on moving geometry
CacheLastTargetBaseInfo(OutVT.Target.Base);
bResetInterp = FALSE;
}
/** Update any attached camera lens effects (e.g. blood) **/
simulated function UpdateCameraLensEffects( const out TViewTarget OutVT )
{
local int Idx;
for (Idx=0; Idx<CameraLensEffects.length; ++Idx)
{
if (CameraLensEffects[Idx] != None)
{
CameraLensEffects[Idx].UpdateLocation(OutVT.POV.Location, OutVT.POV.Rotation, OutVT.POV.FOV);
}
}
}
simulated function DisplayDebug(HUD HUD, out float out_YL, out float out_YPos)
{
local Canvas Canvas;
Super.DisplayDebug(HUD, out_YL, out_YPos);
Canvas = HUD.Canvas;
Canvas.SetDrawColor(255,255,255);
Canvas.DrawText( " " @ `showvar(CurrentCamera));
out_YPos += out_YL;
Canvas.SetPos(4,out_YPos);
if( CurrentCamera != None )
{
CurrentCamera.DisplayDebug(HUD, out_YL, out_YPos);
}
}
/**
* Sets the new color scale
*/
simulated function SetColorScale( vector NewColorScale )
{
if( bEnableColorScaling == TRUE )
{
// set the default color scale
bEnableColorScaling = TRUE;
ColorScale = NewColorScale;
bEnableColorScaleInterp = false;
}
}
/** Stop interpolation for this frame and just let everything go to where it's supposed to be. */
simulated function ResetInterpolation()
{
bResetInterp = TRUE;
}
/**
* Give cameras a chance to influence player view rotation.
*/
function ProcessViewRotation(float DeltaTime, out rotator out_ViewRotation, out rotator out_DeltaRot)
{
if( CurrentCamera != None )
{
CurrentCamera.ProcessViewRotation(DeltaTime, ViewTarget.Target, out_ViewRotation, out_DeltaRot);
}
}
/**
* Given a horizontal FOV that assumes a 16:9 viewport, return an appropriately
* adjusted FOV for the viewport of the target pawn.
* Used to correct for splitscreen.
*/
final protected native function float AdjustFOVForViewport(float inHorizFOV, Pawn CameraTargetPawn) const;
defaultproperties
{
DefaultFOV=70.f
CameraStyle=Default
ThirdPersonCameraClass=class'GameThirdPersonCamera'
FixedCameraClass=class'GameFixedCamera'
}