tengri/Source/TengriPlatformer/Domains/Character/TengriCharacter.h

183 lines
6.5 KiB
C++

// Request Games © All rights reserved
// Source/TengriPlatformer/Character/TengriCharacter.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "InputActionValue.h"
#include "TengriCharacter.generated.h"
// Forward declarations
class UCapsuleComponent;
class USkeletalMeshComponent;
class UArrowComponent;
class USpringArmComponent;
class UCameraComponent;
class UTengriMovementComponent;
class UTengriCameraComponent;
class UTengriCameraConfig;
class ATengriPickupActor;
class UInputMappingContext;
class UInputAction;
/**
* Main player character class with item interaction and throwing mechanics.
* Supports dynamic input context switching for item-based actions.
* Features integrated camera system with multiple behavior modes.
*/
UCLASS()
class TENGRIPLATFORMER_API ATengriCharacter : public APawn
{
GENERATED_BODY()
public:
ATengriCharacter();
protected:
virtual void BeginPlay() override;
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
public:
// ========================================================================
// COMPONENTS
// ========================================================================
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components")
TObjectPtr<UCapsuleComponent> CapsuleComponent;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components")
TObjectPtr<USkeletalMeshComponent> Mesh;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components")
TObjectPtr<UArrowComponent> ArrowComponent;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components")
TObjectPtr<UTengriMovementComponent> MovementComponent;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components")
TObjectPtr<USpringArmComponent> SpringArmComp;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components")
TObjectPtr<UCameraComponent> CameraComp;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components")
TObjectPtr<UTengriCameraComponent> CameraManager;
// ========================================================================
// CAMERA CONFIGS
// ========================================================================
/** Camera configuration for aiming mode (over-the-shoulder view) */
UPROPERTY(EditDefaultsOnly, Category = "Camera|Configs")
TObjectPtr<UTengriCameraConfig> AimingCameraConfig;
// ========================================================================
// INPUT CONFIG
// ========================================================================
/** Interact action (E / Square) - Always available */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input")
TObjectPtr<UInputAction> InteractAction;
/** Throw action (LMB / R2) - Active only in ItemHeld context */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input")
TObjectPtr<UInputAction> ThrowAction;
/** Aim action (RMB / L2) - Active only in ItemHeld context */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input")
TObjectPtr<UInputAction> AimAction;
/** Input mapping context for item-equipped state (Priority 1) */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input")
TObjectPtr<UInputMappingContext> ItemHeldMappingContext;
// ========================================================================
// INTERACTION API
// ========================================================================
/**
* Handle interact button (E/Square).
* Behavior:
* - If holding item: Drop gently with small forward impulse
* - If empty hands: Pick up nearest item in radius
*/
UFUNCTION(BlueprintCallable, Category = "Interaction")
void Interact();
/**
* Execute throw action (LMB/R2).
* Uses camera-based raycasting for precise trajectory calculation.
* Automatically rotates character to face throw direction.
* @note Only callable when HeldItem is valid
*/
void OnThrowInput();
/**
* Handle aim input state changes (RMB/L2).
* Toggles strafe mode and switches camera configuration.
* @param Value - Input action value (true = pressed, false = released)
*/
void OnAimInput(const FInputActionValue& Value);
/** Check if character is currently holding an item */
UFUNCTION(BlueprintPure, Category = "Interaction")
bool HasItem() const { return HeldItem != nullptr; }
protected:
// ========================================================================
// INTERACTION STATE
// ========================================================================
/** Currently held item reference (nullptr if empty-handed) */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Interaction|State")
TObjectPtr<ATengriPickupActor> HeldItem;
/** Aiming state flag (affects camera and animation) */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Interaction|State")
bool bIsAiming = false;
// ========================================================================
// INTERACTION CONFIG
// ========================================================================
/** Socket name on character mesh for attaching held items */
UPROPERTY(EditDefaultsOnly, Category = "Interaction|Config")
FName HandSocketName = FName("HandSocket");
/** Sphere radius for detecting nearby pickups (cm) */
UPROPERTY(EditDefaultsOnly, Category = "Interaction|Config")
float PickupRadius = 150.0f;
/** Throw velocity magnitude (cm/s) */
UPROPERTY(EditDefaultsOnly, Category = "Interaction|Config")
float ThrowForce = 1200.0f;
/** Gentle drop impulse for interact-to-drop (cm/s) */
UPROPERTY(EditDefaultsOnly, Category = "Interaction|Config")
float GentleDropSpeed = 50.0f;
/** Raycast distance for throw targeting (cm) */
UPROPERTY(EditDefaultsOnly, Category = "Interaction|Config")
float ThrowTraceDistance = 5000.0f;
/** Arc elevation adjustment for throw trajectory */
UPROPERTY(EditDefaultsOnly, Category = "Interaction|Config")
float ThrowArcElevation = 0.15f;
private:
/**
* Find nearest interactable pickup within radius.
* Uses sphere overlap against PhysicsBody and WorldDynamic channels.
* @return Nearest valid pickup, or nullptr if none found
*/
ATengriPickupActor* FindNearestPickup() const;
/**
* Toggle ItemHeld input mapping context on/off.
* Manages context priority to enable/disable throw and aim actions.
* @param bEnable - True to add context, false to remove
*/
void ToggleItemHeldContext(bool bEnable) const;
};