过场 Timeline
配置驱动的过场 / 时间线播放队列。框架只提供骨架,真正的播放要宿主实现——一句话:一个 FIFO 队列 + 一个 NotifyFinished() 回调契约。
命名空间 HYC.Framework.Timeline。运行期骨架已实现(Runtime/CutsceneDirector.cs)。
◈
实现状态说明:运行时的
CutsceneDirector 队列骨架已实现(含 Pause/Resume/Interrupt/Priority/Loop,源码实证)。可视化轨道编辑器尚未开发(属 51 号设计稿,类名均不存在于仓库)——框架没有可视化编辑器、也不创作轨道 / 片段级内容,轨道仍由宿主用 Unity Timeline 自己做。核心类
| 类 | 职责 |
|---|---|
Cutscene(sealed class) | 单个过场实例:Id / Name / AssetKey(Addressable key)/ Loop / OnFinished |
CutsceneDirector | FIFO 队列 + 播放契约:IsPlaying / Current / CutsceneStarted / CutsceneFinished / Play(id) / Enqueue / PlayClip(protected virtual,宿主必须重写)/ NotifyFinished / Skip / Clear |
接入方式
public class MyCutsceneDirector : CutsceneDirector
{
private PlayableDirector _director;
// 1. 用配置表解析 id → AssetKey(门面是唯一查询入口;未命中抛 KeyNotFoundException)
public override void Play(long id)
{
ref var row = ref ConfigManager.CutsceneRow.GetByID(id); // ⛔ 必须 ref 接收(EA0001)
Enqueue(new Cutscene
{
Id = id,
Name = row.Name,
AssetKey = row.AssetKey,
Loop = row.Loop,
OnFinished = () => Debug.Log($"cut {id} done"),
});
}
// 2. 真正播放
protected override void PlayClip(Cutscene clip)
{
Addressables.LoadAssetAsync<PlayableDirector>(clip.AssetKey).Completed += h =>
{
_director = h.Result;
_director.stopped += _ => NotifyFinished(); // ← 关键
_director.Play();
};
}
}
var director = new MyCutsceneDirector();
director.CutsceneStarted += c => UIManager.HideAllUI();
director.CutsceneFinished += c => UIManager.ShowAllUI();
director.Play(1001);
director.Play(1002); // 排队,1001 播完自动接上
director.Skip(); // 跳过当前,直接进下一个
director.Clear(); // 全部取消
坑
PlayClip的默认实现只是Debug.Log——不重写就永远不会有NotifyFinished,队列会卡在第一条(IsPlaying恒为 true)。Play(long id)默认只填Id和Name,AssetKey是空的——必须重写它去查配置表,或者直接用Enqueue。Skip()只在IsPlaying时有效,空闲时调用是空操作。NotifyFinished在Current == null时直接 return——重复调用安全。- 生命周期归宿主:加载 / 卸载
PlayableDirector资产由你自己管(与 ECS UI 同策略)。