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(单播委托)
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,8 +1,26 @@
|
|||||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||||
|
|
||||||
#include "ChildHoodGameMode.h"
|
#include "ChildHoodGameMode.h"
|
||||||
|
#include "SystemDriver.h"
|
||||||
|
|
||||||
AChildHoodGameMode::AChildHoodGameMode()
|
AChildHoodGameMode::AChildHoodGameMode()
|
||||||
{
|
{
|
||||||
// stub
|
// stub
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AChildHoodGameMode::BeginPlay()
|
||||||
|
{
|
||||||
|
Super::BeginPlay();
|
||||||
|
|
||||||
|
// 自动 Spawn ASystemDriver(全局交互系统驱动器)
|
||||||
|
// 如果关卡中已手动放置则跳过,避免重复
|
||||||
|
if (UWorld* World = GetWorld())
|
||||||
|
{
|
||||||
|
if (!ASystemDriver::Get(this))
|
||||||
|
{
|
||||||
|
FActorSpawnParameters SpawnParams;
|
||||||
|
SpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
|
||||||
|
World->SpawnActor<ASystemDriver>(ASystemDriver::StaticClass(), FTransform::Identity, SpawnParams);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ public:
|
|||||||
|
|
||||||
/** Constructor */
|
/** Constructor */
|
||||||
AChildHoodGameMode();
|
AChildHoodGameMode();
|
||||||
|
|
||||||
|
virtual void BeginPlay() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -13,10 +13,9 @@ ADoorActor::ADoorActor()
|
|||||||
{
|
{
|
||||||
PrimaryActorTick.bCanEverTick = false;
|
PrimaryActorTick.bCanEverTick = false;
|
||||||
|
|
||||||
// 基类构造函数已创建 MeshComp(根组件)和 InteractableComp
|
// 创建门专用交互组件,赋值给基类指针
|
||||||
|
|
||||||
// 创建门专用交互组件,替代基类的通用 InteractableComp
|
|
||||||
DoorInteractableComp = CreateDefaultSubobject<UDoorInteractableComponent>(TEXT("DoorInteractableComp"));
|
DoorInteractableComp = CreateDefaultSubobject<UDoorInteractableComponent>(TEXT("DoorInteractableComp"));
|
||||||
|
InteractableComp = DoorInteractableComp;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
#include "ChildHood.h"
|
#include "ChildHood.h"
|
||||||
|
|
||||||
#include "Engine/World.h"
|
#include "Engine/World.h"
|
||||||
#include "GameFramework/GameInstance.h"
|
#include "Engine/GameInstance.h"
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// 构造函数
|
// 构造函数
|
||||||
|
|||||||
@@ -9,6 +9,8 @@
|
|||||||
#include "Interaction/PersistenceSubsystem.h"
|
#include "Interaction/PersistenceSubsystem.h"
|
||||||
#include "Interaction/PushCameraActor.h"
|
#include "Interaction/PushCameraActor.h"
|
||||||
#include "Components/SphereComponent.h"
|
#include "Components/SphereComponent.h"
|
||||||
|
#include "Interaction/DoorInteractableComponent.h"
|
||||||
|
#include "Interaction/DoorActor.h"
|
||||||
#include "Kismet/GameplayStatics.h"
|
#include "Kismet/GameplayStatics.h"
|
||||||
#include "Animation/AnimInstance.h"
|
#include "Animation/AnimInstance.h"
|
||||||
|
|
||||||
@@ -176,7 +178,7 @@ void FEffectManager::FinishEffect()
|
|||||||
// 广播完成回调
|
// 广播完成回调
|
||||||
if (OnEffectComplete.IsBound())
|
if (OnEffectComplete.IsBound())
|
||||||
{
|
{
|
||||||
OnEffectComplete.Broadcast();
|
OnEffectComplete.Execute();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -395,8 +397,13 @@ void FEffectManager::ExecuteShowPickupNotification()
|
|||||||
|
|
||||||
void FEffectManager::ExecuteToggleDoor()
|
void FEffectManager::ExecuteToggleDoor()
|
||||||
{
|
{
|
||||||
// v0.1: 日志占位(门逻辑由 UDoorInteractableComponent 派生类实现,Phase 2)
|
if (!CurrentContext.TargetComp.IsValid()) return;
|
||||||
UE_LOG(LogTemp, Log, TEXT("EffectManager: ToggleDoor (placeholder)"));
|
|
||||||
|
if (UDoorInteractableComponent* DoorComp = Cast<UDoorInteractableComponent>(CurrentContext.TargetComp.Get()))
|
||||||
|
{
|
||||||
|
DoorComp->ToggleDoor();
|
||||||
|
UE_LOG(LogTemp, Log, TEXT("EffectManager: ToggleDoor executed"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|||||||
@@ -18,8 +18,7 @@ AInteractableActor::AInteractableActor()
|
|||||||
RootComponent = MeshComp;
|
RootComponent = MeshComp;
|
||||||
MeshComp->SetCollisionProfileName(TEXT("BlockAll"));
|
MeshComp->SetCollisionProfileName(TEXT("BlockAll"));
|
||||||
|
|
||||||
// 创建交互组件(UActorComponent 不需要 SetupAttachment,数据驱动型组件)
|
// InteractableComp 由子类创建(本类为 abstract)
|
||||||
InteractableComp = CreateDefaultSubobject<UInteractableComponent>(TEXT("InteractableComp"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// ChildHood Project - 通用交互物 Actor 基类(v1.1 Effect/Action 架构)
|
// ChildHood Project - 通用交互物 Actor 基类(v1.1 Effect/Action 架构)
|
||||||
// 对应技术方案: docs/technical/交互系统-技术方案.md 第3节(类设计)
|
// 对应技术方案: docs/technical/交互系统-技术方案.md 第3节(类设计)
|
||||||
// 职责:持有 Mesh + InteractableComponent,提供可被子类覆盖的交互回调
|
// 职责:持有 Mesh,提供可被子类覆盖的交互回调
|
||||||
// 核心变更(v0.1 → v1.1):去除门旋转逻辑,只保留干净的基类
|
// 注意:本类为 abstract,子类必须自行创建并赋值 InteractableComp
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
@@ -15,17 +15,14 @@ class UStaticMeshComponent;
|
|||||||
/**
|
/**
|
||||||
* AInteractableActor
|
* AInteractableActor
|
||||||
*
|
*
|
||||||
* 通用交互物 Actor 基类。场景中的每个交互物(冰箱、门、NPC 等)
|
* 交互物 Actor 抽象基类。提供 Mesh 和交互回调框架。
|
||||||
* 均为该类的实例或其子类的实例。
|
* 子类必须在构造函数中创建合适的 InteractableComponent 并赋值给 InteractableComp。
|
||||||
*
|
*
|
||||||
* 组成:
|
* 组成:
|
||||||
* - UStaticMeshComponent* MeshComp(根组件,承载可视模型)
|
* - UStaticMeshComponent* MeshComp(根组件,承载可视模型)
|
||||||
* - UInteractableComponent* InteractableComp(交互逻辑与数据)
|
* - UInteractableComponent* InteractableComp(由子类创建)
|
||||||
*
|
|
||||||
* 子类可覆盖 OnInteractStarted / OnInteractEnded 以实现类型特定行为,
|
|
||||||
* 如门开关时的 Mesh 旋转(ADoorActor)、拾取物的消失效果等。
|
|
||||||
*/
|
*/
|
||||||
UCLASS()
|
UCLASS(abstract)
|
||||||
class AInteractableActor : public AActor
|
class AInteractableActor : public AActor
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
@@ -70,7 +67,10 @@ protected:
|
|||||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components", meta = (AllowPrivateAccess = "true"))
|
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components", meta = (AllowPrivateAccess = "true"))
|
||||||
TObjectPtr<UStaticMeshComponent> MeshComp;
|
TObjectPtr<UStaticMeshComponent> MeshComp;
|
||||||
|
|
||||||
/** 交互物的交互组件(数据 + 检测 + 状态) */
|
/**
|
||||||
|
* 交互物的交互组件(数据 + 检测 + 状态)。
|
||||||
|
* 由子类在构造函数中创建并赋值。
|
||||||
|
*/
|
||||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components", meta = (AllowPrivateAccess = "true"))
|
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components", meta = (AllowPrivateAccess = "true"))
|
||||||
TObjectPtr<UInteractableComponent> InteractableComp;
|
TObjectPtr<UInteractableComponent> InteractableComp;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
#include "Components/SphereComponent.h"
|
#include "Components/SphereComponent.h"
|
||||||
#include "Engine/World.h"
|
#include "Engine/World.h"
|
||||||
#include "GameFramework/GameInstance.h"
|
#include "Engine/GameInstance.h"
|
||||||
#include "GameFramework/Character.h"
|
#include "GameFramework/Character.h"
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@@ -59,7 +59,8 @@ void UInteractableComponent::BeginPlay()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// --- 恢复跨场景持久状态 ---
|
// --- 恢复跨场景持久状态 ---
|
||||||
if (UPersistenceSubsystem* Persistence = GetGameInstance()->GetSubsystem<UPersistenceSubsystem>())
|
UGameInstance* GI = Owner->GetGameInstance();
|
||||||
|
if (UPersistenceSubsystem* Persistence = GI ? GI->GetSubsystem<UPersistenceSubsystem>() : nullptr)
|
||||||
{
|
{
|
||||||
RestorePersistentState(Persistence);
|
RestorePersistentState(Persistence);
|
||||||
}
|
}
|
||||||
@@ -94,9 +95,9 @@ void UInteractableComponent::Consume_Implementation()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 写入持久层
|
// 写入持久层
|
||||||
if (UWorld* World = GetWorld())
|
if (UGameInstance* GI = GetOwner() ? GetOwner()->GetGameInstance() : nullptr)
|
||||||
{
|
{
|
||||||
if (UPersistenceSubsystem* Persistence = World->GetGameInstance()->GetSubsystem<UPersistenceSubsystem>())
|
if (UPersistenceSubsystem* Persistence = GI->GetSubsystem<UPersistenceSubsystem>())
|
||||||
{
|
{
|
||||||
Persistence->MarkItemCollected(Data.ItemId);
|
Persistence->MarkItemCollected(Data.ItemId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,17 +5,8 @@
|
|||||||
#include "SystemDriver.h"
|
#include "SystemDriver.h"
|
||||||
#include "ChildHood.h"
|
#include "ChildHood.h"
|
||||||
|
|
||||||
// FEffectManager 尚未创建时,此 include 会失败。
|
|
||||||
// 临时处理:条件编译,EffectManager.h 存在时才包含。
|
|
||||||
// 当 EffectManager 子代理完成后,去掉 __has_include 判断直接包含。
|
|
||||||
#if __has_include("Interaction/EffectManager.h")
|
|
||||||
#include "Interaction/EffectManager.h"
|
|
||||||
#define HAS_EFFECT_MANAGER 1
|
|
||||||
#else
|
|
||||||
#define HAS_EFFECT_MANAGER 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "Engine/World.h"
|
#include "Engine/World.h"
|
||||||
|
#include "EngineUtils.h"
|
||||||
#include "Kismet/GameplayStatics.h"
|
#include "Kismet/GameplayStatics.h"
|
||||||
#include "GameFramework/PlayerController.h"
|
#include "GameFramework/PlayerController.h"
|
||||||
#include "GameFramework/Character.h"
|
#include "GameFramework/Character.h"
|
||||||
@@ -29,11 +20,6 @@ ASystemDriver::ASystemDriver()
|
|||||||
// AInfo 默认不需要 Tick,我们在构造函数中开启
|
// AInfo 默认不需要 Tick,我们在构造函数中开启
|
||||||
PrimaryActorTick.bCanEverTick = true;
|
PrimaryActorTick.bCanEverTick = true;
|
||||||
PrimaryActorTick.bStartWithTickEnabled = true;
|
PrimaryActorTick.bStartWithTickEnabled = true;
|
||||||
|
|
||||||
// 如果 FEffectManager 可用,在构造时创建实例
|
|
||||||
#if HAS_EFFECT_MANAGER
|
|
||||||
EffectManagerPtr = MakeUnique<FEffectManager>();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@@ -66,19 +52,13 @@ void ASystemDriver::BeginPlay()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// --- 初始化 EffectManager ---
|
// --- 初始化 EffectManager ---
|
||||||
#if HAS_EFFECT_MANAGER
|
|
||||||
if (EffectManagerPtr.IsValid())
|
|
||||||
{
|
{
|
||||||
// 绑定 Effect 完成回调
|
|
||||||
FOnEffectComplete Callback;
|
FOnEffectComplete Callback;
|
||||||
Callback.BindLambda([this]() { this->OnEffectComplete(); });
|
Callback.BindLambda([this]() { this->OnEffectComplete(); });
|
||||||
EffectManagerPtr->SetOnEffectComplete(MoveTemp(Callback));
|
EffectManager.SetOnEffectComplete(MoveTemp(Callback));
|
||||||
|
|
||||||
UE_LOG(LogChildHood, Log, TEXT("SystemDriver: EffectManager 初始化完成"));
|
UE_LOG(LogChildHood, Log, TEXT("SystemDriver: EffectManager 初始化完成"));
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
UE_LOG(LogChildHood, Log, TEXT("SystemDriver: EffectManager 尚未创建(EffectManager.h 不存在)"));
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ASystemDriver::Tick(float DeltaTime)
|
void ASystemDriver::Tick(float DeltaTime)
|
||||||
@@ -87,12 +67,7 @@ void ASystemDriver::Tick(float DeltaTime)
|
|||||||
|
|
||||||
// --- Tick EffectManager ---
|
// --- Tick EffectManager ---
|
||||||
// InteractionManager 无 Tick(纯事件驱动)
|
// InteractionManager 无 Tick(纯事件驱动)
|
||||||
#if HAS_EFFECT_MANAGER
|
EffectManager.Update(DeltaTime);
|
||||||
if (EffectManagerPtr.IsValid())
|
|
||||||
{
|
|
||||||
EffectManagerPtr->Update(DeltaTime);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@@ -125,18 +100,6 @@ ASystemDriver* ASystemDriver::Get(const UObject* WorldContextObject)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// Manager 访问
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
FEffectManager& ASystemDriver::GetEffectManager()
|
|
||||||
{
|
|
||||||
checkf(EffectManagerPtr.IsValid(),
|
|
||||||
TEXT("ASystemDriver::GetEffectManager: EffectManager 未初始化。")
|
|
||||||
TEXT("请确保 EffectManager.h 已创建且 HAS_EFFECT_MANAGER == 1"));
|
|
||||||
return *EffectManagerPtr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// Effect 完成回调
|
// Effect 完成回调
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|||||||
@@ -9,11 +9,9 @@
|
|||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "GameFramework/Info.h"
|
#include "GameFramework/Info.h"
|
||||||
#include "Interaction/InteractionManager.h"
|
#include "Interaction/InteractionManager.h"
|
||||||
|
#include "Interaction/EffectManager.h"
|
||||||
#include "SystemDriver.generated.h"
|
#include "SystemDriver.generated.h"
|
||||||
|
|
||||||
// FEffectManager 由另一个子代理并行创建,此处只前向声明
|
|
||||||
class FEffectManager;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ASystemDriver
|
* ASystemDriver
|
||||||
*
|
*
|
||||||
@@ -56,23 +54,17 @@ public:
|
|||||||
FInteractionManager& GetInteractionManager() { return InteractionManager; }
|
FInteractionManager& GetInteractionManager() { return InteractionManager; }
|
||||||
const FInteractionManager& GetInteractionManager() const { return InteractionManager; }
|
const FInteractionManager& GetInteractionManager() const { return InteractionManager; }
|
||||||
|
|
||||||
/**
|
/** 获取效果管理器(值引用) */
|
||||||
* 获取效果管理器(值引用)。
|
FEffectManager& GetEffectManager() { return EffectManager; }
|
||||||
* FEffectManager 尚未创建时调用会触发链接错误,仅在 EffectManager.h 存在时使用。
|
const FEffectManager& GetEffectManager() const { return EffectManager; }
|
||||||
*/
|
|
||||||
FEffectManager& GetEffectManager();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/** 交互管理器 — 普通 C++ 值持有 */
|
/** 交互管理器 */
|
||||||
FInteractionManager InteractionManager;
|
FInteractionManager InteractionManager;
|
||||||
|
|
||||||
/**
|
/** 效果管理器 */
|
||||||
* 效果管理器 — 普通 C++ 值持有。
|
FEffectManager EffectManager;
|
||||||
* FEffectManager 定义在 Interaction/EffectManager.h 中(由另一个子代理创建)。
|
|
||||||
* 使用 unique_ptr 延迟构造,避免头文件中需要完整定义。
|
|
||||||
*/
|
|
||||||
TUniquePtr<FEffectManager> EffectManagerPtr;
|
|
||||||
|
|
||||||
// === Effect 完成回调连线 ===
|
// === Effect 完成回调连线 ===
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user