Files
KingshearthLegacy/Source/KingshearthLegacy/KingshearthLegacyCharacter.h
T
Dolobarsch 8099d69a23 Neues Interaktionssystem implementiert
Einführung eines modularen Interaktionssystems:
- Hinzufügen der `IInteractable`- und `IInteractionLookupProvider`-Schnittstellen.
- Implementierung der `UInteractionComponent` zur Steuerung von Interaktionen (Tippen, Halten, Kontextmenü).
- Integration der `InteractionComponent` in `KingshearthLegacyCharacter`.
- Hinzufügen des `InteractionContextMenuWidget` für UI-Interaktionen.
- Änderungen an `PlayerHUDWidget`, um Interaktions-Widgets zu unterstützen.
- Neue Assets und Konfigurationsänderungen für Kollisionen und Redirects.
- Verbesserte Modularität und Benutzerfreundlichkeit durch klare Trennung von Logik und Darstellung.
2026-09-05 03:04:12 +02:00

262 lines
9.7 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "Logging/LogMacros.h"
#include "AbilitySystemInterface.h"
#include "ActiveGameplayEffectHandle.h"
#include "KingshearthLegacyCharacter.generated.h"
class USpringArmComponent;
class UCameraComponent;
class UInputAction;
class UAbilitySystemComponent;
class UHealthAttributeSet;
class UStaminaAttributeSet;
class UInteractionComponent;
struct FInputActionValue;
DECLARE_LOG_CATEGORY_EXTERN(LogTemplateCharacter, Log, All);
/**
* A simple player-controllable third person character
* Implements a controllable orbiting camera
*/
UCLASS(abstract)
class AKingshearthLegacyCharacter : public ACharacter, public IAbilitySystemInterface
{
GENERATED_BODY()
/** Camera boom positioning the camera behind the character */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Components", meta = (AllowPrivateAccess = "true"))
USpringArmComponent* CameraBoom;
/** Follow camera */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Components", meta = (AllowPrivateAccess = "true"))
UCameraComponent* FollowCamera;
protected:
/** Jump Input Action */
UPROPERTY(EditAnywhere, Category="Input")
UInputAction* JumpAction;
/** Move Input Action */
UPROPERTY(EditAnywhere, Category="Input")
UInputAction* MoveAction;
/** Look Input Action */
UPROPERTY(EditAnywhere, Category="Input")
UInputAction* LookAction;
/** Mouse Look Input Action */
UPROPERTY(EditAnywhere, Category="Input")
UInputAction* MouseLookAction;
/** Sprint Input Action */
UPROPERTY(EditAnywhere, Category="Input")
UInputAction* SprintAction;
/** Interact Input Action - Started begins a tap/hold, Completed resolves it */
UPROPERTY(EditAnywhere, Category="Input")
UInputAction* InteractAction;
/** Cycles the Context Menu's highlighted option while it is open (e.g. mouse wheel axis) */
UPROPERTY(EditAnywhere, Category="Input")
UInputAction* InteractCycleAction;
/** Walk speed is multiplied by this while sprinting */
UPROPERTY(EditAnywhere, Category="Sprint")
float SprintSpeedMultiplier = 1.6f;
/** Stamina drained per second while sprinting */
UPROPERTY(EditAnywhere, Category="Sprint")
float SprintStaminaDrainRate = 25.0f;
/** Minimum speed (cm/s) for the character to be considered "moving" for sprint purposes. */
UPROPERTY(EditAnywhere, Category="Sprint")
float SprintMovementThreshold = 10.0f;
/** Stamina consumed by each successful jump. */
UPROPERTY(EditAnywhere, Category="Stamina")
float JumpStaminaCost = 15.0f;
/** Regen rate once fully ramped up, in stamina/sec. */
UPROPERTY(EditAnywhere, Category="Stamina")
float StaminaRegenRate = 20.0f;
/** Seconds after the last stamina spend before regen starts at all. */
UPROPERTY(EditAnywhere, Category="Stamina")
float StaminaRegenDelay = 1.0f;
/** Seconds for the regen rate to ramp from 0 up to StaminaRegenRate once regen starts, instead of kicking in at full speed immediately. */
UPROPERTY(EditAnywhere, Category="Stamina")
float StaminaRegenRampTime = 1.5f;
/** Fatigue gained per second while Stamina is actively regaining (ramping back up). Never recovers on its own otherwise - only an explicit debug/design call reduces it. */
UPROPERTY(EditAnywhere, Category="Fatigue")
float FatigueGainRateWhileRegaining = 0.1f;
public:
/** Constructor */
AKingshearthLegacyCharacter();
protected:
virtual void BeginPlay() override;
virtual void Tick(float DeltaSeconds) override;
/** Initialize input action bindings */
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
/** Overridden to charge JumpStaminaCost whenever a jump actually starts. */
virtual void Jump() override;
protected:
/** Called for movement input */
void Move(const FInputActionValue& Value);
/** Called for looking input */
void Look(const FInputActionValue& Value);
/** Called when the sprint input is pressed */
void StartSprint();
/** Called when the sprint input is released */
void StopSprint();
/** Called for Context Menu cycling input (e.g. mouse wheel axis) */
void InteractCycle(const FInputActionValue& Value);
/** Advances the regen delay/ramp curve and applies Stamina/Fatigue regen for this frame. */
void TickStaminaRegen(float DeltaSeconds);
/** Cached from the CharacterMovementComponent's MaxWalkSpeed in BeginPlay, restored whenever not sprinting. */
float BaseWalkSpeed = 0.0f;
bool bWantsToSprint = false;
/** Seconds since Stamina was last reduced by a spend. Resets the regen delay/ramp whenever SpendStamina runs. */
float TimeSinceLastStaminaSpend = 0.0f;
/** Drives all attribute sets (Health, Stamina, and future Nutrition/Blood). Self-owned: this character is both owner and avatar. */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Abilities", meta = (AllowPrivateAccess = "true"))
TObjectPtr<UAbilitySystemComponent> AbilitySystemComponent;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Abilities", meta = (AllowPrivateAccess = "true"))
TObjectPtr<UHealthAttributeSet> HealthAttributeSet;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Abilities", meta = (AllowPrivateAccess = "true"))
TObjectPtr<UStaminaAttributeSet> StaminaAttributeSet;
/** Currently-applied GE_HealthDebuff instance, if any - reapplied/removed wholesale by SetHealthDebuff so it behaves like the old "set to X" API instead of stacking. */
FActiveGameplayEffectHandle HealthDebuffEffectHandle;
/** Drives the contextual "hold E" interaction system - see UInteractionComponent. */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Interaction", meta = (AllowPrivateAccess = "true"))
TObjectPtr<UInteractionComponent> InteractionComponent;
public:
//~ Begin IAbilitySystemInterface
virtual UAbilitySystemComponent* GetAbilitySystemComponent() const override;
//~ End IAbilitySystemInterface
/** Exposed for Blueprint to bind OnHealthChanged/OnHealthDebuffChanged/OnDeath - there's no "component bound event" for a plain UObject subobject, so bind via this getter's return pin instead (drag off it, search "Bind Event to..."). */
UFUNCTION(BlueprintPure, Category = "Health")
FORCEINLINE UHealthAttributeSet* GetHealthAttributeSet() const { return HealthAttributeSet; }
/** Exposed for Blueprint to bind OnStaminaChanged/OnFatigueChanged/OnExhausted - see GetHealthAttributeSet(). */
UFUNCTION(BlueprintPure, Category = "Stamina")
FORCEINLINE UStaminaAttributeSet* GetStaminaAttributeSet() const { return StaminaAttributeSet; }
// Health
UFUNCTION(BlueprintPure, Category = "Health")
float GetHealth() const;
/** Nominal cap, unaffected by HealthDebuff. Feeds the health bar's total width. */
UFUNCTION(BlueprintPure, Category = "Health")
float GetMaxHealth() const;
/** 0-1 fraction of MaxHealth currently locked/unusable (curses, status effects, ...). */
UFUNCTION(BlueprintPure, Category = "Health")
float GetHealthDebuff() const;
UFUNCTION(BlueprintCallable, Category = "Health")
void ApplyDamage(float Amount);
UFUNCTION(BlueprintCallable, Category = "Health")
void ApplyHealing(float Amount);
/** Sets how much of MaxHealth is currently locked away (0-1) by applying/refreshing/removing a single GE_HealthDebuff instance. */
UFUNCTION(BlueprintCallable, Category = "Health")
void SetHealthDebuff(float NewHealthDebuff);
// Stamina
UFUNCTION(BlueprintPure, Category = "Stamina")
float GetStamina() const;
/** Nominal cap, unaffected by Fatigue. Feeds the stamina bar's total width. */
UFUNCTION(BlueprintPure, Category = "Stamina")
float GetMaxStamina() const;
UFUNCTION(BlueprintPure, Category = "Fatigue")
float GetFatigue() const;
/** Deducts Amount from Stamina and resets the regen delay/ramp. No-op for Amount <= 0. */
UFUNCTION(BlueprintCallable, Category = "Stamina")
void SpendStamina(float Amount);
/** Adds Amount to Stamina without affecting the regen delay/ramp (e.g. a stamina potion). No-op for Amount <= 0. */
UFUNCTION(BlueprintCallable, Category = "Stamina")
void RestoreStamina(float Amount);
/** Sets Fatigue directly (0-1). Fatigue only ever builds on its own; this is the only way to reduce it (e.g. a debug key or a future rest mechanic). */
UFUNCTION(BlueprintCallable, Category = "Fatigue")
void SetFatigue(float NewFatigue);
/** Handles move inputs from either controls or UI interfaces */
UFUNCTION(BlueprintCallable, Category="Input")
virtual void DoMove(float Right, float Forward);
/** Handles look inputs from either controls or UI interfaces */
UFUNCTION(BlueprintCallable, Category="Input")
virtual void DoLook(float Yaw, float Pitch);
/** Handles jump pressed inputs from either controls or UI interfaces */
UFUNCTION(BlueprintCallable, Category="Input")
virtual void DoJumpStart();
/** Handles jump pressed inputs from either controls or UI interfaces */
UFUNCTION(BlueprintCallable, Category="Input")
virtual void DoJumpEnd();
/** Handles interact pressed inputs from either controls or UI interfaces - begins a tap/hold */
UFUNCTION(BlueprintCallable, Category="Input")
virtual void DoInteractStart();
/** Handles interact released inputs from either controls or UI interfaces - resolves the tap/hold */
UFUNCTION(BlueprintCallable, Category="Input")
virtual void DoInteractEnd();
/** Handles Context Menu cycling inputs (e.g. mouse wheel) from either controls or UI interfaces */
UFUNCTION(BlueprintCallable, Category="Input")
virtual void DoInteractCycle(float Direction);
/** Returns InteractionComponent subobject **/
FORCEINLINE UInteractionComponent* GetInteractionComponent() const { return InteractionComponent; }
public:
/** Returns CameraBoom subobject **/
FORCEINLINE class USpringArmComponent* GetCameraBoom() const { return CameraBoom; }
/** Returns FollowCamera subobject **/
FORCEINLINE class UCameraComponent* GetFollowCamera() const { return FollowCamera; }
};