108 lines
3.5 KiB
C++
108 lines
3.5 KiB
C++
// ChildHood Project - 可交互物组件(v1.1 Effect/Action 架构)
|
||
// 对应技术方案: docs/technical/交互系统-技术方案.md 第3节(类设计)+ 第12节(跨场景持久化)
|
||
// 职责:单个交互物配置数据、触发区域、运行时状态、跨场景持久状态恢复
|
||
// 核心变更(v0.1 → v1.1):去除所有门逻辑,只保留通用交互物功能
|
||
|
||
#pragma once
|
||
|
||
#include "CoreMinimal.h"
|
||
#include "Components/ActorComponent.h"
|
||
#include "InteractionTypes.h"
|
||
#include "InteractableComponent.generated.h"
|
||
|
||
class UPersistenceSubsystem;
|
||
class USphereComponent;
|
||
class ASystemDriver;
|
||
|
||
/**
|
||
* UInteractableComponent
|
||
*
|
||
* 挂载在 AInteractableActor(或其子类)上的组件。
|
||
* 持有该交互物的全部配置数据(FInteractableData)、运行时触发检测球、
|
||
* 消耗状态管理,以及跨场景持久状态恢复。
|
||
*
|
||
* 碰撞回调通过 ASystemDriver::Get() 获取 Driver,
|
||
* 再调用 GetInteractionManager().RegisterInteractable(this) 注册。
|
||
*
|
||
* 门逻辑已移除,由 UDoorInteractableComponent 派生类实现(Phase 2)。
|
||
*/
|
||
UCLASS(ClassGroup=(Interaction), meta=(BlueprintSpawnableComponent))
|
||
class UInteractableComponent : public UActorComponent
|
||
{
|
||
GENERATED_BODY()
|
||
|
||
public:
|
||
|
||
UInteractableComponent();
|
||
|
||
// === 配置数据 ===
|
||
|
||
/** 该交互物的全部配置数据,编辑器中按实例独立配置 */
|
||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Interact")
|
||
FInteractableData Data;
|
||
|
||
// === 查询接口 ===
|
||
|
||
/** 获取配置数据引用(只读) */
|
||
const FInteractableData& GetInteractableData() const { return Data; }
|
||
|
||
/**
|
||
* 获取提示文本,格式:"[E] 动作词 名称"
|
||
* 子类可覆盖以实现动态动词(如门的"打开"/"关上")
|
||
*/
|
||
UFUNCTION(BlueprintNativeEvent, Category = "Interact", meta = (DisplayName = "Get Prompt Text"))
|
||
FString GetPromptText() const;
|
||
virtual FString GetPromptText_Implementation() const;
|
||
|
||
/** 该交互物是否已被消耗(oneShot 模式) */
|
||
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Interact")
|
||
bool IsConsumed() const { return bIsConsumed; }
|
||
|
||
/** 标记为已消耗,禁用检测球 */
|
||
UFUNCTION(BlueprintNativeEvent, Category = "Interact", meta = (DisplayName = "Consume"))
|
||
void Consume();
|
||
virtual void Consume_Implementation();
|
||
|
||
/** 获取交互物在世界空间的位置 */
|
||
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Interact")
|
||
FVector GetWorldLocation() const;
|
||
|
||
/**
|
||
* 从持久层恢复跨场景持久状态(BeginPlay 中调用)。
|
||
* oneShot 物品已消耗时隐藏 Actor 并禁用检测。
|
||
* 子类可覆盖以恢复额外状态(如门的开关状态)。
|
||
*/
|
||
virtual void RestorePersistentState(UPersistenceSubsystem* Persistence);
|
||
|
||
protected:
|
||
|
||
virtual void BeginPlay() override;
|
||
|
||
private:
|
||
|
||
/** 运行时创建的检测球,用于触发玩家进入/离开交互范围 */
|
||
UPROPERTY()
|
||
TObjectPtr<USphereComponent> DetectionSphere;
|
||
|
||
/** oneShot 物品是否已被消耗 */
|
||
bool bIsConsumed = false;
|
||
|
||
// === 碰撞回调 ===
|
||
|
||
/** 玩家进入检测范围 — 通过 ASystemDriver 注册到 InteractionManager */
|
||
UFUNCTION()
|
||
void OnDetectionOverlapBegin(UPrimitiveComponent* OverlappedComponent,
|
||
AActor* OtherActor,
|
||
UPrimitiveComponent* OtherComp,
|
||
int32 OtherBodyIndex,
|
||
bool bFromSweep,
|
||
const FHitResult& SweepResult);
|
||
|
||
/** 玩家离开检测范围 — 通过 ASystemDriver 从 InteractionManager 注销 */
|
||
UFUNCTION()
|
||
void OnDetectionOverlapEnd(UPrimitiveComponent* OverlappedComponent,
|
||
AActor* OtherActor,
|
||
UPrimitiveComponent* OtherComp,
|
||
int32 OtherBodyIndex);
|
||
};
|