4fc4a39aa6
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
131 lines
4.2 KiB
C++
131 lines
4.2 KiB
C++
// 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);
|
||
};
|