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.
262 lines
9.7 KiB
C++
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; }
|
|
};
|
|
|