OLS/Source/ols/Public/Camera/OLSCameraMode.h
LongLy 57b53b9c0c Implemented OLSCameraMode.
Addressed @TODOs related to custom logs and OLSCameraMode
2025-01-20 14:08:07 -07:00

192 lines
4.9 KiB
C++

// © 2024 Long Ly. All rights reserved. Any unauthorized use, reproduction, or distribution of this trademark is strictly prohibited and may result in legal action.
#pragma once
#include "CoreMinimal.h"
#include "GameplayTagContainer.h"
#include "UObject/Object.h"
#include "OLSCameraMode.generated.h"
/**
* EOLSCameraModeBlendFunction
*
* Blend function used for transitioning between camera modes.
*/
UENUM(BlueprintType)
enum class EOLSCameraModeBlendFunction : uint8
{
// Does a simple linear interpolation.
Linear,
// Immediately accelerates, but smoothly decelerates into the target. Ease amount controlled by the exponent.
EaseIn,
// Smoothly accelerates, but does not decelerate into the target. Ease amount controlled by the exponent.
EaseOut,
// Smoothly accelerates and decelerates. Ease amount controlled by the exponent.
EaseInOut,
COUNT UMETA(Hidden)
};
/**
* FOLSCameraModeView
*
* View data produced by the camera mode that is used to blend camera modes.
*/
struct FOLSCameraModeView
{
public:
FOLSCameraModeView();
void Blend(const FOLSCameraModeView& other, float otherWeight);
public:
FVector Location;
FRotator Rotation;
FRotator ControlRotation;
float FieldOfView;
};
/**
* UOLSCameraMode
*
* Base class for all camera modes.
*/
UCLASS(Abstract, NotBlueprintable)
class OLS_API UOLSCameraMode : public UObject
{
GENERATED_BODY()
public:
UOLSCameraMode();
class UOLSCameraComponent* GetOLSCameraComponent() const;
virtual UWorld* GetWorld() const override;
AActor* GetTargetActor() const;
const FOLSCameraModeView& GetCameraModeView() const;
// Called when this camera mode is activated on the camera mode stack.
virtual void OnActivation();
// Called when this camera mode is deactivated on the camera mode stack.
virtual void OnDeactivation();
void UpdateCameraMode(float deltaTime);
float GetBlendTime() const;
float GetBlendWeight() const;
void SetBlendWeight(float weight);
FGameplayTag GetCameraTypeTag() const;
virtual void DrawDebug(UCanvas* canvas) const;
protected:
virtual FVector GetPivotLocation() const;
virtual FRotator GetPivotRotation() const;
virtual void UpdateView(float deltaTime);
virtual void UpdateBlending(float deltaTime);
protected:
// A tag that can be queried by gameplay code that cares when a kind of camera mode is active
// without having to ask about a specific mode (e.g., when aiming downsights to get more accuracy)
UPROPERTY(EditDefaultsOnly, Category = "Blending")
FGameplayTag CameraTypeTag = FGameplayTag::EmptyTag;
// View output produced by the camera mode.
FOLSCameraModeView View;
// The horizontal field of view (in degrees).
UPROPERTY(EditDefaultsOnly, Category = "View", Meta = (UIMin = "5.0", UIMax = "170", ClampMin = "5.0", ClampMax = "170.0"))
float FieldOfView = 0.0f;
// Minimum view pitch (in degrees).
UPROPERTY(EditDefaultsOnly, Category = "View", Meta = (UIMin = "-89.9", UIMax = "89.9", ClampMin = "-89.9", ClampMax = "89.9"))
float ViewPitchMin = 0.0f;
// Maximum view pitch (in degrees).
UPROPERTY(EditDefaultsOnly, Category = "View", Meta = (UIMin = "-89.9", UIMax = "89.9", ClampMin = "-89.9", ClampMax = "89.9"))
float ViewPitchMax = 0.0f;
// How long it takes to blend in this mode.
UPROPERTY(EditDefaultsOnly, Category = "Blending")
float BlendTime = 0.0f;
// Function used for blending.
UPROPERTY(EditDefaultsOnly, Category = "Blending")
EOLSCameraModeBlendFunction BlendFunction = EOLSCameraModeBlendFunction::Linear;
// Exponent used by blend functions to control the shape of the curve.
UPROPERTY(EditDefaultsOnly, Category = "Blending")
float BlendExponent = 0.0f;
// Linear blend alpha used to determine the blend weight.
float BlendAlpha = 0.0f;
// Blend weight calculated using the blend alpha and function.
float BlendWeight = 0.0f;
protected:
/** If true, skips all interpolation and puts camera in ideal location. Automatically set to false next frame. */
UPROPERTY(Transient)
uint32 bShouldResetInterpolation : 1 = false;
};
/**
* UOLSCameraModeStack
*
* Stack used for blending camera modes.
*/
UCLASS()
class UOLSCameraModeStack : public UObject
{
GENERATED_BODY()
public:
UOLSCameraModeStack();
void ActivateStack();
void DeactivateStack();
bool IsStackActivate() const;
void PushCameraMode(TSubclassOf<UOLSCameraMode> cameraModeClass);
bool EvaluateStack(float deltaTime, FOLSCameraModeView& outCameraModeView);
void DrawDebug(UCanvas* canvas) const;
// Gets the tag associated with the top layer and the blend weight of it
void GetBlendInfo(float& outWeightOfTopLayer, FGameplayTag& outTagOfTopLayer) const;
protected:
UOLSCameraMode* GetCameraModeInstance(TSubclassOf<UOLSCameraMode> cameraModeClass);
void UpdateStack(float deltaTime);
void BlendStack(FOLSCameraModeView& outCameraModeView) const;
protected:
uint8 bIsStackActive : 1 = true;
UPROPERTY()
TArray<TObjectPtr<UOLSCameraMode>> CameraModeInstances;
UPROPERTY()
TArray<TObjectPtr<UOLSCameraMode>> CameraModeStack;
};