using BaseGames.Core.Events;
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Timeline;
namespace BaseGames.Cutscene
{
// =====================================================================
// SignalEmitterClip —— Timeline 零耦合事件桥接(架构 14 §11.6)
// =====================================================================
///
/// 在 Timeline 轨道上放置此 Clip,Clip 播放时向目标 Void 事件频道 Raise 一次事件。
/// 用途:Timeline 动画与游戏逻辑保持零耦合(不直接引用场景对象)。
/// 使用场景示例:过场第 3 秒 → 触发 EVT_BossPhase2 → BossOrchestrator 切换阶段。
///
[CreateAssetMenu(menuName = "BaseGames/Cutscene/SignalEmitterClip")]
public class SignalEmitterClip : PlayableAsset, ITimelineClipAsset
{
[Tooltip("Clip 播放时发射的目标 Void 事件频道 SO")]
[SerializeField] private VoidEventChannelSO _targetChannel;
/// Timeline 系统查询 Clip 能力(无额外能力)。
public ClipCaps clipCaps => ClipCaps.None;
public override Playable CreatePlayable(PlayableGraph graph, GameObject owner)
{
var playable = ScriptPlayable.Create(graph);
playable.GetBehaviour().Clip = this;
return playable;
}
/// 供 SignalEmitterBehaviour 内部调用,发射事件。
internal void Fire() => _targetChannel?.Raise();
}
// ─────────────────────────────────────────────────────────────────────
///
/// SignalEmitterClip 对应的 PlayableBehaviour,处理 ProcessFrame 时机。
///
public class SignalEmitterBehaviour : PlayableBehaviour
{
/// 由 CreatePlayable 注入,内部访问 Fire() 发射事件。
public SignalEmitterClip Clip;
private bool _fired;
public override void OnBehaviourPlay(Playable playable, FrameData info)
{
_fired = false; // 支持 Timeline 循环/重播时重置
}
public override void ProcessFrame(Playable playable, FrameData info, object playerData)
{
if (!_fired && Clip != null)
{
Clip.Fire();
_fired = true;
}
}
}
}