Files
ChildHood/Source/ChildHood/Interaction/EffectManager.h
T
2026-06-15 05:13:28 +08:00

131 lines
4.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// ChildHood Project - Effect Timeline 调度器(v1.1 Effect/Action 架构)
// 对应技术方案: docs/technical/交互系统-技术方案.md 第3节(类设计)+ 第6节(复杂接口描述)
// 职责:Effect Timeline 调度、Action 执行分发、TurnToTarget 插值、WaitForInput 暂停机制
// 注意:普通 C++ 类,非 UObject,由 ASystemDriver 持有并 Tick 驱动
#pragma once
#include "CoreMinimal.h"
#include "InteractionTypes.h"
class APushCameraActor;
/**
* FEffectManager
*
* Effect Timeline 调度器,管理一次交互 Effect 的完整生命周期:
* - 按 TriggerTime 依次触发各 Action
* - 维护 TurnToTarget 跨帧插值
* - 支持 WaitForInput 暂停/恢复机制
* - 支持取消(CancelEffect)
* - Effect 结束时通过 OnEffectComplete 回调通知上层
*
* 生命周期:由 ASystemDriver 在 BeginPlay 中构造,每帧由 ASystemDriver::Tick 调用 Update。
*/
class FEffectManager
{
public:
// === 公开接口 ===
/** 设置完成回调(由 ASystemDriver 在 BeginPlay 中设置) */
void SetOnEffectComplete(FOnEffectComplete&& Callback);
/** 设置物品获得回调(AddToBackpack Action 执行时触发)。
* 由 ASystemDriver 绑定到 FCollectionManager::OnItemObtained(收集系统技术方案第13节)。 */
void SetOnItemAddedCallback(FOnItemAdded&& Callback);
/** 播放 Effect — 初始化状态,开始 Timeline 推进 */
void PlayEffect(const FInteractEffect& Effect, const FEffectContext& Context);
/** 取消 Effect(用户按 E/ESC) — 区分 WaitForInput 恢复 vs 强制取消 */
void CancelEffect();
/** 当前是否正在播放 Effect */
bool IsPlaying() const { return bIsPlaying; }
/** 当前是否暂停等待用户输入 */
bool IsWaitingForInput() const { return bIsWaitingForInput; }
/** 每帧更新(由 ASystemDriver::Tick 调用) */
void Update(float DeltaTime);
private:
// === Effect 状态 ===
/** 当前播放中的 Effect 数据 */
FInteractEffect CurrentEffect;
/** 当前 Effect 的运行时上下文 */
FEffectContext CurrentContext;
/** 从 Effect 开始累计的经过时间 */
float ElapsedTime = 0.f;
/** 下一个待触发的 Action 索引(Actions 按 TriggerTime 排序) */
int32 NextActionIndex = 0;
/** 是否正在播放 Effect */
bool bIsPlaying = false;
/** 是否暂停等待用户输入(ShowNarrative bWaitForInput=true 时设置) */
bool bIsWaitingForInput = false;
/** 上一次随机选取的叙事文本索引(用于避免连续重复) */
int32 LastNarrativeIndex = -1;
// === Turn 插值 ===
/** TurnToTarget 跨帧插值状态 */
FTurnState TurnState;
// === 推镜缓存 ===
/** 推镜期间 Spawn 的临时摄像机(弱引用,Effect 结束时销毁) */
TWeakObjectPtr<APushCameraActor> CachedPushCamera;
// === 回调 ===
/** Effect 完成回调(正常结束或取消后清理完毕时触发) */
FOnEffectComplete OnEffectComplete;
/** 物品获得回调(AddToBackpack Action 触发,传 ItemId/DisplayName/Category) */
FOnItemAdded OnItemAdded;
// === 内部方法 ===
/** 执行单个 Action(按 Type 分发到对应 ExecuteXxx) */
void ExecuteAction(const FInteractAction& Action);
/** Effect 正常结束 — 清理状态 + 广播回调 */
void FinishEffect();
/** 从 WaitForInput 暂停恢复 */
void ResumeFromWait();
/** 清理所有运行时状态(推镜相机、蒙太奇、转向等) */
void PerformCleanup();
/** 从 NarrativeTexts 中随机选取一条(避免与上次重复) */
FString PickRandomNarrative(const TArray<FString>& Texts);
// === 各 Action 处理 ===
void ExecuteWait(const FInteractAction& Action);
void ExecuteTurnToTarget(const FInteractAction& Action);
void ExecutePlayMontage(const FInteractAction& Action);
void ExecuteCameraPush(const FInteractAction& Action);
void ExecuteCameraReturn(const FInteractAction& Action);
void ExecuteConsume();
void ExecuteHideActor();
void ExecuteShowActor();
void ExecuteShowNarrative(const FInteractAction& Action);
void ExecuteHideNarrative();
void ExecuteShowPickupNotification();
void ExecuteToggleDoor();
/** 更新 TurnToTarget 跨帧插值(在 Update 末尾调用) */
void UpdateTurn(float DeltaTime);
};