// Request Games © All rights reserved // Source/TengriPlatformer/Camera/TengriCameraComponent.h #pragma once #include "CoreMinimal.h" #include "Components/ActorComponent.h" #include "Core/TengriCameraConfig.h" #include "TengriCameraComponent.generated.h" class USpringArmComponent; class UCameraComponent; /** * Dynamic camera system with multiple behavior modes and smooth transitions. * Supports free look (3D) and side-scroller (2.5D) with configurable dead zones. * Updates after physics to prevent visual jitter during interpolation. */ UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent)) class TENGRIPLATFORMER_API UTengriCameraComponent : public UActorComponent { GENERATED_BODY() public: UTengriCameraComponent(); virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override; /** * Initialize camera system with spring arm and camera references. * Must be called before TickComponent runs. * @param InSpringArm - Spring arm component for camera positioning * @param InCamera - Camera component for rendering */ void InitializeCamera(USpringArmComponent* InSpringArm, UCameraComponent* InCamera); /** * Switch to a new camera configuration (e.g. from camera volume trigger). * Smoothly transitions between configs using TransitionSpeed. * @param NewConfig - New camera configuration to apply */ UFUNCTION(BlueprintCallable, Category = "Tengri Camera") void SetCameraConfig(UTengriCameraConfig* NewConfig); protected: virtual void BeginPlay() override; public: // ════════════════════════════════════════════════════════════════════ // CONFIGURATION // ════════════════════════════════════════════════════════════════════ /** Default camera configuration applied at BeginPlay */ UPROPERTY(EditAnywhere, Category = "Config") TObjectPtr DefaultConfig; /** Currently active camera configuration */ UPROPERTY(Transient, BlueprintReadOnly, Category = "Config") TObjectPtr CurrentConfig; private: // ════════════════════════════════════════════════════════════════════ // COMPONENT REFERENCES // ════════════════════════════════════════════════════════════════════ UPROPERTY() TObjectPtr SpringArm; UPROPERTY() TObjectPtr Camera; // ════════════════════════════════════════════════════════════════════ // STATE // ════════════════════════════════════════════════════════════════════ /** Current smoothed camera focus point in world space */ FVector CurrentFocusLocation = FVector::ZeroVector; // ════════════════════════════════════════════════════════════════════ // INTERNAL HELPERS // ════════════════════════════════════════════════════════════════════ /** * Calculate target focus position with dead zone clamping. * Returns input position if player is inside dead zone, * otherwise returns edge of dead zone closest to player. * @param PlayerLocation - Current player position * @return Target camera focus position */ FVector CalculateDeadZoneTarget(const FVector& PlayerLocation) const; /** * Draw debug visualization of dead zone box. * Only enabled in editor builds when bDrawDebugBox is true. * @param Center - Dead zone center point * @param Extent - Dead zone half-extents */ void DrawDebugDeadZone(const FVector& Center, const FVector& Extent) const; };