Files
ChildHood/Source/ChildHood/Interaction/DoorInteractableComponent.cpp
T
starmen1265 237885e3b8 fix(interaction): 修复编译错误和交互系统集成问题
- SystemDriver: EffectManager改为值持有,去掉TUniquePtr和条件编译
- SystemDriver: 补充EngineUtils.h include修复TActorIterator编译错误
- GameMode: BeginPlay自动Spawn ASystemDriver
- InteractableActor: 改为abstract基类,子类自行创建交互组件
- DoorActor: 创建DoorInteractableComp替代基类组件
- EffectManager: 实现ExecuteToggleDoor调用实际门开关逻辑
- InteractableComponent/DoorComponent: 修复GetGameInstance路径和调用方式
- EffectManager: Broadcast改为Execute(单播委托)
2026-06-12 00:51:00 +08:00

90 lines
2.7 KiB
C++

// ChildHood Project - 门交互组件 实现
#include "Interaction/DoorInteractableComponent.h"
#include "Interaction/DoorActor.h"
#include "Interaction/PersistenceSubsystem.h"
#include "ChildHood.h"
#include "Engine/World.h"
#include "Engine/GameInstance.h"
// ============================================================================
// 构造函数
// ============================================================================
UDoorInteractableComponent::UDoorInteractableComponent()
{
// 门不需要 Tick,状态变更由交互事件驱动
PrimaryComponentTick.bCanEverTick = false;
}
// ============================================================================
// 门操作
// ============================================================================
void UDoorInteractableComponent::ToggleDoor()
{
bDoorIsOpen = !bDoorIsOpen;
// 通知 ADoorActor 更新视觉旋转
if (AActor* Owner = GetOwner())
{
if (ADoorActor* DoorActor = Cast<ADoorActor>(Owner))
{
DoorActor->UpdateDoorVisual(bDoorIsOpen);
}
}
// 持久化门状态
if (UWorld* World = GetWorld())
{
if (UPersistenceSubsystem* Persistence = World->GetGameInstance()->GetSubsystem<UPersistenceSubsystem>())
{
Persistence->SetDoorOpen(Data.ItemId, bDoorIsOpen);
}
}
UE_LOG(LogChildHood, Log, TEXT("Door Toggle: %s → %s"),
*Data.ItemId.ToString(),
bDoorIsOpen ? TEXT("Open") : TEXT("Closed"));
}
// ============================================================================
// 提示文本
// ============================================================================
FString UDoorInteractableComponent::GetPromptText_Implementation() const
{
// 根据门状态选择动词:已打开用 Alt 动词(如"关上"),已关闭用主动词(如"打开")
const FString& Verb = bDoorIsOpen ? Data.InteractVerbAlt : Data.InteractVerb;
return FString::Printf(TEXT("[E] %s %s"), *Verb, *Data.DisplayName);
}
// ============================================================================
// 跨场景持久状态恢复
// ============================================================================
void UDoorInteractableComponent::RestorePersistentState(UPersistenceSubsystem* Persistence)
{
if (!Persistence) return;
// 1. 先调用基类恢复消耗状态
Super::RestorePersistentState(Persistence);
// 2. 恢复门开关状态
bDoorIsOpen = Persistence->IsDoorOpen(Data.ItemId);
// 3. 通知 DoorActor 更新视觉旋转
if (AActor* Owner = GetOwner())
{
if (ADoorActor* DoorActor = Cast<ADoorActor>(Owner))
{
DoorActor->UpdateDoorVisual(bDoorIsOpen);
}
}
UE_LOG(LogChildHood, Log, TEXT("Door RestorePersistentState: %s → %s"),
*Data.ItemId.ToString(),
bDoorIsOpen ? TEXT("Open") : TEXT("Closed"));
}