// 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 UTengriMovementComponent; class ATengriPickupActor; class UArrowComponent; class UInputMappingContext; class UInputAction; /** * Main player character class with item interaction and throwing mechanics. * Supports dynamic input context switching for item-based actions. */ 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 CapsuleComponent; UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components") TObjectPtr Mesh; UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components") TObjectPtr ArrowComponent; UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components") TObjectPtr MovementComponent; // ======================================================================== // INPUT CONFIG // ======================================================================== /** Interact action (E / Square) - Always available */ UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input") TObjectPtr InteractAction; /** Throw action (LMB / R2) - Active only in ItemHeld context */ UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input") TObjectPtr ThrowAction; /** Aim action (RMB / L2) - Active only in ItemHeld context */ UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input") TObjectPtr AimAction; /** Input mapping context for item-equipped state (Priority 1) */ UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input") TObjectPtr 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 on MovementComponent for camera-aligned rotation. * @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 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; };