第一次提交
This commit is contained in:
@@ -0,0 +1,168 @@
|
||||
// Copyright(c) Aurora Devs 2022-2025. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Animation/AnimNotifies/AnimNotifyState.h"
|
||||
#include "Curves/CurveFloat.h"
|
||||
#include "Misc/Guid.h"
|
||||
#include "UGC_CameraPropertiesRequestAnimNotifyState.generated.h"
|
||||
|
||||
/**
|
||||
* Anim Notify State to send requests to the FOVAnimNotifyModifier to change the FOV during animations.
|
||||
*/
|
||||
UCLASS()
|
||||
class AURORADEVS_UGC_API UUGC_FOVRequestAnimNotifyState : public UAnimNotifyState
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
protected:
|
||||
virtual void NotifyBegin(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation, float TotalDuration, const FAnimNotifyEventReference& EventReference) override;
|
||||
virtual FString GetNotifyName_Implementation() const override;
|
||||
virtual FLinearColor GetEditorColor() override;
|
||||
|
||||
protected:
|
||||
/** Horizontal FOV to set. */
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings")
|
||||
float TargetFOV = 90.f;
|
||||
|
||||
/** Time needed for the FOV value to ease into the TargetValue. */
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings")
|
||||
float BlendInDuration = 0.5f;
|
||||
|
||||
/** Controls the blending in. The curve has to be normalized (going from 0 to 1). Leave empty or use Hermit if unsure. */
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings")
|
||||
TObjectPtr<UCurveFloat> BlendInCurve = nullptr;
|
||||
|
||||
/** Time needed for the FOV value to ease out from the TargetValue into the normal gameplay value. */
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings")
|
||||
float BlendOutDuration = 0.5f;
|
||||
|
||||
/** Controls the blending Out. The curve has to be normalized (going from 0 to 1). Leave empty or use Hermit if unsure. */
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings")
|
||||
TObjectPtr<UCurveFloat> BlendOutCurve = nullptr;
|
||||
|
||||
#if WITH_EDITORONLY_DATA
|
||||
/** Whether the name of the notify should include the request Id. */
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings")
|
||||
bool bShowRequestIdInName = false;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
FGuid RequestId = FGuid::NewGuid();
|
||||
};
|
||||
|
||||
/**
|
||||
* Anim Notify State to send requests to the ArmOffsetAnimNotifyModifier to change the Arm Offsets during animations.
|
||||
*/
|
||||
UCLASS()
|
||||
class AURORADEVS_UGC_API UUGC_ArmOffsetRequestAnimNotifyState : public UAnimNotifyState
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
protected:
|
||||
virtual void NotifyBegin(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation, float TotalDuration, const FAnimNotifyEventReference& EventReference) override;
|
||||
virtual FString GetNotifyName_Implementation() const override;
|
||||
virtual FLinearColor GetEditorColor() override;
|
||||
|
||||
protected:
|
||||
/** Whether to change socket offset. */
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings|SocketOffset")
|
||||
bool bModifySocketOffset = false;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings|SocketOffset", meta = (EditCondition="bModifySocketOffset"))
|
||||
FVector TargetSocketOffset = FVector::Zero();
|
||||
|
||||
/** Time needed for the Socket Offset value to ease into the TargetValue. */
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings|SocketOffset", meta = (EditCondition = "bModifySocketOffset"))
|
||||
float SocketOffsetBlendInDuration = 0.5f;
|
||||
|
||||
/** Controls the blending in. The curve has to be normalized (going from 0 to 1). Leave empty or use Hermit if unsure. */
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings|SocketOffset", meta = (EditCondition = "bModifySocketOffset"))
|
||||
TObjectPtr<UCurveFloat> SocketOffsetBlendInCurve = nullptr;
|
||||
|
||||
/** Time needed for the Socket Offset value to ease out from the TargetValue into the normal gameplay value. */
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings|SocketOffset", meta = (EditCondition = "bModifySocketOffset"))
|
||||
float SocketOffsetBlendOutDuration = 0.5f;
|
||||
|
||||
/** Controls the blending Out. The curve has to be normalized (going from 0 to 1). Leave empty or use Hermit if unsure. */
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings|SocketOffset", meta = (EditCondition = "bModifySocketOffset"))
|
||||
TObjectPtr<UCurveFloat> SocketOffsetBlendOutCurve = nullptr;
|
||||
|
||||
/** Whether to change socket offset. */
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings|TargetOffset")
|
||||
bool bModifyTargetOffset = false;
|
||||
|
||||
/** Target Offset to set. */
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings|TargetOffset", meta = (EditCondition = "bModifyTargetOffset"))
|
||||
FVector TargetTargetOffset = FVector::Zero();
|
||||
|
||||
/** Time needed for the Target Offset value to ease into the TargetValue. */
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings|TargetOffset", meta = (EditCondition = "bModifyTargetOffset"))
|
||||
float TargetOffsetBlendInDuration = 0.5f;
|
||||
|
||||
/** Controls the blending in. The curve has to be normalized (going from 0 to 1). Leave empty or use Hermit if unsure. */
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings|TargetOffset", meta = (EditCondition = "bModifyTargetOffset"))
|
||||
TObjectPtr<UCurveFloat> TargetOffsetBlendInCurve = nullptr;
|
||||
|
||||
/** Time needed for the Target Offset value to ease out from the TargetValue into the normal gameplay value. */
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings|TargetOffset", meta = (EditCondition = "bModifyTargetOffset"))
|
||||
float TargetOffsetBlendOutDuration = 0.5f;
|
||||
|
||||
/** Controls the blending Out. The curve has to be normalized (going from 0 to 1). Leave empty or use Hermit if unsure. */
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings|TargetOffset", meta = (EditCondition = "bModifyTargetOffset"))
|
||||
TObjectPtr<UCurveFloat> TargetOffsetBlendOutCurve = nullptr;
|
||||
|
||||
#if WITH_EDITORONLY_DATA
|
||||
/** Whether the name of the notify should include the request Id. */
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings")
|
||||
bool bShowRequestIdInName = false;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
FGuid RequestId = FGuid::NewGuid();
|
||||
};
|
||||
|
||||
/**
|
||||
* Anim Notify State to send requests to the ArmLengthAnimNotifyModifier to change the Arm Length during animations.
|
||||
*/
|
||||
UCLASS()
|
||||
class AURORADEVS_UGC_API UUGC_ArmLengthRequestAnimNotifyState : public UAnimNotifyState
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
protected:
|
||||
virtual void NotifyBegin(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation, float TotalDuration, const FAnimNotifyEventReference& EventReference) override;
|
||||
virtual FString GetNotifyName_Implementation() const override;
|
||||
virtual FLinearColor GetEditorColor() override;
|
||||
|
||||
protected:
|
||||
/** ArmLength to set. */
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings")
|
||||
float TargetArmLength = 0.f;
|
||||
|
||||
/** Time needed for the ArmLength value to ease into the TargetValue. */
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings")
|
||||
float BlendInDuration = 0.5f;
|
||||
|
||||
/** Controls the blending in. The curve has to be normalized (going from 0 to 1). Leave empty or use Hermit if unsure. */
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings")
|
||||
TObjectPtr<UCurveFloat> BlendInCurve = nullptr;
|
||||
|
||||
/** Time needed for the ArmLength value to ease out from the TargetValue into the normal gameplay value. */
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings")
|
||||
float BlendOutDuration = 0.5f;
|
||||
|
||||
/** Controls the blending Out. The curve has to be normalized (going from 0 to 1). Leave empty or use Hermit if unsure. */
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings")
|
||||
TObjectPtr<UCurveFloat> BlendOutCurve = nullptr;
|
||||
|
||||
#if WITH_EDITORONLY_DATA
|
||||
/** Whether the name of the notify should include the request Id. */
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings")
|
||||
bool bShowRequestIdInName = false;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
FGuid RequestId = FGuid::NewGuid();
|
||||
};
|
||||
30
Plugins/UGC/Source/AuroraDevs_UGC/Public/AuroraDevs_UGC.h
Normal file
30
Plugins/UGC/Source/AuroraDevs_UGC/Public/AuroraDevs_UGC.h
Normal file
@@ -0,0 +1,30 @@
|
||||
// Copyright(c) Aurora Devs 2022-2025. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Modules/ModuleManager.h"
|
||||
|
||||
#ifndef AURORA_DEVS_UGC
|
||||
#define AURORA_DEVS_UGC
|
||||
#endif
|
||||
|
||||
DECLARE_LOG_CATEGORY_EXTERN(AuroraUGC, Log, All);
|
||||
#define UGC_LOG(Verbosity, Format, ...) UE_LOG(AuroraUGC, Verbosity, Format, ##__VA_ARGS__)
|
||||
#define UGC_LOG_ONCE(LogId, Verbosity, Format, ...)\
|
||||
do\
|
||||
{\
|
||||
static bool bLogged##LogId##Already = false; \
|
||||
if (!bLogged##LogId##Already)\
|
||||
{\
|
||||
UE_LOG(AuroraUGC, Verbosity, Format, ##__VA_ARGS__); \
|
||||
bLogged##LogId##Already = true; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
class FAuroraDevs_UGCModule : public IModuleInterface
|
||||
{
|
||||
public:
|
||||
virtual void StartupModule() override;
|
||||
virtual void ShutdownModule() override;
|
||||
};
|
||||
@@ -0,0 +1,53 @@
|
||||
// Copyright(c) Aurora Devs 2022-2025. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GameFramework/SpringArmComponent.h"
|
||||
#include "Camera/Data/UGC_CameraData.h"
|
||||
#include "Misc/CoreMiscDefines.h"
|
||||
#include "UGC_SpringArmComponentBase.generated.h"
|
||||
|
||||
/**
|
||||
* Custom SpringArm component with enhanced collision handling.
|
||||
*/
|
||||
UCLASS(Blueprintable, Abstract, ClassGroup = "UGC Camera", Category = "UGC|Components", meta = (BlueprintSpawnableComponent))
|
||||
class AURORADEVS_UGC_API UUGC_SpringArmComponentBase : public USpringArmComponent
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
protected:
|
||||
virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
|
||||
virtual void UpdateDesiredArmLocation(bool bDoTrace, bool bDoLocationLag, bool bDoRotationLag, float DeltaTime) override;
|
||||
virtual FVector BlendLocations(const FVector& DesiredArmLocation, const FVector& TraceHitLocation, bool bHitSomething, float DeltaTime) override;
|
||||
bool IsPlayerControlled() const;
|
||||
|
||||
protected:
|
||||
/** Camera collision settings including feelers */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = CameraCollision, meta = (EditCondition = "bDoCollisionTest"))
|
||||
FCameraCollisionSettings CameraCollisionSettings;
|
||||
|
||||
/* *EXPERIMENTAL* Might cause bugs.
|
||||
* Whether we want the framing to stay the same during collisions. This is useful for games where you need to aim (bow, gun; etc.) since it
|
||||
* allows the center of the screen to not shift during collision.
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = CameraCollision)
|
||||
bool bMaintainFramingDuringCollisions = false;
|
||||
|
||||
/* Whether to draw debug messages regarding the spring arm collision.*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "CameraCollision")
|
||||
bool bPrintCollisionDebug = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "CameraCollision", meta = (EditCondition = "bPrintCollisionDebug"))
|
||||
bool bPrintHitActors = false;
|
||||
|
||||
protected:
|
||||
/** Runtime interpolated distance percentage (0 = fully blocked, 1 = clear) */
|
||||
float DistBlockedPct = 1.f;
|
||||
|
||||
// Debug-only: Track which actors were hit by feeler rays (not needed in shipping)
|
||||
#if WITH_EDITORONLY_DATA
|
||||
UPROPERTY(VisibleInstanceOnly, Transient, Category = "CameraCollision|Debug")
|
||||
TArray<class AActor*> HitActors;
|
||||
#endif
|
||||
};
|
||||
@@ -0,0 +1,639 @@
|
||||
// Copyright(c) Aurora Devs 2022-2025. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Curves/CurveFloat.h"
|
||||
#include "Engine/DataAsset.h"
|
||||
#include "Engine/EngineTypes.h"
|
||||
#include "UGC_CameraData.generated.h"
|
||||
|
||||
/*
|
||||
* The settings of the camera yaw follow. This is useful for player who don't like to control the camera too much.
|
||||
* The YawFollowModifier in blueprint will adjust the yaw to face the movement direction (Used by AAA games like Hogwarts Legacy, Witcher, etc).
|
||||
*/
|
||||
USTRUCT(BlueprintType)
|
||||
struct FCameraYawFollowSettings
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
// Whether the yaw should follow the character, when they are moving.
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera Yaw Follow")
|
||||
bool bEnableYawMovementFollow = true;
|
||||
|
||||
// Whether the yaw threshold timer should be reset when the character stop moving.
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera Yaw Follow")
|
||||
bool bResetThresholdTimerWhenNoMovement = false;
|
||||
|
||||
// The speed at which the camera rotates its yaw in the movement direction of the character.
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera Yaw Follow")
|
||||
float YawFollowSpeed = 50.f;
|
||||
|
||||
/* The minimum time the player shouldn't rotate the camera manually before the yaw follow kicks in.
|
||||
* The timer can be reset when the character stops moving by enabling `bResetThresholdTimerWhenNoMovement`.
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera Yaw Follow")
|
||||
float YawFollowTimeThreshold = 2.f;
|
||||
|
||||
// Threshold yaw angle above which we trigger the yaw follow modifier.
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera Yaw Follow")
|
||||
float YawFollowAngleThreshold = 10.f;
|
||||
};
|
||||
|
||||
/*
|
||||
* The settings of the camera pitch follow. This is useful for player who don't like to control the camera too much.
|
||||
* The PitchFollowModifier in blueprint will adjust the pitch to face slopes, falling and reset the pitch if it's left untouched for long enough.
|
||||
* (Used by AAA games like Red Dead Redemption, Hogwarts Legacy, Witcher, etc)
|
||||
*/
|
||||
USTRUCT(BlueprintType)
|
||||
struct FCameraPitchFollowSettings
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
/** Whether the pitch should reset to the resting pitch when the character is moving. */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera Pitch Follow")
|
||||
bool bEnablePitchMovementFollow = true;
|
||||
|
||||
/** The speed at which the camera rotates its pitch to follow when falling/moving. */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera Pitch Follow")
|
||||
float PitchFollowSpeed = 10.f;
|
||||
|
||||
/** The minimum time the player shouldn't rotate the camera manually before the pitch follow kicks in. */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera Pitch Follow")
|
||||
float PitchFollowTimeThreshold = 2.f;
|
||||
|
||||
/** Whether the pitch threshold timer should be reset when the character stop moving. */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera Pitch Follow")
|
||||
bool bResetThresholdTimerWhenNoMovement = false;
|
||||
|
||||
/** Threshold pitch angle above which we trigger the pitch follow modifier to reset the pitch to RestingPitch. */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Movement Follow")
|
||||
float PitchFollowAngleThreshold = 5.f;
|
||||
|
||||
/** The pitch to go to when the the character is moving without controlling the camera's pitch is messed up. */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Movement Follow")
|
||||
float RestingPitch = -10.f;
|
||||
|
||||
/** Should the camera look down when the character is falling for at least TimeThresholdWhenFalling in seconds and the floor is at least MinDistanceFromGround centimeters away ? */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Falling")
|
||||
bool bTriggerWhenFalling = true;
|
||||
|
||||
/** The minimun duration of time the character should fall before the modifier is triggered. */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Falling", meta = (EditCondition = "bTriggerWhenFalling"))
|
||||
float PitchFollowTimeThresholdWhenFalling = 0.5f;
|
||||
|
||||
/** The minimum distance we should be above the ground to trigger the pitch follow when falling. */
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Falling", meta = (EditCondition = "bTriggerWhenFalling"))
|
||||
float MinDistanceFromGroundToTriggerWhenFalling = 500.f;
|
||||
|
||||
/** A multiplier to apply to the follow speed of the camera when we're feeling. */
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Falling", meta = (EditCondition = "bTriggerWhenFalling"))
|
||||
float SpeedMultiplierWhenFalling = 6.f;
|
||||
|
||||
/** Should the camera pitch look toward the inclination of the slope the character is walking on? */
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Slopes")
|
||||
bool bTriggerOnSlopes = true;
|
||||
|
||||
/** The minimum slope pitch inclination angle so that the pitch follow modifier is triggered (so that it's not triggered for small bumps). */
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Slopes", meta = (EditCondition = "bTriggerOnSlopes"))
|
||||
float SlopeMinIncline = 25.f;
|
||||
|
||||
/** The weight of the pitch of the camera when the modifier is trying to follow a slope.
|
||||
* 1 means the camera pitch will match the slope angle exactly, 0.5 means half the angle; etc.
|
||||
*/
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Slopes", meta = (MultiLine = "true", EditCondition = "bTriggerOnSlopes", UIMin = "0.1", ClampMin = "0.1", UIMax = "1", ClampMax = "1"))
|
||||
float SlopeFollowWeight = 1.f;
|
||||
};
|
||||
|
||||
/*
|
||||
* The settings of the camera Arm Offset.
|
||||
*/
|
||||
USTRUCT(BlueprintType)
|
||||
struct FCameraArmOffsetSettings
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
/** Offset at the end of the spring arm. Use this instead of the relative-space *rotation* so that the UE camera system works as expected. */
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera Arm Offset Modifier", meta = (MultiLine = "true"))
|
||||
FVector ArmSocketOffset = FVector(0.f, 40.f, 0.f);
|
||||
|
||||
/** How long does it take to blend to the current ArmSocketOffset. */
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera Arm Offset Modifier", meta = (MultiLine = "true", UIMin = "0", ClampMin = "0"))
|
||||
float ArmSocketOffsetBlendTime = 0.5f;
|
||||
|
||||
/** Controls the acceleration/deceleration of the blend. The curve has to be normalized (going from 0 to 1). Leave empty or use Hermite if unsure. */
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera Arm Offset Modifier", meta = (MultiLine = "true"))
|
||||
TObjectPtr<UCurveFloat> ArmSocketOffsetBlendCurve;
|
||||
|
||||
/** Offset at start of spring, applied in world space. Use this if you want a world-space offset from the parent component instead of the usual relative-space location. */
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera Arm Offset Modifier", meta = (MultiLine = "true"))
|
||||
FVector ArmTargetOffset = FVector(0.f, 0.f, 58.f);
|
||||
|
||||
/** How long does it take to blend to the current ArmTargetOffset. */
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera Arm Offset Modifier", meta = (MultiLine = "true", UIMin = "0", ClampMin = "0"))
|
||||
float ArmTargetOffsetBlendTime = 0.5f;
|
||||
|
||||
/** Controls the acceleration/deceleration of the blend. The curve has to be normalized (going from 0 to 1). Leave empty or use Hermite if unsure. */
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera Arm Offset Modifier", meta = (MultiLine = "true"))
|
||||
TObjectPtr<UCurveFloat> ArmTargetOffsetBlendCurve;
|
||||
};
|
||||
|
||||
/*
|
||||
* This is used by the PitchToArmLengthAndFOV Camera Modifier in blueprint.
|
||||
* This makes the Arm Length and FOV change when the character is looking up/down (Used by many AAA games like all GTA games, Red Dead Redemption Assassin's Creed, Hogwarts Legacy, etc.).
|
||||
*/
|
||||
USTRUCT(BlueprintType)
|
||||
struct FCameraPitchToArmAndFOVCurveSettings
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera Pitch to Arm and FOV Modifier", meta = (MultiLine = "true"))
|
||||
bool Enabled = true;
|
||||
|
||||
/** Curve with X and Y between -1.0 and 1.0. This maps the LocalMinPitch (X=-1.0) and LocalMaxPitch (X=1.0) to the MinArmLength and MaxArmLength. */
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera Pitch to Arm and FOV Modifier", meta = (MultiLine = "true"))
|
||||
TObjectPtr<UCurveFloat> PitchToArmLengthCurve;
|
||||
|
||||
/** Curve with X and Y between -1.0 and 1.0. This maps the LocalMinPitch (X=-1.0) and LocalMaxPitch (X=1.0) to the MinFOV and MaxFOV. */
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera Pitch to Arm and FOV Modifier", meta = (MultiLine = "true"))
|
||||
TObjectPtr<UCurveFloat> PitchToFOVCurve;
|
||||
};
|
||||
|
||||
/*
|
||||
* The settings of the camera Arm Length. Defines the range of the Arm Length and how to blend from one range to this one. This is used by the PitchToArmLengthAndFOV Camera Modifier in blueprint.
|
||||
* This makes the Arm Length change when the character is looking up/down (Used by many AAA games like all GTA games, Red Dead Redemption Assassin's Creed, Hogwarts Legacy, etc.).
|
||||
*/
|
||||
USTRUCT(BlueprintType)
|
||||
struct FCameraArmLengthSettings
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
/** The minimum arm length value. The length of the arm will change depending on the current pitch of the camera and the PitchToArmLengthCurve. */
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera Arm Length", meta = (MultiLine = "true"))
|
||||
float MinArmLength = 100.f;
|
||||
|
||||
/** The maximum arm length value. The length of the arm will change depending on the current pitch of the camera and the PitchToArmLengthCurve. */
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera Arm Length", meta = (MultiLine = "true"))
|
||||
float MaxArmLength = 250.f;
|
||||
|
||||
/** How long does it take to blend to the current Arm Length range. */
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera Arm Length", meta = (MultiLine = "true", UIMin = "0", ClampMin = "0"))
|
||||
float ArmRangeBlendTime = 0.5f;
|
||||
|
||||
/** Controls the acceleration/deceleration of the blend. The curve has to be normalized (going from 0 to 1). Leave empty or use Hermite if unsure. */
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera Arm Length", meta = (MultiLine = "true"))
|
||||
TObjectPtr<UCurveFloat> ArmRangeBlendCurve;
|
||||
};
|
||||
|
||||
/*
|
||||
* The settings of the camera FOV. Defines the range of the FOV and how to blend from one range to this one. This is used by the PitchToArmLengthAndFOV Camera Modifier in blueprint.
|
||||
* This makes the FOV change when the character is looking up/down (Used by many AAA games like GTA IV).
|
||||
*/
|
||||
USTRUCT(BlueprintType)
|
||||
struct FCameraFOVSettings
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
/** The minimum FOV value. The FOV of the camera will change depending on the current pitch of the camera and the PitchToFOVCurve. */
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera FOV", meta = (MultiLine = "true"))
|
||||
float MinFOV = 90.f;
|
||||
|
||||
/** The maximum FOV value. The FOV of the camera will change depending on the current pitch of the camera and the PitchToFOVCurve. */
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera FOV", meta = (MultiLine = "true"))
|
||||
float MaxFOV = 125.f;
|
||||
|
||||
/** A tolerance in degrees above which the Angle Constraints modifier will start decelerating the camera. */
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera FOV", meta = (MultiLine = "true", UIMin = "0", ClampMin = "0"))
|
||||
float FOVRangeBlendTime = 0.5f;
|
||||
|
||||
/** Controls the acceleration/deceleration of the blend. The curve has to be normalized (going from 0 to 1). Leave empty or use Hermite if unsure. */
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera FOV", meta = (MultiLine = "true"))
|
||||
TObjectPtr<UCurveFloat> FOVRangeBlendCurve;
|
||||
};
|
||||
|
||||
/*
|
||||
* The settings of the camera yaw contraints. This is useful to limit how much the character can look left/right.
|
||||
* The looking input action needs to have a UGC_CameraTurnRateModifier for the camera to decelerate when close to the constraints.
|
||||
*/
|
||||
USTRUCT(BlueprintType)
|
||||
struct FCameraYawConstraintSettings
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
/** Whether the yaw should be constrained to LocalMinYaw and LocalMaxYaw. If the yaw was already out of the new range, it will blend into range using the BlendTime and BlendCurve. */
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera Angle Constraints", meta = (MultiLine = "true"))
|
||||
bool bConstrainYaw = false;
|
||||
|
||||
/** How close in degrees to the YawMin or YawMax should the camera start decelerating? */
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera Angle Constraints", meta = (MultiLine = "true", UIMin = "0", ClampMin = "0"))
|
||||
float YawConstraintTolerance = 10.f;
|
||||
|
||||
/** How much can the character look right (angle in degrees). */
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera Angle Constraints", meta = (MultiLine = "true"))
|
||||
float LocalMinYaw = 0.f;
|
||||
|
||||
/** How much can the character look left (angle in degrees). */
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera Angle Constraints", meta = (MultiLine = "true"))
|
||||
float LocalMaxYaw = 359.998993f;
|
||||
|
||||
/** How fast should we blend from one Yaw constraint range to this one. */
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera Angle Constraints", meta = (MultiLine = "true", UIMin = "0", ClampMin = "0"))
|
||||
float YawConstraintsBlendTime = 0.5f;
|
||||
|
||||
/** Controls the acceleration/deceleration of the blend. The curve has to be normalized (going from 0 to 1). Leave empty or use Hermite if unsure. */
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera Angle Constraints", meta = (MultiLine = "true"))
|
||||
TObjectPtr<UCurveFloat> YawConstraintsBlendCurve;
|
||||
};
|
||||
|
||||
/*
|
||||
* The settings of the camera pitch contraints. This is useful to limit how much the character can look up/down. AAA games usually do not allow the entire 180 degrees range.
|
||||
* The looking input action needs to have a UGC_CameraTurnRateModifier for the camera to decelerate when close to the constraints.
|
||||
*/
|
||||
USTRUCT(BlueprintType)
|
||||
struct FCameraPitchConstraintSettings
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
/** Whether the pitch should be constrained to LocalMinPitch and LocalMaxPitch. If the yaw was already out of the new range, it will blend into range using the BlendTime and BlendCurve. */
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera Angle Constraints", meta = (MultiLine = "true"))
|
||||
bool bConstrainPitch = false;
|
||||
|
||||
/** How close in degrees to the PitchMin or PitchMax should the camera start decelerating? */
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera Angle Constraints", meta = (MultiLine = "true", UIMin = "0", ClampMin = "0"))
|
||||
float PitchConstraintTolerance = 10.f;
|
||||
|
||||
// How much can the character look down (angle in degrees).
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera Angle Constraints", meta = (MultiLine = "true"))
|
||||
float LocalMinPitch = -89.99f;
|
||||
|
||||
// How much can the character look up (angle in degrees).
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera Angle Constraints", meta = (MultiLine = "true"))
|
||||
float LocalMaxPitch = 89.99f;
|
||||
|
||||
/** How fast should we blend from one Pitch constraint range to this one. */
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera Angle Constraints", meta = (MultiLine = "true", UIMin = "0", ClampMin = "0"))
|
||||
float PitchConstraintsBlendTime = 0.5f;
|
||||
|
||||
/** Controls the acceleration/deceleration of the blend. The curve has to be normalized (going from 0 to 1). Leave empty or use Hermite if unsure. */
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera Angle Constraints", meta = (MultiLine = "true"))
|
||||
TObjectPtr<UCurveFloat> PitchConstraintsBlendCurve;
|
||||
};
|
||||
|
||||
/*
|
||||
* The settings of the focus camera. This is used for hard-lock in games.
|
||||
* Has a function which retrieves the target we want the camera to look at. (Uses the Strategy Design Pattern)
|
||||
*/
|
||||
USTRUCT(BlueprintType)
|
||||
struct FUGCCameraFocusSettings
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
/** Whether the focus camera is enabled. If it is, this will use the Focus Target Method to get the target's location.*/
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera Focus", meta = (MultiLine = "true"))
|
||||
bool bEnabled = false;
|
||||
|
||||
/** How fast the camera will focus the target.*/
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera Focus", meta = (MultiLine = "true"))
|
||||
float InterpSpeed = 10.f;
|
||||
|
||||
/** An offset in degrees applied on the pitch and yaw. This is useful if you want the focused location to always be on the left/right or looked down/up.*/
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera Focus", meta = (MultiLine = "true"))
|
||||
FRotator RotationOffset = FRotator::ZeroRotator;
|
||||
|
||||
/** Whether the camera input should be ignored during focus.*/
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera Focus", meta = (MultiLine = "true"))
|
||||
bool bIgnoreCameraInput = false;
|
||||
|
||||
|
||||
/** Whether we should rotatet only the yaw angle of the camera or the pitch as well.
|
||||
* You can set this to true and combine it with the Rotation Offset if you want the cam to stay at a specific pitch. */
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera Focus", meta = (MultiLine = "true"))
|
||||
bool bRotateYawOnly = false;
|
||||
|
||||
/** Whether we should stop focusing if the Line of Sight is occluded.*/
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera Focus", meta = (MultiLine = "true"))
|
||||
bool bStopIfBlockedLOS = false;
|
||||
|
||||
/** How long should the line of sight be occluded before we stop focusing trying to focus target.*/
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera Focus", meta = (MultiLine = "true", EditCondition = "bStopIfBlockedLOS"))
|
||||
float BlockedLOSTimeThreshold = 3.f;
|
||||
|
||||
/** The distance from the target below which we will stop focusing the target. If this is too low, the camera might start rotating crazily around the target.*/
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera Focus", meta = (MultiLine = "true"))
|
||||
float MinDistanceFromTarget = 100.f;
|
||||
|
||||
/** The distance from the target above which we will stop focusing the target.*/
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera Focus", meta = (MultiLine = "true"))
|
||||
float MaxDistanceFromTarget = 1000.f;
|
||||
|
||||
/** Function which retrieves the target we want the camera to look at. (Uses the Strategy Design Pattern) */
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera Focus", Instanced, meta = (MultiLine = "true"))
|
||||
TObjectPtr<class UUGC_IFocusTargetMethod> FocusTargetMethod;
|
||||
};
|
||||
|
||||
/*
|
||||
* The settings of a camera modifier which needs to retrieve a list of actors.
|
||||
* Has a function which retrieves the all actors relevant for some camera modifier/other object with settings inheriting from this class. (Uses the Strategy Design Pattern)
|
||||
*/
|
||||
USTRUCT(BlueprintType)
|
||||
struct FUGCCameraSettingsWithGetActorsMethod
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
/** Function which retrieves all relevant actors. (Uses the Strategy Design Pattern) */
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Targets", Instanced, meta = (MultiLine = "true"))
|
||||
TObjectPtr<class UUGC_IGetActorsMethod> GetActorsMethod;
|
||||
};
|
||||
|
||||
/*
|
||||
* The settings of a camera modifier or other object which needs to retrieve one actor location.
|
||||
* Has a function which an actor and its location using the instanced method. (Uses the Strategy Design Pattern)
|
||||
*/
|
||||
USTRUCT(BlueprintType)
|
||||
struct FUGCCameraSettingsWithGetActorLocationMethod
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
/** Function which retrieves the relevant actor and their position. (Uses the Strategy Design Pattern) */
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Target", Instanced, meta = (MultiLine = "true"))
|
||||
TObjectPtr<class UUGC_IFocusTargetMethod> GetActorLocationMethod;
|
||||
};
|
||||
|
||||
/*
|
||||
* Dithering settings used to dither/hide/fade objects colliding with the camera either occluding the line of sight to the player or overlapping the camera directly.
|
||||
*/
|
||||
USTRUCT(BlueprintType)
|
||||
struct FCameraDitheringSettings
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
// The name of the scalar material parameter to blend in/out.
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UGC Camera Dithering")
|
||||
FName MaterialOpacityParameterName = "Opacity";
|
||||
|
||||
// Whether the material has a vector parameter which should be updated to the player location.
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UGC Camera Dithering")
|
||||
bool bUpdateMaterialPlayerPosition = false;
|
||||
|
||||
// The name of the vector parameter to set to the player position inside the Material Parameter Collection.
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UGC Camera Dithering", meta = (EditCondition = "bUpdateMaterialPlayerPosition"))
|
||||
FName MaterialPlayerPositionParameterName = "PlayerLocation";
|
||||
|
||||
// The minimum value of the material's Opacity when dithered.
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UGC Camera Dithering", meta = (UIMin = 0.f, UIMax = 1.f, ClampMin = 0.f, ClampMax = 1.f))
|
||||
float MaterialDitherMinimum = 0.1f;
|
||||
|
||||
// Controls the speed of the blend when starting to dither an object.
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UGC Camera Dithering", meta = (UIMin = 0.f, ClampMin = 0.f))
|
||||
float DitherInSpeed = 10.f;
|
||||
|
||||
// Controls the speed of the blend when finishing to dither an object.
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UGC Camera Dithering", meta = (UIMin = 0.f, ClampMin = 0.f))
|
||||
float DitherOutSpeed = 10.f;
|
||||
|
||||
// Actors with this tag will not be dithered even if they overlap DitherLOSChannel and DitherOverlapChannel.
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UGC Camera Dithering")
|
||||
FName IgnoreDitheringTag = "UGC_IgnoreDithering";
|
||||
|
||||
// Whether we should dither the child actors attached to the obstacle.
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UGC Camera Dithering|Collisions")
|
||||
bool bDitherChildActors = true;
|
||||
|
||||
// Whether we should dither the components attached to the obstacle.
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UGC Camera Dithering|Collisions")
|
||||
bool bDitherAttachedComponents = true;
|
||||
|
||||
// Whether we should dither objects that block the LINE OF SIGHT of the camera.
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UGC Camera Dithering|Collisions|Line Of Sight")
|
||||
bool bDitherLineOfSight = false;
|
||||
|
||||
// The collision channel to use when checking for what the LINE OF SIGHT of the camera is colliding with. The other objects have to Overlap this channel in order to be dithered!
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UGC Camera Dithering|Collisions|Line Of Sight", meta = (EditCondition = "bDitherLineOfSight"))
|
||||
TEnumAsByte<ECollisionChannel> DitherLOSChannel = ECC_Camera;
|
||||
|
||||
// The width of the probe when testing if any object is blocking the LINE OF SIGHT from the player to the camera. The other objects have to Overlap this channel in order to be dithered!
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UGC Camera Dithering|Collisions|Line Of Sight", meta = (UIMin = 0.f, ClampMin = 0.f, EditCondition = "bDitherLineOfSight"))
|
||||
float LOSProbeSize = 5.f;
|
||||
|
||||
// The minimum amount of time the camera LINE OF SIGHT has to collide with an object for it to be dithered.
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UGC Camera Dithering|Collisions|Line Of Sight", meta = (UIMin = 0.f, ClampMin = 0.f, EditCondition = "bDitherLineOfSight"))
|
||||
float CollisionTimeThreshold = 0.f;
|
||||
|
||||
// Whether we should dither objects that OVERLAP the actual camera component.
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UGC Camera Dithering|Collisions|Overlaps")
|
||||
bool bDitherOverlaps = true;
|
||||
|
||||
// Whether we should dither the owner character when the actual camera overlaps with them.
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UGC Camera Dithering|Collisions|Overlaps", meta = (EditCondition = "bDitherOverlaps"))
|
||||
bool bDitherOwner = true;
|
||||
|
||||
// The collision channel to use when checking for what the actual camera is overlapping with. The other objects have to Overlap this channel in order to be dithered!
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UGC Camera Dithering|Collisions|Overlaps", meta = (EditCondition = "bDitherOverlaps"))
|
||||
TEnumAsByte<ECollisionChannel> DitherOverlapChannel = ECC_Camera;
|
||||
|
||||
// The radius around the camera where we check for collisions.
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UGC Camera Dithering|Collisions|Overlaps", meta = (UIMin = 0.f, ClampMin = 0.f, EditCondition = "bDitherOverlaps"))
|
||||
float SphereCollisionRadius = 15.f;
|
||||
};
|
||||
|
||||
/**
|
||||
* Struct defining a feeler ray used for camera penetration avoidance. The feeler uses sphere sweeps.
|
||||
*/
|
||||
USTRUCT(BlueprintType)
|
||||
struct FPenetrationAvoidanceFeeler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
FPenetrationAvoidanceFeeler();
|
||||
|
||||
FPenetrationAvoidanceFeeler(const FRotator& InAdjustmentRot, const float& InWorldWeight, const float& InPawnWeight, const float& InExtent);
|
||||
|
||||
// FRotator describing deviance from main ray.
|
||||
UPROPERTY(EditAnywhere, Category = PenetrationAvoidanceFeeler)
|
||||
FRotator AdjustmentRot;
|
||||
|
||||
// How much this feeler affects the final position if it hits the world.
|
||||
UPROPERTY(EditAnywhere, Category = PenetrationAvoidanceFeeler, meta = (UIMin = 0.f, UIMax = 1.f, ClampMin = 0.f, ClampMax = 1.f))
|
||||
float WorldWeight = 0.f;
|
||||
|
||||
// How much this feeler affects the final position if it hits a APawn (setting to 0 will not attempt to collide with pawns at all).
|
||||
UPROPERTY(EditAnywhere, Category = PenetrationAvoidanceFeeler, meta = (UIMin = 0.f, UIMax = 1.f, ClampMin = 0.f, ClampMax = 1.f))
|
||||
float PawnWeight = 0.f;
|
||||
|
||||
// The radius of this feeler probe.
|
||||
UPROPERTY(EditAnywhere, Category = PenetrationAvoidanceFeeler)
|
||||
float ProbeRadius = 5.f;
|
||||
};
|
||||
|
||||
/**
|
||||
* Camera collision settings which define how the camera avoidance uses collision feelers or whiskers to avoid camera clipping through obstacles.
|
||||
*/
|
||||
USTRUCT(BlueprintType)
|
||||
struct FCameraCollisionSettings
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
FCameraCollisionSettings();
|
||||
|
||||
/* The time the camera takes to go to the safe location after a collision has been detected. */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Collision")
|
||||
float PenetrationBlendInTime = 0.05f;
|
||||
|
||||
/* The time the camera takes to go back to its normal position after the collision has finished. */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Collision")
|
||||
float PenetrationBlendOutTime = 0.5f;
|
||||
|
||||
// If true, does collision checks to keep the camera out of the world.
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Collision")
|
||||
bool bPreventPenetration = true;
|
||||
|
||||
// If true, try to detect nearby walls and move the camera in anticipation. Helps prevent popping.
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Collision", meta = (EditCondition = "bPreventPenetration"))
|
||||
bool bDoPredictiveAvoidance = true;
|
||||
|
||||
/**
|
||||
* These are the feeler rays that are used to find where to place the camera.
|
||||
* Index: 0 : This is the normal feeler we use to prevent collisions.
|
||||
* Index: 1+ : These feelers are used if you bDoPredictiveAvoidance=true, to scan for potential impacts if the player
|
||||
* were to rotate towards that direction and primitively collide the camera so that it pulls in before
|
||||
* impacting the occluder.
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Collision")
|
||||
TArray<FPenetrationAvoidanceFeeler> PenetrationAvoidanceFeelers;
|
||||
|
||||
// Actors with this tag will ignore camera collisions.
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Collision")
|
||||
FName IgnoreCameraCollisionTag = "UGC_IgnoreCameraCollision";
|
||||
};
|
||||
|
||||
/**
|
||||
* Camera settings for the spring arm component.
|
||||
*/
|
||||
USTRUCT(BlueprintType)
|
||||
struct FCameraArmLagSettings
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
|
||||
/**
|
||||
* If true, these settings will be used and the settings authored directly in the spring arm will be ignored.
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Lag")
|
||||
bool bOverrideSpringArmComponentSettings = false;
|
||||
|
||||
/**
|
||||
* If true, camera lags behind target position to smooth its movement.
|
||||
* @see CameraLagSpeed
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Lag", meta = (editcondition = "bOverrideSpringArmComponentSettings"))
|
||||
bool bEnableCameraLag = true;
|
||||
|
||||
/**
|
||||
* If true, camera lags behind target rotation to smooth its movement.
|
||||
* @see CameraRotationLagSpeed
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Lag", meta = (editcondition = "bOverrideSpringArmComponentSettings"))
|
||||
bool bEnableCameraRotationLag = false;
|
||||
|
||||
/** If bEnableCameraLag is true, controls how quickly camera reaches target position. Low values are slower (more lag), high values are faster (less lag), while zero is instant (no lag). */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Lag", meta = (editcondition = "bEnableCameraLag && bOverrideSpringArmComponentSettings", ClampMin = "0.0", ClampMax = "1000.0", UIMin = "0.0", UIMax = "1000.0"))
|
||||
float CameraLagSpeed = 8.f;
|
||||
|
||||
/** If bEnableCameraRotationLag is true, controls how quickly camera reaches target position. Low values are slower (more lag), high values are faster (less lag), while zero is instant (no lag). */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Lag", meta = (editcondition = "bEnableCameraRotationLag && bOverrideSpringArmComponentSettings", ClampMin = "0.0", ClampMax = "1000.0", UIMin = "0.0", UIMax = "1000.0"))
|
||||
float CameraRotationLagSpeed = 10.f;
|
||||
|
||||
/** Max distance the camera target may lag behind the current location. If set to zero, no max distance is enforced. */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Lag", meta = (editcondition = "bEnableCameraLag && bOverrideSpringArmComponentSettings", ClampMin = "0.0", UIMin = "0.0"))
|
||||
float CameraLagMaxDistance = 0.f;
|
||||
};
|
||||
|
||||
/**
|
||||
* Generic data class which holds settings for an associated Camera Add-On Modifier.
|
||||
*/
|
||||
UCLASS(abstract, Category = "UGC|Add On|Settings", EditInlineNew, Blueprintable)
|
||||
class AURORADEVS_UGC_API UUGC_CameraAddOnModifierSettings : public UObject
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
};
|
||||
|
||||
/** Camera Data Asset holding all of the camera settings. */
|
||||
UCLASS(Blueprintable, BlueprintType)
|
||||
class UUGC_CameraDataAssetBase : public UPrimaryDataAsset
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
/**
|
||||
* The settings of the camera Arm Length. Defines the range of the Arm Length and how to blend from one range to this one. This is used by the PitchToArmLengthAndFOV Camera Modifier in blueprint.
|
||||
* This makes the Arm Length change when the character is looking up/down (Used by many AAA games like all GTA games, Red Dead Redemption Assassin's Creed, Hogwarts Legacy, etc.).
|
||||
*/
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera Arm")
|
||||
FCameraArmLengthSettings ArmLengthSettings;
|
||||
|
||||
/**
|
||||
* The settings of the camera FOV. Defines the range of the FOV and how to blend from one range to this one. This is used by the PitchToArmLengthAndFOV Camera Modifier in blueprint.
|
||||
* This makes the FOV change when the character is looking up/down (Used by many AAA games like GTA IV).
|
||||
*/
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera FOV")
|
||||
FCameraFOVSettings FOVSettings;
|
||||
|
||||
/** Camera collision settings which define how the camera avoidance uses collision feelers or whiskers to avoid camera clipping through obstacles. */
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "CameraCollisions")
|
||||
FCameraCollisionSettings CollisionSettings;
|
||||
|
||||
/** Dithering settings used to dither/hide/fade objects colliding with the camera either occluding the line of sight to the player or overlapping the camera directly. */
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera Dithering")
|
||||
FCameraDitheringSettings DitheringSettings;
|
||||
|
||||
/**
|
||||
* The settings of the camera pitch follow. This is useful for player who don't like to control the camera too much.
|
||||
* The PitchFollowModifier in blueprint will adjust the pitch to face slopes, falling and reset the pitch if it's left untouched for long enough.
|
||||
* (Used by AAA games like Red Dead Redemption, Hogwarts Legacy, Witcher, etc)
|
||||
*/
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera Movement Follow|Pitch")
|
||||
FCameraPitchFollowSettings PitchFollowSettings;
|
||||
|
||||
/**
|
||||
* The settings of the camera yaw follow. This is useful for player who don't like to control the camera too much.
|
||||
* The YawFollowModifier in blueprint will adjust the yaw to face the movement direction (Used by AAA games like Hogwarts Legacy, Witcher, etc).
|
||||
*/
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera Movement Follow|Yaw")
|
||||
FCameraYawFollowSettings YawFollowSettings;
|
||||
|
||||
/** The settings of the camera Spring Arm Offset. Offset at the end of the spring arm. Use this instead of the relative world location so that the UE camera system works as exptected */
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera Arm")
|
||||
FCameraArmOffsetSettings ArmOffsetSettings;
|
||||
|
||||
/**
|
||||
* The settings of the camera pitch contraints. This is useful to limit how much the character can look up/down. AAA games usually do not allow the entire 180 degrees range.
|
||||
* The looking input action needs to have a UGC_CameraSlowDownInputModifier for the camera to decelerate when close to the constraints.
|
||||
*/
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera Angle Constraints")
|
||||
FCameraPitchConstraintSettings PitchConstraints;
|
||||
|
||||
/**
|
||||
* The settings of the camera yaw contraints. This is useful to limit how much the character can look left/right.
|
||||
* The looking input action needs to have a UGC_CameraSlowDownInputModifier for the camera to decelerate when close to the constraints.
|
||||
*/
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Camera Angle Constraints")
|
||||
FCameraYawConstraintSettings YawConstraints;
|
||||
|
||||
/**
|
||||
* The settings of the focus camera. This is used for hard-lock in games.
|
||||
* Has a function which retrieves the target we want the camera to look at. (Uses the Strategy Design Pattern)
|
||||
*/
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "CameraFocus")
|
||||
FUGCCameraFocusSettings FocusSettings;
|
||||
|
||||
/** This makes the Arm Length and FOV change when the character is looking up/down (Used by many AAA games like all GTA games, Red Dead Redemption Assassin's Creed, Hogwarts Legacy, etc.). */
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "PitchToArmLengthAndFOVCurv")
|
||||
FCameraPitchToArmAndFOVCurveSettings PitchToArmAndFOVCurveSettings;
|
||||
|
||||
/** Arm lag settings of the camera. Need to be enabled by checking `bOverrideSpringArmComponentSettings`, otherwise the settings of the component are used instead. **/
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Camera Arm")
|
||||
FCameraArmLagSettings ArmLagSettings;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "Add Ons", Instanced, meta = (MultiLine = "true"))
|
||||
TArray<TObjectPtr<UUGC_CameraAddOnModifierSettings>> AddOnsSettings;
|
||||
};
|
||||
@@ -0,0 +1,32 @@
|
||||
// Copyright(c) Aurora Devs 2022-2025. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GameFramework/Actor.h"
|
||||
#include "UObject/WeakObjectPtrTemplates.h"
|
||||
|
||||
#include "UGC_IFocusTargetMethod.generated.h"
|
||||
|
||||
/**
|
||||
* Function which retrieves the target we want the camera to look at. (Uses the Strategy Design Pattern)
|
||||
*/
|
||||
UCLASS(abstract, Category = "UGC|Methods", EditInlineNew, Blueprintable)
|
||||
class AURORADEVS_UGC_API UUGC_IFocusTargetMethod : public UObject
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
/*
|
||||
* Get the location of the target we want the camera to look at.
|
||||
* @param Owner The owner of the camera.
|
||||
* @param OwnerLocation The world location of the owner of camera.
|
||||
* @param ViewPointLocation Camera's location.
|
||||
* @param ViewPointRotation Camera's rotation.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, BlueprintNativeEvent, Category = "UGC|Methods")
|
||||
AActor* GetTargetLocation(class AActor* InOwner, FVector OwnerLocation, FVector ViewPointLocation, FRotator ViewPointRotation, FVector& OutTargetLocation);
|
||||
|
||||
private:
|
||||
/** Getter for the cached world pointer, will return null if the actor is not actually spawned in a level */
|
||||
virtual UWorld* GetWorld() const override;
|
||||
};
|
||||
@@ -0,0 +1,32 @@
|
||||
// Copyright(c) Aurora Devs 2022-2025. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GameFramework/Actor.h"
|
||||
#include "UObject/WeakObjectPtrTemplates.h"
|
||||
|
||||
#include "UGC_IGetActorsMethod.generated.h"
|
||||
|
||||
/**
|
||||
* Function which retrieves a vector of actors. (Uses the Strategy Design Pattern)
|
||||
*/
|
||||
UCLASS(abstract, Category = "UGC|Methods", EditInlineNew, Blueprintable)
|
||||
class AURORADEVS_UGC_API UUGC_IGetActorsMethod : public UObject
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
/*
|
||||
* Get the all actors relevant for this method.
|
||||
* @param Owner The owner of the camera.
|
||||
* @param OwnerLocation The world location of the owner of camera.
|
||||
* @param ViewPointLocation Camera's location.
|
||||
* @param ViewPointRotation Camera's rotation.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, BlueprintNativeEvent, Category = "UGC|Methods")
|
||||
void GetActors(class AActor* InOwner, FVector OwnerLocation, FVector ViewPointLocation, FRotator ViewPointRotation, TArray<AActor*>& OutActors);
|
||||
|
||||
private:
|
||||
/** Getter for the cached world pointer, will return null if the actor is not actually spawned in a level */
|
||||
virtual UWorld* GetWorld() const override;
|
||||
};
|
||||
@@ -0,0 +1,131 @@
|
||||
// Copyright(c) Aurora Devs 2022-2025. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "CameraAnimationCameraModifier.h"
|
||||
#include "DrawDebugHelpers.h"
|
||||
#include "UGC_CameraAnimationModifier.generated.h"
|
||||
|
||||
/**
|
||||
* Delegate for when a UGC Camera Animation is completed, whether the animation has been interrupted or finished.
|
||||
*
|
||||
* bInterrupted = true if it was not property finished
|
||||
*/
|
||||
DECLARE_DELEGATE_TwoParams(FOnCameraAnimationEnded, class UCameraAnimationSequence*, bool /*bInterrupted*/)
|
||||
|
||||
/**
|
||||
* Delegate for when a UGC Camera Animation started easing out, whether the animation has actually been interrupted or not.
|
||||
*
|
||||
* bInterrupted = true if it was not property finished
|
||||
*/
|
||||
DECLARE_DELEGATE_OneParam(FOnCameraAnimationEaseOutStarted, class UCameraAnimationSequence*)
|
||||
|
||||
UENUM()
|
||||
enum class ECameraAnimationResetType : uint8
|
||||
{
|
||||
BackToStart UMETA(ToolTip = "The camera will go back to the position it started from."),
|
||||
ResetToZero UMETA(ToolTip = "The camera's orientation will be reset to zero. This is usually the back of the character. If UseControllerRotationYaw is true, this is forcefully used."),
|
||||
ContinueFromEnd UMETA(ToolTip = "The camera will blend out from the last position of the animation.")
|
||||
};
|
||||
|
||||
USTRUCT()
|
||||
struct FUGCActiveAnimationInfo
|
||||
{
|
||||
GENERATED_USTRUCT_BODY()
|
||||
|
||||
ECameraAnimationResetType ResetType = ECameraAnimationResetType::ResetToZero;
|
||||
/** Runtime interpolated distance percentage (0 = fully blocked, 1 = clear) */
|
||||
float DistBlockedPct = 1.f;
|
||||
bool bDoCollisionChecks = false;
|
||||
bool bWasEasingOut = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gameplay Camera Animation Modifier which plays in the correct transform space in rgeards to the owning player.
|
||||
*/
|
||||
UCLASS(abstract, ClassGroup = "UGC Camera Modifiers")
|
||||
class AURORADEVS_UGC_API UUGC_CameraAnimationModifier : public UCameraAnimationCameraModifier
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
// UCameraModifier interface
|
||||
virtual bool ModifyCamera(float DeltaTime, FMinimalViewInfo& InOutPOV) override;
|
||||
|
||||
void CameraAnimation_SetEasingOutDelegate(FOnCameraAnimationEaseOutStarted& InOnAnimationEaseOutStarted, FCameraAnimationHandle AnimationHandle);
|
||||
void CameraAnimation_SetEndedDelegate(FOnCameraAnimationEnded& InOnAnimationEnded, FCameraAnimationHandle AnimationHandle);
|
||||
|
||||
FCameraAnimationHandle PlaySingleCameraAnimation(UCameraAnimationSequence* Sequence, FCameraAnimationParams Params, ECameraAnimationResetType ResetType, bool bInterruptOthers, bool bDoCollisionChecks);
|
||||
|
||||
/**
|
||||
* Stops the given camera animation sequence. If nullptr, will stop whatever is currently active.
|
||||
* @param Sequence The camera sequence animation.
|
||||
* @param bImmediate True to stop it right now and ignore blend out, false to let it blend out as indicated.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = "UGC|Modifiers|Camera Animation")
|
||||
void StopCameraAnimationSequence(UCameraAnimationSequence* Sequence, bool bImmediate = false);
|
||||
|
||||
/**
|
||||
* Get the current camera animation playing on this modifier.
|
||||
* @return The current camera animation playing.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = "UGC|Modifiers|Camera Animations")
|
||||
void GetCurrentCameraAnimations(TArray<UCameraAnimationSequence*>& OutAnimations) const;
|
||||
|
||||
/**
|
||||
* Returns whether the given camera animation is playing on this modifier.
|
||||
* @param Sequence The Camera Animation Sequence.
|
||||
* @return Whether the corresponding camera animation is playing or not.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = "UGC|Modifiers|Camera Animations")
|
||||
bool IsCameraAnimationSequenceActive(UCameraAnimationSequence* Sequence) const;
|
||||
|
||||
/**
|
||||
* Returns whether any camera animation is playing on this modifier.
|
||||
* @param Sequence The Camera Animation Sequence.
|
||||
* @return Whether any camera animation is playing or not.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = "UGC|Modifiers|Camera Animations")
|
||||
bool IsAnyCameraAnimationSequence() const;
|
||||
|
||||
protected:
|
||||
void UGCDeactivateCameraAnimation(FActiveCameraAnimationInfo& ActiveAnimation);
|
||||
|
||||
// UCameraAnimationCameraModifier interface
|
||||
virtual void UGCTickActiveAnimation(float DeltaTime, FMinimalViewInfo& InOutPOV);
|
||||
|
||||
// UCameraAnimationCameraModifier interface
|
||||
virtual void UGCTickAnimation(FActiveCameraAnimationInfo& CameraAnimation, float DeltaTime, FMinimalViewInfo& InOutPOV, int Index);
|
||||
virtual void UGCTickAnimCollision(FActiveCameraAnimationInfo& CameraAnimation, float DeltaTime, FMinimalViewInfo& InOutPOV, int Index);
|
||||
|
||||
FVector GetTraceSafeLocation(FMinimalViewInfo const& InPOV);
|
||||
|
||||
template<typename T>
|
||||
T* GetViewTargetAs() const
|
||||
{
|
||||
return Cast<T>(GetViewTarget());
|
||||
}
|
||||
|
||||
private:
|
||||
#if ENABLE_DRAW_DEBUG
|
||||
void UGCDebugAnimation(FActiveCameraAnimationInfo& ActiveAnimation, float DeltaTime);
|
||||
#endif
|
||||
|
||||
private:
|
||||
UPROPERTY(Transient)
|
||||
TObjectPtr<class AUGC_PlayerCameraManager> UGCCameraManager = nullptr;
|
||||
UPROPERTY(Transient)
|
||||
TObjectPtr<class UUGC_CameraCollisionModifier> CollisionModifier = nullptr;
|
||||
|
||||
/** How should the camera behave after the current animation is over. */
|
||||
UPROPERTY(Transient)
|
||||
TArray<FUGCActiveAnimationInfo> UGCAnimInfo;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
int LastIndex = 0;
|
||||
|
||||
// Delegates
|
||||
FOnCameraAnimationEnded OnAnimationEnded;
|
||||
FOnCameraAnimationEaseOutStarted OnAnimationEaseOutStarted;
|
||||
};
|
||||
@@ -0,0 +1,63 @@
|
||||
// Copyright(c) Aurora Devs 2022-2025. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
|
||||
#include "UGC_CameraModifier.h"
|
||||
#include "Camera/Data/UGC_CameraData.h"
|
||||
#include "Camera/CameraTypes.h"
|
||||
#include "DrawDebugHelpers.h"
|
||||
#include "Containers/StaticBitArray.h"
|
||||
#include "UGC_CameraCollisionModifier.generated.h"
|
||||
|
||||
/**
|
||||
* DEPRECATED. USE UGC_SpringArmComponent INSTEAD.
|
||||
* Camera Modifier which does camera avoidance using predictive collision feelers.
|
||||
*/
|
||||
UCLASS(abstract, ClassGroup = "UGC Camera Modifiers", meta = (Deprecated = 5.5))
|
||||
class AURORADEVS_UGC_API UUGC_CameraCollisionModifier : public UUGC_CameraModifier
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UUGC_CameraCollisionModifier();
|
||||
|
||||
public:
|
||||
// Force collision modifier to use a single ray by another modifier. Do not use this if you're not familiar with it.
|
||||
UFUNCTION(BlueprintCallable, Category = "UGC|Modifiers|Collision")
|
||||
void AddSingleRayOverrider(UCameraModifier const* OverridingModifier) { if (OverridingModifier) SingleRayOverriders.AddUnique(OverridingModifier); }
|
||||
|
||||
// Remove single ray modifier override. Do not use this if you're not familiar with it.
|
||||
UFUNCTION(BlueprintCallable, Category = "UGC|Modifiers|Collision")
|
||||
void RemoveSingleRayOverrider(UCameraModifier const* OverridingModifier) { if (OverridingModifier) SingleRayOverriders.Remove(OverridingModifier); }
|
||||
|
||||
protected:
|
||||
virtual bool ModifyCamera(float DeltaTime, FMinimalViewInfo& InOutPOV) override;
|
||||
|
||||
void UpdatePreventPenetration(float DeltaTime, FMinimalViewInfo& InOutPOV);
|
||||
|
||||
void PreventCameraPenetration(class AActor const& ViewTarget, FVector const& SafeLoc, FVector& OutCameraLoc, float const& DeltaTime, float& OutDistBlockedPct, bool bSingleRayOnly);
|
||||
|
||||
FVector GetTraceSafeLocation(FMinimalViewInfo const& POV);
|
||||
|
||||
void ResetSingleRayOverriders() { SingleRayOverriders.Reset(); }
|
||||
|
||||
public:
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UGC|Modifiers|Collision")
|
||||
FCameraCollisionSettings CollisionSettings;
|
||||
|
||||
// If you don't want the camera to start close to the character and smoothly pan out once your character is spawned, default-initialize this variable to 1.f.
|
||||
UPROPERTY(Transient)
|
||||
float AimLineToDesiredPosBlockedPct = 1.f;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
TArray<TObjectPtr<const AActor>> DebugActorsHitDuringCameraPenetration;
|
||||
|
||||
protected:
|
||||
TArray<UCameraModifier const*> SingleRayOverriders;
|
||||
TStaticBitArray<128u> CollidingFeelers;
|
||||
|
||||
#if ENABLE_DRAW_DEBUG
|
||||
mutable float LastDrawDebugTime = -MAX_FLT;
|
||||
#endif
|
||||
};
|
||||
@@ -0,0 +1,93 @@
|
||||
// Copyright(c) Aurora Devs 2022-2025. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Camera/Modifiers/UGC_CameraModifier.h"
|
||||
#include "Camera/Data/UGC_CameraData.h"
|
||||
#include "DrawDebugHelpers.h"
|
||||
#include "UGC_CameraDitheringModifier.generated.h"
|
||||
|
||||
UENUM()
|
||||
enum class EDitherType : uint8
|
||||
{
|
||||
None,
|
||||
BlockingLOS,
|
||||
OverlappingCamera
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FDitheredActorState
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UGC|Modifiers|Camera Dithering")
|
||||
TObjectPtr<AActor> Actor;
|
||||
|
||||
UPROPERTY(VisibleInstanceOnly, BlueprintReadWrite, Category = "UGC|Modifiers|Camera Dithering")
|
||||
float CurrentOpacity = 1.f;
|
||||
|
||||
UPROPERTY(VisibleInstanceOnly, BlueprintReadWrite, Category = "UGC|Modifiers|Camera Dithering")
|
||||
float CollisionTime = 0.f;
|
||||
|
||||
UPROPERTY(VisibleInstanceOnly, BlueprintReadWrite, Category = "UGC|Modifiers|Camera Dithering")
|
||||
bool bIsDitheringIn = false;
|
||||
|
||||
UPROPERTY(VisibleInstanceOnly, BlueprintReadWrite, Category = "UGC|Modifiers|Camera Dithering")
|
||||
bool bIsDitheringOut = false;
|
||||
|
||||
UPROPERTY(VisibleInstanceOnly, BlueprintReadWrite, Category = "UGC|Modifiers|Camera Dithering")
|
||||
EDitherType DitherType = EDitherType::None;
|
||||
|
||||
bool IsValid() const { return Actor != nullptr && DitherType != EDitherType::None; }
|
||||
|
||||
void StartDithering(AActor* InActor, EDitherType InDitherType);
|
||||
|
||||
void Invalidate();
|
||||
|
||||
friend bool operator==(FDitheredActorState const& lhs, FDitheredActorState const& rhs)
|
||||
{
|
||||
return lhs.Actor == rhs.Actor;
|
||||
}
|
||||
|
||||
void ComputeOpacity(float DeltaTime, float DitherInTime, float DitherOutTime, float DitherMin);
|
||||
};
|
||||
|
||||
/**
|
||||
* UGC Camera Modifier used to dither objects colliding with the camera
|
||||
*/
|
||||
UCLASS()
|
||||
class AURORADEVS_UGC_API UUGC_CameraDitheringModifier : public UUGC_CameraModifier
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UUGC_CameraDitheringModifier();
|
||||
|
||||
UFUNCTION(BlueprintCallable, BlueprintNativeEvent, Category = "UGC|Modifiers|Dithering")
|
||||
void ResetDitheredActors();
|
||||
|
||||
protected:
|
||||
virtual bool ModifyCamera(float DeltaTime, FMinimalViewInfo& InOutPOV) override;
|
||||
|
||||
virtual void ApplyDithering(float DeltaTime, FDitheredActorState& DitherState);
|
||||
|
||||
private:
|
||||
#if ENABLE_DRAW_DEBUG
|
||||
void UGCDebugDithering(FDitheredActorState& DitherState, float DeltaTime, float DitherMin);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UGC|Modifiers|Dithering")
|
||||
FCameraDitheringSettings DitheringSettings;
|
||||
|
||||
/** Material Parameter Collection for everything dithering-related */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UGC|Modifiers|Dithering")
|
||||
TSoftObjectPtr<class UMaterialParameterCollection> DitheringMPC;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
TSoftObjectPtr<class UMaterialParameterCollectionInstance> DitheringMPCInstance;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
TArray<FDitheredActorState> DitheredActorStates;
|
||||
};
|
||||
@@ -0,0 +1,233 @@
|
||||
// Copyright(c) Aurora Devs 2022-2025. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Camera/CameraModifier.h"
|
||||
#include "UGC_CameraModifier.generated.h"
|
||||
|
||||
/**
|
||||
* Base Camera Modifier Class
|
||||
*/
|
||||
UCLASS(abstract, ClassGroup = "UGC|Camera Modifiers")
|
||||
class AURORADEVS_UGC_API UUGC_CameraModifier : public UCameraModifier
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
virtual void EnableModifier() override;
|
||||
virtual void DisableModifier(bool bImmediate) override;
|
||||
bool GetDebugEnabled() const { return bDebug; }
|
||||
|
||||
/**
|
||||
* Function called once this modifier gets enabled.
|
||||
* @param LastPOV - the last view POV of the camera.
|
||||
*/
|
||||
UFUNCTION(BlueprintNativeEvent, Category = "UGC|Camera Modifier")
|
||||
void OnModifierEnabled(FMinimalViewInfo const& LastPOV);
|
||||
|
||||
/**
|
||||
* Function called once this modifier gets disabled.
|
||||
* @param bWasImmediate - true if modifier was disabled without a blend out.
|
||||
* @param LastPOV - the last view POV of the camera.
|
||||
*/
|
||||
UFUNCTION(BlueprintNativeEvent, Category = "UGC|Camera Modifier")
|
||||
void OnModifierDisabled(FMinimalViewInfo const& LastPOV, bool bWasImmediate);
|
||||
|
||||
/**
|
||||
* Called to give modifiers a chance to adjust view rotation updates before they are applied.
|
||||
*
|
||||
* Default just returns ViewRotation unchanged
|
||||
* @param ViewTarget - Current view target.
|
||||
* @param InLocalControlRotation - The difference between the actor rotation and the control rotation.
|
||||
* @param DeltaTime - Frame time in seconds.
|
||||
* @param InViewLocation - In. The view location of the camera.
|
||||
* @param InViewRotation - In. The view rotation of the camera.
|
||||
* @param InDeltaRot - In/out. How much the rotation changed this frame.
|
||||
* @param OutDeltaRot - Out. How much the control rotation should change this frame.
|
||||
* @return Return true to prevent subsequent (lower priority) modifiers to further adjust rotation, false otherwise.
|
||||
*/
|
||||
UFUNCTION(BlueprintNativeEvent, Category = "UGC|Camera Modifier")
|
||||
bool ProcessControlRotation(AActor* ViewTarget, float DeltaTime, FVector InViewLocation, FRotator InViewRotation, FRotator InLocalControlRotation, FRotator InDeltaRot, FRotator& OutDeltaRot);
|
||||
|
||||
/**
|
||||
* Called to give modifiers a chance to adjust arm length and FOV before they are applied.
|
||||
*
|
||||
* @param DeltaTime - Frame time in seconds.
|
||||
* @param InFOV - The Current FOV of the camera.
|
||||
* @param InArmLength - The Current Arm Length of the camera.
|
||||
* @param ViewLocation - The view location of the camera.
|
||||
* @param ViewRotation - The view rotation of the camera.
|
||||
* @param OutFOV - The New FOV of the camera.
|
||||
* @param OutArmLength - The New Arm Length of the camera.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, BlueprintNativeEvent, Category = "UGC|Camera Modifier")
|
||||
void ProcessBoomLengthAndFOV(float DeltaTime, float InFOV, float InArmLength, FVector ViewLocation, FRotator ViewRotation, float& OutFOV, float& OutArmLength);
|
||||
|
||||
/**
|
||||
* Called to give modifiers a chance to adjust arm offsets before they are applied.
|
||||
*
|
||||
* @param DeltaTime - Frame time in seconds.
|
||||
* @param InSocketOffset - The Current Socket Offset of the camera.
|
||||
* @param InTargetOffset - The Current Target Offset of the camera.
|
||||
* @param ViewLocation - The view location of the camera.
|
||||
* @param ViewRotation - The view rotation of the camera.
|
||||
* @param OutSocketOffset - New Socket Offset of the camera.
|
||||
* @param OutTargetOffset - New Target Offset of the camera.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, BlueprintNativeEvent, Category = "UGC|Camera Modifier")
|
||||
void ProcessBoomOffsets(float DeltaTime, FVector InSocketOffset, FVector InTargetOffset, FVector ViewLocation, FRotator ViewRotation, FVector& OutSocketOffset, FVector& OutTargetOffset);
|
||||
|
||||
/**
|
||||
* Called to give modifiers a chance to adjust miscelaneous stuff at the end of the update order.
|
||||
*
|
||||
* @param DeltaTime - Frame time in seconds.
|
||||
* @param ViewLocation - The view location of the camera.
|
||||
* @param ViewRotation - The view rotation of the camera.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, BlueprintNativeEvent, Category = "UGC|Camera Modifier")
|
||||
void PostUpdate(float DeltaTime, FVector ViewLocation, FRotator ViewRotation);
|
||||
|
||||
UFUNCTION(BlueprintNativeEvent, Category = "UGC|Camera Modifier")
|
||||
void OnAnyLevelSequenceStarted();
|
||||
|
||||
UFUNCTION(BlueprintNativeEvent, Category = "UGC|Camera Modifier")
|
||||
void OnAnyLevelSequenceEnded();
|
||||
|
||||
UFUNCTION(BlueprintNativeEvent, Category = "UGC|Camera Modifier")
|
||||
void OnSetViewTarget(bool bImmediate, bool bNewTargetIsOwner);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "UGC|Camera Modifier")
|
||||
bool IsDebugEnabled() const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "UGC|Camera Modifier")
|
||||
void ToggleDebug(bool const bEnabled);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "UGC|Camera Modifier")
|
||||
void SetAlpha(float InAlpha) { Alpha = InAlpha; }
|
||||
|
||||
/**
|
||||
* Called to give modifiers a chance to adjust both the yaw turn rate and pitch turn rate. However the input for looking needs to have UGC_CameraTurnRateModifier.
|
||||
*
|
||||
* @param DeltaTime - Frame time in seconds.
|
||||
* @param InLocalControlRotation - The difference between the actor rotation and the control rotation.
|
||||
* @param OutPitchTurnRate - Out. New value of the pitch turn rate (between 0 and 1).
|
||||
* @param OutYawTurnRate - Out. New value of the yaw turn rate (between 0 and 1).
|
||||
* @return Return true to prevent subsequent (lower priority) modifiers to further adjust rotation, false otherwise.
|
||||
*/
|
||||
UFUNCTION(BlueprintNativeEvent, Category = "UGC|Camera Modifier")
|
||||
bool ProcessTurnRate(float DeltaTime, FRotator InLocalControlRotation, float InPitchTurnRate, float InYawTurnRate, float& OutPitchTurnRate, float& OutYawTurnRate);
|
||||
|
||||
bool CanPlayDuringCameraAnimation() const { return bPlayDuringCameraAnimations; }
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "UGC|Camera Modifier|Movement")
|
||||
FVector GetOwnerVelocity() const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "UGC|Camera Modifier|Movement")
|
||||
bool IsOwnerFalling() const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "UGC|Camera Modifier|Movement")
|
||||
bool IsOwnerStrafing() const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "UGC|Camera Modifier|Movement")
|
||||
bool IsOwnerMovingOnGround() const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "UGC|Camera Modifier|Movement")
|
||||
void ComputeOwnerFloorDistance(float SweepDistance, float CapsuleRadius, bool& bOutFloorExists, float& OutFloorDistance) const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "UGC|Camera Modifier|Movement")
|
||||
void ComputeOwnerFloorNormal(float SweepDistance, float CapsuleRadius, bool& bOutFloorExists, FVector& OutFloorNormal) const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "UGC|Camera Modifier|Movement")
|
||||
void ComputeOwnerSlopeAngle(float& OutSlopePitchDegrees, float& OutSlopeRollDegrees);
|
||||
|
||||
/*
|
||||
* Returns value betwen 1 (the character is looking where they're moving) or -1 (looking in the opposite direction they're moving).
|
||||
* Will return 0 if the character isn't moving.
|
||||
*/
|
||||
UFUNCTION(BlueprintPure, Category = "UGC|Camera Modifier|Movement")
|
||||
float ComputeOwnerLookAndMovementDot();
|
||||
|
||||
protected:
|
||||
virtual bool ModifyCamera(float DeltaTime, FMinimalViewInfo& InOutPOV) override;
|
||||
virtual void ModifyCamera(float DeltaTime, FVector ViewLocation, FRotator ViewRotation, float FOV, FVector& OutViewLocation, FRotator& OutViewRotation, float& OutFOV) override;
|
||||
virtual bool ProcessViewRotation(AActor* ViewTarget, float DeltaTime, FRotator& OutViewRotation, FRotator& OutDeltaRot) override;
|
||||
|
||||
template<typename T>
|
||||
T* GetViewTargetAs() const { return Cast<T>(GetViewTarget()); }
|
||||
|
||||
void UpdateOwnerReferences();
|
||||
|
||||
void UpdateInternalVariables(float DeltaTime);
|
||||
|
||||
protected:
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Modifier Settings")
|
||||
bool bPlayDuringCameraAnimations = false;
|
||||
|
||||
UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "UGC|Camera Modifier|Internal")
|
||||
TObjectPtr<class AUGC_PlayerCameraManager> UGCCameraManager = nullptr;
|
||||
|
||||
UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "UGC|Camera Modifier|Internal")
|
||||
TObjectPtr<class APlayerController> OwnerController = nullptr;
|
||||
|
||||
UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "UGC|Camera Modifier|Internal")
|
||||
TObjectPtr<class ACharacter> OwnerCharacter = nullptr;
|
||||
|
||||
UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "UGC|Camera Modifier|Internal")
|
||||
TObjectPtr<class APawn> OwnerPawn = nullptr;
|
||||
|
||||
UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "UGC|Camera Modifier|Internal")
|
||||
TObjectPtr<class USpringArmComponent> SpringArm = nullptr;
|
||||
|
||||
UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "UGC|Camera Modifier|Internal")
|
||||
TObjectPtr<class UCharacterMovementComponent> MovementComponent = nullptr;
|
||||
|
||||
UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "UGC|Camera Modifier|Internal")
|
||||
FVector CurrentSocketOffset;
|
||||
|
||||
UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "UGC|Camera Modifier|Internal")
|
||||
FVector CurrentTargetOffset;
|
||||
|
||||
UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "UGC|Camera Modifier|Internal")
|
||||
float CurrentArmLength;
|
||||
|
||||
UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "UGC|Camera Modifier|Internal")
|
||||
bool bHasMovementInput;
|
||||
|
||||
UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "UGC|Camera Modifier|Internal")
|
||||
FVector PreviousMovementInput;
|
||||
|
||||
UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "UGC|Camera Modifier|Internal")
|
||||
FVector MovementInput;
|
||||
|
||||
UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "UGC|Camera Modifier|Internal")
|
||||
float TimeSinceMovementInput;
|
||||
|
||||
UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "UGC|Camera Modifier|Internal")
|
||||
bool bHasRotationInput;
|
||||
|
||||
UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "UGC|Camera Modifier|Internal")
|
||||
FRotator RotationInput;
|
||||
|
||||
UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "UGC|Camera Modifier|Internal")
|
||||
float TimeSinceRotationInput;
|
||||
};
|
||||
|
||||
/**
|
||||
* Base Camera Modifier Class for Add-on modifiers
|
||||
*/
|
||||
UCLASS(abstract, ClassGroup = "UGC|Add On|Camera Modifiers")
|
||||
class AURORADEVS_UGC_API UUGC_CameraAddOnModifier : public UUGC_CameraModifier
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "UGC|Add On|Camera Modifiers")
|
||||
void SetSettings(class UUGC_CameraAddOnModifierSettings* InSettings);
|
||||
|
||||
// Add-On Settings class associated to this add-on modifier.
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Settings")
|
||||
TSubclassOf<class UUGC_CameraAddOnModifierSettings> SettingsClass;
|
||||
|
||||
UPROPERTY(VisibleInstanceOnly, BlueprintReadWrite, Category = "Settings")
|
||||
TObjectPtr<UUGC_CameraAddOnModifierSettings> Settings;
|
||||
};
|
||||
@@ -0,0 +1,86 @@
|
||||
// Copyright(c) Aurora Devs 2022-2025. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Camera/Modifiers/UGC_CameraModifier.h"
|
||||
#include "Misc/Build.h"
|
||||
#include "Misc/Guid.h"
|
||||
#include "UGC_CameraPropertyRequestStackHelper.h"
|
||||
#include "UGC_CameraPropertiesAnimNotifyModifiers.generated.h"
|
||||
|
||||
/**
|
||||
* Camera Modifier in charge of handling FOV change requests from Anim Notifies.
|
||||
*/
|
||||
UCLASS(abstract, ClassGroup = "UGC Camera Modifiers")
|
||||
class AURORADEVS_UGC_API UUGC_FOVAnimNotifyCameraModifier : public UUGC_CameraModifier
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UUGC_FOVAnimNotifyCameraModifier();
|
||||
|
||||
protected:
|
||||
void PushFOVAnimNotifyRequest(FGuid RequestId, float TargetFOV, float TotalDuration, float BlendInDuration, UCurveFloat* BlendInCurve, float BlendOutDuration, UCurveFloat* BlendOutCurve);
|
||||
void PopFOVAnimNotifyRequest(FGuid RequestId);
|
||||
|
||||
protected:
|
||||
void ProcessBoomLengthAndFOV_Implementation(float DeltaTime, float InFOV, float InArmLength, FVector ViewLocation, FRotator ViewRotation, float& OutFOV, float& OutArmLength) override;
|
||||
void OnModifierDisabled_Implementation(FMinimalViewInfo const& LastPOV, bool bWasImmediate);
|
||||
|
||||
protected:
|
||||
friend class UUGC_FOVRequestAnimNotifyState;
|
||||
UGC_CameraPropertyRequestStackHelper<float> RequestHelper;
|
||||
};
|
||||
|
||||
/**
|
||||
* Camera Modifier in charge of handling Arm Offset changes requests from Anim Notifies.
|
||||
*/
|
||||
UCLASS(abstract, ClassGroup = "UGC Camera Modifiers")
|
||||
class AURORADEVS_UGC_API UUGC_ArmOffsetAnimNotifyCameraModifier : public UUGC_CameraModifier
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UUGC_ArmOffsetAnimNotifyCameraModifier();
|
||||
|
||||
protected:
|
||||
void PushArmSocketOffsetAnimNotifyRequest(FGuid RequestId, FVector TargetOffset, float TotalDuration, float BlendInDuration, UCurveFloat* BlendInCurve, float BlendOutDuration, UCurveFloat* BlendOutCurve);
|
||||
void PopArmSocketOffsetAnimNotifyRequest(FGuid RequestId);
|
||||
|
||||
void PushArmTargetOffsetAnimNotifyRequest(FGuid RequestId, FVector TargetOffset, float TotalDuration, float BlendInDuration, UCurveFloat* BlendInCurve, float BlendOutDuration, UCurveFloat* BlendOutCurve);
|
||||
void PopArmTargetOffsetAnimNotifyRequest(FGuid RequestId);
|
||||
|
||||
protected:
|
||||
void ProcessBoomOffsets_Implementation(float DeltaTime, FVector InSocketOffset, FVector InTargetOffset, FVector ViewLocation, FRotator ViewRotation, FVector& OutSocketOffset, FVector& OutTargetOffset) override;
|
||||
void OnModifierDisabled_Implementation(FMinimalViewInfo const& LastPOV, bool bWasImmediate);
|
||||
|
||||
protected:
|
||||
friend class UUGC_ArmOffsetRequestAnimNotifyState;
|
||||
UGC_CameraPropertyRequestStackHelper<FVector> SocketOffsetRequestHelper;
|
||||
UGC_CameraPropertyRequestStackHelper<FVector> TargetOffsetRequestHelper;
|
||||
};
|
||||
|
||||
/**
|
||||
* Camera Modifier in charge of handling Arm Length changes requests from Anim Notifies.
|
||||
*/
|
||||
UCLASS(abstract, ClassGroup = "UGC Camera Modifiers")
|
||||
class AURORADEVS_UGC_API UUGC_ArmLengthAnimNotifyCameraModifier : public UUGC_CameraModifier
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UUGC_ArmLengthAnimNotifyCameraModifier();
|
||||
|
||||
protected:
|
||||
void PushArmLengthAnimNotifyRequest(FGuid RequestId, float TargetLength, float TotalDuration, float BlendInDuration, UCurveFloat* BlendInCurve, float BlendOutDuration, UCurveFloat* BlendOutCurve);
|
||||
void PopArmLengthAnimNotifyRequest(FGuid RequestId);
|
||||
|
||||
protected:
|
||||
void ProcessBoomLengthAndFOV_Implementation(float DeltaTime, float InFOV, float InArmLength, FVector ViewLocation, FRotator ViewRotation, float& OutFOV, float& OutArmLength) override;
|
||||
void OnModifierDisabled_Implementation(FMinimalViewInfo const& LastPOV, bool bWasImmediate);
|
||||
|
||||
protected:
|
||||
friend class UUGC_ArmLengthRequestAnimNotifyState;
|
||||
UGC_CameraPropertyRequestStackHelper<float> RequestHelper;
|
||||
};
|
||||
@@ -0,0 +1,72 @@
|
||||
// Copyright(c) Aurora Devs 2022-2025. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Misc/Build.h"
|
||||
#include "Misc/Guid.h"
|
||||
#include "Camera/CameraTypes.h"
|
||||
|
||||
class UUGC_CameraModifier;
|
||||
|
||||
template<typename ValueType>
|
||||
struct UGC_CameraPropertyValueRequest
|
||||
{
|
||||
public:
|
||||
bool IsValid() const { return RequestId.IsValid(); }
|
||||
void Invalidate();
|
||||
|
||||
public:
|
||||
FGuid RequestId = FGuid();
|
||||
|
||||
ValueType TargetValue = {};
|
||||
float TotalDuration = 0.f;
|
||||
float BlendInDuration = 0.f;
|
||||
float BlendOutDuration = 0.f;
|
||||
float CurrentTime = 0.f;
|
||||
float BlendInCurrentTime = 0.f;
|
||||
float BlendOutCurrentTime = 0.f;
|
||||
|
||||
class UCurveFloat* BlendInCurve = nullptr;
|
||||
class UCurveFloat* BlendOutCurve = nullptr;
|
||||
|
||||
bool bBlendingIn = false;
|
||||
bool bBlendingOut = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Camera Modifier Helper in charge of handling value change requests from Anim Notifies.
|
||||
*/
|
||||
template<typename ValueType>
|
||||
class AURORADEVS_UGC_API UGC_CameraPropertyRequestStackHelper final
|
||||
{
|
||||
public:
|
||||
void Init(const FName& PropertyName, const TFunction<bool()>& DebugGetterFunction);
|
||||
|
||||
public:
|
||||
void PushValueRequest(FGuid RequestId, ValueType TargetValue, float TotalDuration, float BlendInDuration, UCurveFloat* BlendInCurve, float BlendOutDuration, UCurveFloat* BlendOutCurve);
|
||||
void PopValueRequest(FGuid RequestId);
|
||||
void ProcessValue(float DeltaTime, ValueType InValue, FVector ViewLocation, FRotator ViewRotation, ValueType& OutValue);
|
||||
void OnModifierDisabled(FMinimalViewInfo const& LastPOV, bool bWasImmediate);
|
||||
|
||||
protected:
|
||||
void InvalidateRequest(int32 RequestIndex);
|
||||
int32 FindInactiveRequest();
|
||||
|
||||
protected:
|
||||
friend class UUGC_FOVRequestAnimNotifyState;
|
||||
TArray<UGC_CameraPropertyValueRequest<ValueType>> Requests;
|
||||
TFunction<bool()> DebugGetterFunction;
|
||||
|
||||
FName PropertyName = TEXT("");
|
||||
|
||||
#if !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
|
||||
public:
|
||||
FLinearColor PropertyColor = FColor::Red;
|
||||
|
||||
protected:
|
||||
uint32 NumberActive = 0;
|
||||
#endif
|
||||
};
|
||||
|
||||
#include "UGC_CameraPropertyRequestStackHelper.inl"
|
||||
@@ -0,0 +1,211 @@
|
||||
#pragma once
|
||||
#include "Curves/CurveFloat.h"
|
||||
#include "Engine/Engine.h"
|
||||
#include "Containers/UnrealString.h"
|
||||
#include "Templates/IsArithmetic.h"
|
||||
#include "Templates/Decay.h"
|
||||
|
||||
template<typename ValueType>
|
||||
void UGC_CameraPropertyValueRequest<ValueType>::Invalidate()
|
||||
{
|
||||
*this = UGC_CameraPropertyValueRequest<ValueType>();
|
||||
}
|
||||
|
||||
template<typename ValueType>
|
||||
void UGC_CameraPropertyRequestStackHelper<ValueType>::Init(const FName& InPropertyName, const TFunction<bool()>& BoolDebugGetterFunction)
|
||||
{
|
||||
PropertyName = InPropertyName;
|
||||
DebugGetterFunction = BoolDebugGetterFunction;
|
||||
}
|
||||
|
||||
template<typename ValueType>
|
||||
void UGC_CameraPropertyRequestStackHelper<ValueType>::PushValueRequest(FGuid RequestId, ValueType TargetValue, float TotalDuration, float BlendInDuration, UCurveFloat* BlendInCurve, float BlendOutDuration, UCurveFloat* BlendOutCurve)
|
||||
{
|
||||
if (!RequestId.IsValid() || TotalDuration <= 0.f)
|
||||
{
|
||||
UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__ ": Wrong request."));
|
||||
return;
|
||||
}
|
||||
|
||||
UGC_CameraPropertyValueRequest<ValueType> Request;
|
||||
Request.RequestId = RequestId;
|
||||
Request.CurrentTime = 0.f;
|
||||
Request.TargetValue = TargetValue;
|
||||
Request.TotalDuration = TotalDuration;
|
||||
|
||||
Request.bBlendingIn = BlendInDuration > 0.f;
|
||||
Request.BlendInDuration = BlendInDuration;
|
||||
Request.BlendInCurve = BlendInCurve;
|
||||
Request.BlendInCurrentTime = 0.f;
|
||||
|
||||
Request.bBlendingOut = false;
|
||||
Request.BlendOutDuration = BlendOutDuration;
|
||||
Request.BlendOutCurve = BlendOutCurve;
|
||||
Request.BlendOutCurrentTime = 0.f;
|
||||
|
||||
const int32 NewIndex = FindInactiveRequest();
|
||||
check(NewIndex < MAX_uint16);
|
||||
Requests[NewIndex] = MoveTemp(Request);
|
||||
|
||||
#if !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
|
||||
NumberActive++;
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename ValueType>
|
||||
void UGC_CameraPropertyRequestStackHelper<ValueType>::PopValueRequest(FGuid RequestId)
|
||||
{
|
||||
int32 FoundIndex = -1;
|
||||
for (int32 Index = 0; Index < Requests.Num(); ++Index)
|
||||
{
|
||||
if (Requests[Index].RequestId == RequestId)
|
||||
{
|
||||
FoundIndex = Index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (FoundIndex >= 0)
|
||||
{
|
||||
InvalidateRequest(FoundIndex);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename ValueType>
|
||||
int32 UGC_CameraPropertyRequestStackHelper<ValueType>::FindInactiveRequest()
|
||||
{
|
||||
for (int32 Index = 0; Index < Requests.Num(); ++Index)
|
||||
{
|
||||
const UGC_CameraPropertyValueRequest<ValueType>& Request(Requests[Index]);
|
||||
if (!Request.IsValid())
|
||||
{
|
||||
return Index;
|
||||
}
|
||||
}
|
||||
|
||||
return Requests.Emplace();
|
||||
}
|
||||
|
||||
template<typename ValueType>
|
||||
void UGC_CameraPropertyRequestStackHelper<ValueType>::InvalidateRequest(int32 RequestIndex)
|
||||
{
|
||||
if (RequestIndex >= 0 && RequestIndex < Requests.Num())
|
||||
{
|
||||
Requests[RequestIndex].Invalidate();
|
||||
#if !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
|
||||
--NumberActive;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
template<typename ValueType>
|
||||
void UGC_CameraPropertyRequestStackHelper<ValueType>::ProcessValue(float DeltaTime, ValueType InValue, FVector ViewLocation, FRotator ViewRotation, ValueType& OutValue)
|
||||
{
|
||||
ValueType FinalValue = InValue;
|
||||
for (int32 Index = 0; Index < Requests.Num(); ++Index)
|
||||
{
|
||||
UGC_CameraPropertyValueRequest<ValueType>& Request = Requests[Index];
|
||||
if (!Request.IsValid())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Request.CurrentTime += DeltaTime;
|
||||
|
||||
// Advance any easing times.
|
||||
if (Request.bBlendingIn)
|
||||
{
|
||||
Request.BlendInCurrentTime += DeltaTime;
|
||||
}
|
||||
if (Request.bBlendingOut)
|
||||
{
|
||||
Request.BlendOutCurrentTime += DeltaTime;
|
||||
}
|
||||
|
||||
// Start easing out if we're nearing the end.
|
||||
if (!Request.bBlendingOut)
|
||||
{
|
||||
const float BlendOutStartTime = Request.TotalDuration - Request.BlendOutDuration;
|
||||
if (Request.CurrentTime > BlendOutStartTime)
|
||||
{
|
||||
Request.bBlendingOut = true;
|
||||
Request.BlendOutCurrentTime = Request.CurrentTime - BlendOutStartTime;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if we're done easing in or out.
|
||||
bool bIsDoneEasingOut = false;
|
||||
if (Request.bBlendingIn)
|
||||
{
|
||||
if (Request.BlendInCurrentTime > Request.BlendInDuration || Request.BlendInDuration == 0.f)
|
||||
{
|
||||
Request.bBlendingIn = false;
|
||||
}
|
||||
}
|
||||
if (Request.bBlendingOut)
|
||||
{
|
||||
if (Request.BlendOutCurrentTime > Request.BlendOutDuration)
|
||||
{
|
||||
bIsDoneEasingOut = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Figure out the final easing weight.
|
||||
const float EasingInT = FMath::Clamp((Request.BlendInCurrentTime / Request.BlendInDuration), 0.f, 1.f);
|
||||
const float EasingInWeight = Request.bBlendingIn ?
|
||||
(Request.BlendInCurve ? Request.BlendInCurve->GetFloatValue(EasingInT) : EasingInT) : 1.f;
|
||||
|
||||
const float EasingOutT = FMath::Clamp((1.f - Request.BlendOutCurrentTime / Request.BlendOutDuration), 0.f, 1.f);
|
||||
const float EasingOutWeight = Request.bBlendingOut ?
|
||||
(Request.BlendOutCurve ? Request.BlendOutCurve->GetFloatValue(EasingOutT) : EasingOutT) : 1.f;
|
||||
|
||||
const float TotalEasingWeight = FMath::Min(EasingInWeight, EasingOutWeight);
|
||||
|
||||
// We might be done playing or there was a DisableModifier() call with bImmediate=false to let a value request blend out.
|
||||
if (bIsDoneEasingOut || TotalEasingWeight <= 0.f)
|
||||
{
|
||||
InvalidateRequest(Index);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Using FinalValue so that having multiple value requests at the same time doesn't cause jumps in values.
|
||||
FinalValue = FMath::Lerp(FinalValue, Request.TargetValue, TotalEasingWeight);
|
||||
|
||||
#if !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
|
||||
if (DebugGetterFunction && DebugGetterFunction() && GEngine)
|
||||
{
|
||||
const float TextAlpha = (TotalEasingWeight * static_cast<float>(Index + 1) / static_cast<float>(NumberActive));
|
||||
const FLinearColor TextColor = FMath::Lerp(FLinearColor::White, PropertyColor, TextAlpha);
|
||||
|
||||
FString ValueStr = "";
|
||||
if constexpr (TIsArithmetic<ValueType>::Value) ValueStr = LexToSanitizedString<FString, ValueType>(FinalValue);
|
||||
else ValueStr = FinalValue.ToCompactString();
|
||||
|
||||
GEngine->AddOnScreenDebugMessage(-1, DeltaTime, TextColor.ToFColor(true),
|
||||
FString::Printf(TEXT("UUGC_%sAnimNotifyRequest: Notify %d - %s"), *PropertyName.ToString(), Index, *ValueStr));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
OutValue = FinalValue;
|
||||
}
|
||||
|
||||
template<typename ValueType>
|
||||
void UGC_CameraPropertyRequestStackHelper<ValueType>::OnModifierDisabled(FMinimalViewInfo const& LastPOV, bool bWasImmediate)
|
||||
{
|
||||
for (int32 Index = 0; Index < Requests.Num(); ++Index)
|
||||
{
|
||||
if (!Requests[Index].IsValid())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bWasImmediate)
|
||||
{
|
||||
InvalidateRequest(Index);
|
||||
}
|
||||
else if (!Requests[Index].bBlendingOut)
|
||||
{
|
||||
Requests[Index].bBlendingOut = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
// Copyright(c) Aurora Devs 2022-2025. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/NoExportTypes.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "UObject/Object.h"
|
||||
#include "UObject/ScriptMacros.h"
|
||||
#include "UGC_CameraAnimationModifier.h"
|
||||
#include "UGC_PlayCameraAnimCallbackProxy.generated.h"
|
||||
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnCameraAnimationPlayDelegate);
|
||||
|
||||
/** Parameter struct for adding new camera animations to UGCCameraAnimationCameraModifier */
|
||||
USTRUCT(BlueprintType)
|
||||
struct FUGCCameraAnimationParams
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
/** Time scale for playing the new camera animation */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera Animation")
|
||||
float PlayRate = 1.f;
|
||||
|
||||
/** Ease-in function type */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera Animation")
|
||||
ECameraAnimationEasingType EaseInType = ECameraAnimationEasingType::Linear;
|
||||
/** Ease-in duration in seconds */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera Animation")
|
||||
float EaseInDuration = 0.f;
|
||||
|
||||
/** Ease-out function type */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera Animation")
|
||||
ECameraAnimationEasingType EaseOutType = ECameraAnimationEasingType::Linear;
|
||||
/** Ease-out duration in seconds */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera Animation")
|
||||
float EaseOutDuration = 0.f;
|
||||
|
||||
/** How should the camera behave after the animation is over. */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera Animation")
|
||||
ECameraAnimationResetType ResetType = ECameraAnimationResetType::ResetToZero;
|
||||
|
||||
explicit operator FCameraAnimationParams() const;
|
||||
};
|
||||
|
||||
UCLASS()
|
||||
class AURORADEVS_UGC_API UUGC_PlayCameraAnimCallbackProxy : public UObject
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
// Called when Camera Animation finished playing and wasn't interrupted
|
||||
UPROPERTY(BlueprintAssignable)
|
||||
FOnCameraAnimationPlayDelegate OnCompleted;
|
||||
|
||||
// Called when Camera Animation starts blending out and is not interrupted
|
||||
UPROPERTY(BlueprintAssignable)
|
||||
FOnCameraAnimationPlayDelegate OnEaseOut;
|
||||
|
||||
// Called when Camera Animation has been interrupted (or failed to play)
|
||||
UPROPERTY(BlueprintAssignable)
|
||||
FOnCameraAnimationPlayDelegate OnInterrupted;
|
||||
|
||||
// Called to perform the query internally
|
||||
UFUNCTION(BlueprintCallable, meta = (BlueprintInternalUseOnly = "true"))
|
||||
static UUGC_PlayCameraAnimCallbackProxy* CreateProxyObjectForPlayCameraAnim(
|
||||
class APlayerCameraManager* InPlayerCameraManager,
|
||||
TSubclassOf<class UUGC_CameraAnimationModifier> ModifierClass,
|
||||
class UCameraAnimationSequence* CameraSequence,
|
||||
FUGCCameraAnimationParams Params,
|
||||
struct FCameraAnimationHandle& Handle,
|
||||
bool bInterruptOthers,
|
||||
bool bDoCollisionChecks);
|
||||
|
||||
UFUNCTION(BlueprintCallable, meta = (BlueprintInternalUseOnly = "true"))
|
||||
static UUGC_PlayCameraAnimCallbackProxy* CreateProxyObjectForPlayCameraAnimForModifier(
|
||||
class UUGC_CameraAnimationModifier* CameraAnimationModifier,
|
||||
class UCameraAnimationSequence* CameraSequence,
|
||||
FUGCCameraAnimationParams Params,
|
||||
struct FCameraAnimationHandle& Handle,
|
||||
bool bInterruptOthers,
|
||||
bool bDoCollisionChecks);
|
||||
|
||||
protected:
|
||||
UFUNCTION()
|
||||
void OnCameraAnimationEasingOut(UCameraAnimationSequence* CameraAnimation);
|
||||
|
||||
UFUNCTION()
|
||||
void OnCameraAnimationEnded(UCameraAnimationSequence* CameraAnimation, bool bInterrupted);
|
||||
|
||||
private:
|
||||
TWeakObjectPtr<class UUGC_CameraAnimationModifier> CameraAnimationModifierPtr;
|
||||
|
||||
bool bInterruptedCalledBeforeBlendingOut = false;
|
||||
|
||||
FOnCameraAnimationEaseOutStarted CameraAnimationEasingOutDelegate;
|
||||
FOnCameraAnimationEnded CameraAnimationEndedDelegate;
|
||||
|
||||
void PlayCameraAnimation(
|
||||
class APlayerCameraManager* InPlayerCameraManager,
|
||||
TSubclassOf<class UUGC_CameraAnimationModifier> ModifierClass,
|
||||
class UCameraAnimationSequence* CameraSequence,
|
||||
FUGCCameraAnimationParams Params,
|
||||
struct FCameraAnimationHandle& Handle,
|
||||
bool bInterruptOthers,
|
||||
bool bDoCollisionChecks);
|
||||
|
||||
void PlayCameraAnimation(
|
||||
class UUGC_CameraAnimationModifier* CameraAnimationModifier,
|
||||
class UCameraAnimationSequence* CameraSequence,
|
||||
FUGCCameraAnimationParams Params,
|
||||
struct FCameraAnimationHandle& Handle,
|
||||
bool bInterruptOthers,
|
||||
bool bDoCollisionChecks);
|
||||
};
|
||||
@@ -0,0 +1,326 @@
|
||||
// Copyright(c) Aurora Devs 2022-2025. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Camera/PlayerCameraManager.h"
|
||||
#include "UGC_PlayerCameraManager.generated.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS()
|
||||
class AURORADEVS_UGC_API AUGC_PlayerCameraManager : public APlayerCameraManager
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
AUGC_PlayerCameraManager();
|
||||
|
||||
virtual void InitializeFor(class APlayerController* PC) override;
|
||||
|
||||
/*
|
||||
* This returns the real camera view, this isn't necessarily the view of the camera attached to your character.
|
||||
* For example, during camera animations, the camera used is different than the normal gameplay camera.
|
||||
*/
|
||||
UFUNCTION(BlueprintPure, Category = "UGC|Camera Manager")
|
||||
void GetRealCameraView(FVector& OutViewLocation, FRotator& OutViewRotation) { OutViewLocation = ViewTarget.POV.Location; OutViewRotation = ViewTarget.POV.Rotation; }
|
||||
|
||||
/*
|
||||
* Prepare the possession of a new pawn. Doesn't actually possess the pawn.
|
||||
* APlayerController::Possess needs to be called directly after this function.
|
||||
* @param NewPawn The new pawn that we intend on possessing.
|
||||
* @param NewCameraDA The camera data asset that will be pushed after possessing.
|
||||
*Requires call to PostPosses after the APlayerController::Possess has been called!*
|
||||
* @param bBlendSpringArmProperties Whether the new pawn's spring arm should prepare to blend from the previous spring arm.
|
||||
*This doesn't work with SetViewTargetWithBlend!*
|
||||
*Requires call to PostPosses after the APlayerController::Possess has been called!*
|
||||
* @param bMatchCameraRotation Whether the new pawn should have the same camera spring arm rotation (aka Control Rotation) or not.
|
||||
*This doesn't work with SetViewTargetWithBlend!*
|
||||
*Requires call to PostPosses after the APlayerController::Possess has been called!*
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = "UGC|Camera Manager")
|
||||
void PrePossess(class APawn* NewPawn, class UUGC_CameraDataAssetBase* NewCameraDA, bool bBlendSpringArmProperties = false, bool bMatchCameraRotation = false);
|
||||
|
||||
/*
|
||||
* Finush the possession of a new pawn. APlayerController::Possess needs to have been called directly before this function.
|
||||
* @param bReplaceCurrentCameraDA Whether to push the Camera DA that was passed in the PrePossess function (if any) should
|
||||
replace the current camera DA or be pushed on top of it.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = "UGC|Camera Manager")
|
||||
void PostPossess(bool bReplaceCurrentCameraDA = true);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "UGC|Camera Manager")
|
||||
void RefreshLevelSequences();
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "UGC|Camera Manager")
|
||||
bool IsPlayingAnyLevelSequence() const { return NbrActiveLevelSequences > 0 || NbrActivePausedLevelSequences > 0; }
|
||||
|
||||
// Plays a single new camera animation sequence. Any subsequent calls while this animation runs will interrupt the current animation.
|
||||
// This variation can be used in contexts where async nodes aren't allowd (e.g., AnimNotifies).
|
||||
UFUNCTION(BlueprintCallable, Category = "UGC|Camera Manager")
|
||||
void PlayCameraAnimation(class UCameraAnimationSequence* CameraSequence, struct FUGCCameraAnimationParams const& Params, bool bInterruptOthers, bool bDoCollisionChecks);
|
||||
|
||||
/**
|
||||
* Enables/Disables all camera modifiers ONLY if they inherit from UGC Camera Modifier.
|
||||
* @param bEnabled - true to enable all UGC camera modifiers, false to disable.
|
||||
* @param bImmediate - If bEnabled is false: true to disable immediately with no blend out, false (default) to allow blend out
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = "UGC|Camera Manager")
|
||||
void ToggleUGCCameraModifiers(bool const bEnabled, bool const bImmediate = true);
|
||||
|
||||
/**
|
||||
* Enables/Disables all camera modifiers, regardless of whether they inherit from UGC Camera Modifier.
|
||||
* @param bEnabled - true to enable all camera modifiers, false to disable.
|
||||
* @param bImmediate - If bEnabled is false: true to disable immediately with no blend out, false (default) to allow blend out
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = "UGC|Camera Manager")
|
||||
void ToggleCameraModifiers(bool const bEnabled, bool const bImmediate = true);
|
||||
|
||||
/**
|
||||
* Enables/Disables all debugging of camera modifiers ONLY if they inherit from UGC Camera Modifier.
|
||||
* @param bEnabled - true to enable all debugging of UGC camera modifiers, false to disable.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = "UGC|Camera Manager")
|
||||
void ToggleAllUGCModifiersDebug(bool const bEnabled);
|
||||
/**
|
||||
*
|
||||
* Enables/Disables all debugging of camera modifiers regardless of whether they inherit from UGC Camera Modifier.
|
||||
* @param bEnabled - true to enable all debugging of all camera modifiers, false to disable.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = "UGC|Camera Manager")
|
||||
void ToggleAllModifiersDebug(bool const bEnabled);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "UGC|Camera Manager")
|
||||
class USpringArmComponent* GetOwnerSpringArmComponent() const { return CameraArm.Get(); }
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "UGC|Camera Manager")
|
||||
class UUGC_CameraDataAssetBase* GetCurrentCameraDataAsset() const { return CameraDataStack.IsEmpty() ? nullptr : CameraDataStack[CameraDataStack.Num() - 1]; }
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "UGC|Camera Manager")
|
||||
void PushCameraData(class UUGC_CameraDataAssetBase* CameraDA);
|
||||
|
||||
// Pops the most recent Camera DA.
|
||||
UFUNCTION(BlueprintCallable, Category = "UGC|Camera Manager")
|
||||
void PopCameraDataHead();
|
||||
|
||||
// Pops the given Camera DA. If it isn't in stack, it returns false.
|
||||
UFUNCTION(BlueprintCallable, Category = "UGC|Camera Manager")
|
||||
void PopCameraData(class UUGC_CameraDataAssetBase* CameraDA);
|
||||
|
||||
UFUNCTION(BlueprintNativeEvent, Category = "UGC|Camera Manager")
|
||||
void OnCameraDataStackChanged(class UUGC_CameraDataAssetBase* CameraDA, bool bBlendCameraProperties = true);
|
||||
|
||||
/** Draw a debug camera shape at the real camera's location, which can be different from the character's attached camera.
|
||||
* For example, camera animations use a different camera then the character's attached camera.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = "UGC|Camera Manager|Debug")
|
||||
void DrawRealDebugCamera(float Duration, FLinearColor CameraColor = FLinearColor::Red, float Thickness = 1.f) const;
|
||||
|
||||
/** Draw a debug camera shape at the character's attached camera's location, which can be different from the real camera.
|
||||
* For example, camera animations use a different camera then the character's attached camera.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = "UGC|Camera Manager|Debug")
|
||||
void DrawGameDebugCamera(float Duration, bool bDrawCamera = true, FLinearColor CameraColor = FLinearColor::Blue, bool bDrawSpringArm = true, FLinearColor SpringArmColor = FLinearColor::Blue, float Thickness = 1.f) const;
|
||||
|
||||
/* Draw Spring Arm.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = "UGC|Camera Manager|Debug")
|
||||
void DrawDebugSpringArm(FVector const& CameraLocation, float Duration, FLinearColor SpringArmColor = FLinearColor::Blue, float Thickness = 1.f) const;
|
||||
|
||||
UFUNCTION(BlueprintPure, BlueprintCallable, Category = "UGC|Camera Manager")
|
||||
bool IsPlayingAnyCameraAnimation() const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "UGC|Camera Manager|Movement")
|
||||
FVector GetOwnerVelocity() const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "UGC|Camera Manager|Movement")
|
||||
void ComputeOwnerFloorDist(float SweepDistance, float CapsuleRadius, bool& bOutFloorExists, float& OutFloorDistance) const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "UGC|Camera Manager|Movement")
|
||||
bool IsOwnerFalling() const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "UGC|Camera Manager|Movement")
|
||||
bool IsOwnerStrafing() const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "UGC|Camera Manager|Movement")
|
||||
bool IsOwnerMovingOnGround() const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "UGC|Camera Manager|Movement")
|
||||
void ComputeOwnerFloorNormal(float SweepDistance, float CapsuleRadius, bool& bOutFloorExists, FVector& OutFloorNormal) const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "UGC|Camera Modifier|Movement")
|
||||
void ComputeOwnerSlopeAngle(float& OutSlopePitchDegrees, float& OutSlopeRollDegrees);
|
||||
|
||||
/*
|
||||
* Returns value betwen 1 (the character is looking where they're moving) or -1 (looking in the opposite direction they're moving).
|
||||
* Will return 0 if the character isn't moving.
|
||||
*/
|
||||
UFUNCTION(BlueprintPure, Category = "UGC|Camera Modifier|Movement")
|
||||
float ComputeOwnerLookAndMovementDot();
|
||||
|
||||
/*
|
||||
* Only use this when your pawn has multiple spring arm components and you need to use a different one.
|
||||
* The spring arm is automatically reset to the first found spring arm component on the pawn when we initialize
|
||||
* the camera manager or when we possess a new pawn.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = "UGC|Camera Manager")
|
||||
void SetSpringArmComponent(class USpringArmComponent* Arm) { if (Arm) CameraArm = Arm; }
|
||||
|
||||
/**
|
||||
* Returns camera modifier for this camera of the given class, if it exists.
|
||||
* Looks for inherited classes too. If there are multiple modifiers which fit, the first one is returned.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = "UGC|Camera Manager", meta = (DeterminesOutputType = "ModifierClass"))
|
||||
UCameraModifier* FindCameraModifierOfClass(TSubclassOf<UCameraModifier> ModifierClass, bool bIncludeInherited);
|
||||
|
||||
FVector GetCameraTurnRate() const { return FVector(YawTurnRate, PitchTurnRate, 0.f); }
|
||||
|
||||
UCameraModifier const* FindCameraModifierOfClass(TSubclassOf<UCameraModifier> ModifierClass, bool bIncludeInherited) const;
|
||||
|
||||
template<typename T>
|
||||
T* FindCameraModifierOfType()
|
||||
{
|
||||
bool constexpr bIncludeInherited = true;
|
||||
UCameraModifier* Modifier = FindCameraModifierOfClass(T::StaticClass(), bIncludeInherited);
|
||||
return Modifier != nullptr ? Cast<T>(Modifier) : nullptr;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T const* FindCameraModifierOfType() const
|
||||
{
|
||||
bool constexpr bIncludeInherited = true;
|
||||
UCameraModifier const* Modifier = FindCameraModifierOfClass(T::StaticClass(), bIncludeInherited);
|
||||
return Modifier != nullptr ? Cast<T>(Modifier) : nullptr;
|
||||
}
|
||||
protected:
|
||||
void PushCameraData_Internal(class UUGC_CameraDataAssetBase* CameraDA, bool bBlendCameraProperties);
|
||||
|
||||
void DoForEachUGCModifier(TFunction<void(class UUGC_CameraModifier*)> const& Function);
|
||||
|
||||
// Breaks when the function returns true.
|
||||
void DoForEachUGCModifierWithBreak(TFunction<bool(class UUGC_CameraModifier*)> const& Function);
|
||||
|
||||
virtual void DisplayDebug(class UCanvas* Canvas, const FDebugDisplayInfo& DebugDisplay, float& YL, float& YPos) override;
|
||||
virtual UCameraModifier* AddNewCameraModifier(TSubclassOf<UCameraModifier> ModifierClass) override;
|
||||
virtual bool RemoveCameraModifier(UCameraModifier* ModifierToRemove) override;
|
||||
|
||||
virtual void SetViewTarget(AActor* NewViewTarget, FViewTargetTransitionParams TransitionParams) override;
|
||||
|
||||
/**
|
||||
* Called to give PlayerCameraManager a chance to adjust view rotation updates before they are applied.
|
||||
* e.g. The base implementation enforces view rotation limits using LimitViewPitch, et al.
|
||||
* @param DeltaTime - Frame time in seconds.
|
||||
* @param OutViewRotation - In/out. The view rotation to modify.
|
||||
* @param OutDeltaRot - In/out. How much the rotation changed this frame.
|
||||
*/
|
||||
virtual void ProcessViewRotation(float DeltaTime, FRotator& OutViewRotation, FRotator& OutDeltaRot);
|
||||
|
||||
/**
|
||||
* Called to give PlayerCameraManager a chance to adjust both the yaw turn rate and pitch turn rate.
|
||||
*
|
||||
* @param DeltaTime - Frame time in seconds.
|
||||
* @param InLocalControlRotation - The difference between the actor rotation and the control rotation.
|
||||
* @param OutPitchTurnRate - Out. New value of the pitch turn rate (between 0 and 1).
|
||||
* @param OutYawTurnRate - Out. New value of the yaw turn rate (between 0 and 1).
|
||||
* @return Return true to prevent subsequent (lower priority) modifiers to further adjust rotation, false otherwise.
|
||||
*/
|
||||
virtual void ProcessTurnRate(float DeltaTime, FRotator InLocalControlRotation, float& OutPitchTurnRate, float& OutYawTurnRate);
|
||||
|
||||
virtual void Tick(float DeltaTime) override;
|
||||
|
||||
virtual void LimitViewYaw(FRotator& ViewRotation, float InViewYawMin, float InViewYawMax) override;
|
||||
|
||||
// This updates the internal variables of the UGC Player Camera Manager. Make sure to call the parent function if you override this in BP.
|
||||
UFUNCTION(BlueprintNativeEvent, Category = "UGC|Camera Manager|Internal")
|
||||
void UpdateInternalVariables(float DeltaTime);
|
||||
|
||||
// Usually uses the UGC Pawn Interface to fetch the rotation input of the camera (Mouse or Right Thumbstick). Override this if you want to provide your own way of getting the camera rotation input.
|
||||
UFUNCTION(BlueprintCallable, BlueprintNativeEvent, Category = "UGC|Camera Manager|Internal")
|
||||
FRotator GetRotationInput() const;
|
||||
|
||||
// Usually uses the UGC Pawn Interface to fetch the movement input of the character (WASD or Left Thumbstick). Override this if you want to provide your own way of getting the camera rotation input.
|
||||
UFUNCTION(BlueprintCallable, BlueprintNativeEvent, Category = "UGC|Camera Manager|Internal")
|
||||
FVector GetMovementControlInput() const;
|
||||
|
||||
UFUNCTION()
|
||||
void OnLevelSequenceStarted();
|
||||
|
||||
UFUNCTION()
|
||||
void OnLevelSequencePaused();
|
||||
|
||||
UFUNCTION()
|
||||
void OnLevelSequenceEnded();
|
||||
protected:
|
||||
friend class UUGC_CameraModifier;
|
||||
|
||||
UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "UGC|Camera Manager|Internal")
|
||||
TArray<class UUGC_CameraDataAssetBase*> CameraDataStack;
|
||||
|
||||
UPROPERTY(VisibleInstanceOnly, BlueprintReadWrite, Category = "UGC|Camera Manager|Internal")
|
||||
TObjectPtr<class ACharacter> OwnerCharacter;
|
||||
|
||||
UPROPERTY(VisibleInstanceOnly, BlueprintReadWrite, Category = "UGC|Camera Manager|Internal")
|
||||
TObjectPtr<class APawn> OwnerPawn;
|
||||
|
||||
UPROPERTY(VisibleInstanceOnly, BlueprintReadWrite, Category = "UGC|Camera Manager|Internal")
|
||||
TObjectPtr<class USpringArmComponent> CameraArm;
|
||||
|
||||
UPROPERTY(VisibleInstanceOnly, BlueprintReadWrite, Category = "UGC|Camera Manager|Internal")
|
||||
TObjectPtr<class UCharacterMovementComponent> MovementComponent;
|
||||
|
||||
UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "UGC|Camera Manager|Internal")
|
||||
TArray<class ALevelSequenceActor*> LevelSequences;
|
||||
|
||||
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "UGC|Camera Manager|Angle Constraints", meta = (UIMin = 0.f, UIMax = 1.f, ClampMin = 0.f, ClampMax = 1.f))
|
||||
float PitchTurnRate = 1.f;
|
||||
|
||||
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "UGC|Camera Manager|Angle Constraints", meta = (UIMin = 0.f, UIMax = 1.f, ClampMin = 0.f, ClampMax = 1.f))
|
||||
float YawTurnRate = 1.f;
|
||||
|
||||
UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "UGC|Camera Manager|Internal")
|
||||
float AspectRatio = 0.f;
|
||||
UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "UGC|Camera Manager|Internal")
|
||||
float VerticalFOV = 0.f;
|
||||
UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = "UGC|Camera Manager|Internal")
|
||||
float HorizontalFOV = 0.f;
|
||||
|
||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "UGC|Camera Manager|Internal")
|
||||
bool bHasMovementInput = false;
|
||||
|
||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "UGC|Camera Manager|Internal")
|
||||
FVector MovementInput = FVector::ZeroVector;
|
||||
|
||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "UGC|Camera Manager|Internal")
|
||||
float TimeSinceMovementInput = 0.f;
|
||||
|
||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "UGC|Camera Manager|Internal")
|
||||
bool bHasRotationInput = false;
|
||||
|
||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "UGC|Camera Manager|Internal")
|
||||
FRotator RotationInput = FRotator::ZeroRotator;
|
||||
|
||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "UGC|Camera Manager|Internal")
|
||||
float TimeSinceRotationInput = 0.f;
|
||||
|
||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "UGC|Camera Manager|Internal")
|
||||
float OriginalArmLength = 0.f;
|
||||
|
||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "UGC|Camera Manager|Internal")
|
||||
TArray<class UUGC_CameraModifier*> UGCModifiersList;
|
||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "UGC|Camera Manager|Internal")
|
||||
TArray<class UUGC_CameraAddOnModifier*> UGCAddOnModifiersList;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
int NbrActiveLevelSequences = 0;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
int NbrActivePausedLevelSequences = 0;
|
||||
|
||||
struct PossessPayload
|
||||
{
|
||||
TObjectPtr<class UUGC_CameraDataAssetBase> PendingCameraDA = nullptr;
|
||||
FRotator PendingControlRotation = FRotator::ZeroRotator;
|
||||
bool bBlendCameraProperties = false;
|
||||
bool bMatchCameraRotation = false;
|
||||
} PendingPossessPayload;
|
||||
};
|
||||
@@ -0,0 +1,21 @@
|
||||
// Copyright(c) Aurora Devs 2022-2025. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "InputModifiers.h"
|
||||
#include "UGC_CameraTurnRateModifier.generated.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS()
|
||||
class AURORADEVS_UGC_API UUGC_CameraTurnRateModifier : public UInputModifier
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
virtual FInputActionValue ModifyRaw_Implementation(const UEnhancedPlayerInput* PlayerInput, FInputActionValue CurrentValue, float DeltaTime) override;
|
||||
|
||||
private:
|
||||
TObjectPtr<class AUGC_PlayerCameraManager> PlayerCameraManager;
|
||||
};
|
||||
@@ -0,0 +1,30 @@
|
||||
// Copyright(c) Aurora Devs 2022-2025. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "InputModifiers.h"
|
||||
#include "UGC_InputAccelerationModifier.generated.h"
|
||||
|
||||
/**
|
||||
* Apply an acceleration curve to your input so that it accelerates as time goes by. The given curve should be time-normalized, i.e., between 0 and 1.
|
||||
*/
|
||||
UCLASS(ClassGroup = "UGC Input Modifiers")
|
||||
class AURORADEVS_UGC_API UUGC_InputAccelerationModifier : public UInputModifier
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
virtual FInputActionValue ModifyRaw_Implementation(const UEnhancedPlayerInput* PlayerInput, FInputActionValue CurrentValue, float DeltaTime) override;
|
||||
|
||||
public:
|
||||
// The time it takes to reach full speed.
|
||||
UPROPERTY(EditInstanceOnly, BlueprintReadWrite, Category = Settings, Config)
|
||||
float AccelerationTime = 1.f;
|
||||
|
||||
// Apply an acceleration curve to your input so that it accelerates as time goes by. The given curve should be time-normalized, i.e., between 0 and 1.
|
||||
UPROPERTY(EditInstanceOnly, BlueprintReadWrite, Category = Settings, meta = (DisplayThumbnail = "false"))
|
||||
TObjectPtr<UCurveFloat> AccelerationCurve;
|
||||
|
||||
private:
|
||||
float Timer = 0.f;
|
||||
};
|
||||
@@ -0,0 +1,60 @@
|
||||
// Copyright(c) Aurora Devs 2022-2025. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/Interface.h"
|
||||
#include "UGC_PawnInterface.generated.h"
|
||||
|
||||
// This class does not need to be modified.
|
||||
UINTERFACE(MinimalAPI)
|
||||
class UUGC_PawnInterface : public UInterface
|
||||
{
|
||||
GENERATED_BODY()
|
||||
};
|
||||
|
||||
/**
|
||||
* Pawn Interface used to get the movement/rotation input values.
|
||||
*/
|
||||
class AURORADEVS_UGC_API IUGC_PawnInterface
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
// Get the value of the camera rotation input (usually the right thumbstick or the mouse).
|
||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "UGC|Camera Interface")
|
||||
FRotator GetRotationInput() const;
|
||||
|
||||
// Get the value of the movement input (usually WASD or the left thumbstick).
|
||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "UGC|Camera Interface")
|
||||
FVector GetMovementInput() const;
|
||||
};
|
||||
|
||||
// This class does not need to be modified.
|
||||
UINTERFACE(MinimalAPI)
|
||||
class UUGC_PawnMovementInterface : public UInterface
|
||||
{
|
||||
GENERATED_BODY()
|
||||
};
|
||||
|
||||
/**
|
||||
* This interface should only be used with player classes NOT using the default Unreal Movement Component or components inheriting from it.
|
||||
* This interface can be used to query important movement properties (velocity, falling; etc.) from your custom movement components.
|
||||
*/
|
||||
class AURORADEVS_UGC_API IUGC_PawnMovementInterface
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UFUNCTION(BlueprintImplementableEvent, BlueprintCallable, Category = "UGC|Movement Interface")
|
||||
FVector GetOwnerVelocity() const;
|
||||
|
||||
UFUNCTION(BlueprintImplementableEvent, BlueprintCallable, Category = "UGC|Movement Interface")
|
||||
bool IsOwnerFalling() const;
|
||||
|
||||
UFUNCTION(BlueprintImplementableEvent, BlueprintCallable, Category = "UGC|Movement Interface")
|
||||
bool IsOwnerStrafing() const;
|
||||
|
||||
UFUNCTION(BlueprintImplementableEvent, BlueprintCallable, Category = "UGC|Movement Interface")
|
||||
bool IsOwnerMovingOnGround() const;
|
||||
};
|
||||
Reference in New Issue
Block a user