using System; using System.Collections; using System.Collections.Generic; using AibisDream.Kit; using AibisDream.SaveSystem; using UnityEngine; namespace AibisDream { public class TimelineCenter : SingletonBase, ITimelineCenter { private readonly Dictionary _timelineDict = new(); /// /// 私有构造函数,供单例工具使用 /// private TimelineCenter() { } public void RegisterDirector(DirectorHandler directorHandler) { _timelineDict.Add(directorHandler.timelineName, directorHandler); } public void UnregisterDirector(DirectorHandler directorHandler) { _timelineDict.Remove(directorHandler.timelineName); } /// /// 解析 timelineName,返回 (directorName, addressableKey 或 null) /// 格式:仅 DirectorName 或 DirectorName/AddressableKey /// private static (string directorName, string addressableKey) ParseTimelineName(string timelineName) { var idx = timelineName.IndexOf('/'); if (idx < 0) return (timelineName, null); return (timelineName.Substring(0, idx), timelineName.Substring(idx + 1)); } // -------------------------- 播放控制 -------------------------- /// /// 播放 Timeline。timelineName 支持两种格式:仅 DirectorName(播放自带)或 DirectorName/AddressableKey(从 Addressables 加载播放) /// public void PlayTimeline(string timelineName) { var (directorName, addressableKey) = ParseTimelineName(timelineName); if (!_timelineDict.TryGetValue(directorName, out var directorHandler)) { Debug.LogError($"Timeline {timelineName} not found (directorName: {directorName})"); return; } directorHandler.gameObject.SetActive(true); if (addressableKey == null) { directorHandler.Play(); } else { directorHandler.PlayFromAddressable(addressableKey); } } public IEnumerator PlayTimelineAsync(string name) { var (directorName, addressableKey) = ParseTimelineName(name); if (!_timelineDict.TryGetValue(directorName, out var directorHandler)) { Debug.LogError($"Timeline {name} not found (directorName: {directorName})"); yield break; } directorHandler.gameObject.SetActive(true); if (addressableKey == null) { yield return directorHandler.PlayAsync(); } else { yield return directorHandler.PlayFromAddressableAsync(addressableKey); } } public void StopTimeline(string timelineName) { var (directorName, _) = ParseTimelineName(timelineName); if (!_timelineDict.TryGetValue(directorName, out var directorHandler)) { Debug.LogError($"Timeline {timelineName} not found (directorName: {directorName})"); return; } directorHandler.Stop(); } public void PauseTimeline(string timelineName) { var (directorName, _) = ParseTimelineName(timelineName); if (!_timelineDict.TryGetValue(directorName, out var directorHandler)) { Debug.LogError($"Timeline {timelineName} not found (directorName: {directorName})"); return; } directorHandler.Pause(); } public void ResumeTimeline(string timelineName) { var (directorName, _) = ParseTimelineName(timelineName); if (!_timelineDict.TryGetValue(directorName, out var directorHandler)) { Debug.LogError($"Timeline {timelineName} not found (directorName: {directorName})"); return; } directorHandler.Resume(); } public void ResetTimeline(string timelineName) { var (directorName, _) = ParseTimelineName(timelineName); if (!_timelineDict.TryGetValue(directorName, out var directorHandler)) { Debug.LogError($"Timeline {timelineName} not found (directorName: {directorName})"); return; } directorHandler.Reset(); } public void HideTimeline(string timelineName) { var (directorName, _) = ParseTimelineName(timelineName); if (!_timelineDict.TryGetValue(directorName, out var directorHandler)) { Debug.LogError($"Timeline {timelineName} not found (directorName: {directorName})"); return; } directorHandler.gameObject.SetActive(false); } #region 状态查询 public double GetPlaybackTime(string name) { var (directorName, _) = ParseTimelineName(name); if (!_timelineDict.TryGetValue(directorName, out var directorHandler)) { Debug.LogError($"Timeline {name} not found (directorName: {directorName})"); return 0; } return directorHandler.GetPlaybackTime(); } public double GetDuration(string name) { var (directorName, _) = ParseTimelineName(name); if (!_timelineDict.TryGetValue(directorName, out var directorHandler)) { Debug.LogError($"Timeline {name} not found (directorName: {directorName})"); return 0; } return directorHandler.GetDuration(); } #endregion #region 扩展操作 public void SetPlaybackSpeed(string name, float speed) { var (directorName, _) = ParseTimelineName(name); if (!_timelineDict.TryGetValue(directorName, out var directorHandler)) { Debug.LogError($"Timeline {name} not found (directorName: {directorName})"); return; } directorHandler.SetPlaybackSpeed(speed); } public void SeekToTime(string name, double time) { var (directorName, _) = ParseTimelineName(name); if (!_timelineDict.TryGetValue(directorName, out var directorHandler)) { Debug.LogError($"Timeline {name} not found (directorName: {directorName})"); return; } directorHandler.SeekToTime(time); } #endregion #region 批量操作 public void PauseAll() { foreach (var directorHandler in _timelineDict.Values) { directorHandler.Pause(); } } public void StopAll() { foreach (var directorHandler in _timelineDict.Values) { directorHandler.Stop(); } } public void ResetAll() { foreach (var directorHandler in _timelineDict.Values) { directorHandler.Reset(); } } #endregion public TimelineSnapshotDto CaptureSnapshot() { var dto = new TimelineSnapshotDto(); foreach (var handler in _timelineDict.Values) { dto.entries.Add(handler.CaptureSnapshotEntry()); } return dto; } public IEnumerator RestoreSnapshotAsync(TimelineSnapshotDto dto) { if (dto?.entries == null) yield break; foreach (var entry in dto.entries) { if (!_timelineDict.TryGetValue(entry.directorName, out var handler)) { continue; } yield return handler.RestoreSnapshotEntryAsync(entry); } } } public interface ITimelineCenter { void PlayTimeline(string timelineName); IEnumerator PlayTimelineAsync(string name); void StopTimeline(string timelineName); void PauseTimeline(string timelineName); void ResumeTimeline(string timelineName); void ResetTimeline(string timelineName); #region 状态查询 /// /// 获取当前播放时间 /// /// Timeline 名称 /// 当前播放时间 double GetPlaybackTime(string name); /// /// 获取总时长 /// /// Timeline 名称 /// 总时长 double GetDuration(string name); #endregion #region 扩展操作 /// /// 设置播放速度 /// /// Timeline 名称 /// 播放速度 void SetPlaybackSpeed(string name, float speed); /// /// 跳转到指定时间点 /// /// Timeline 名称 /// 时间点(秒) void SeekToTime(string name, double time); #endregion #region 批量操作 /// /// 暂停所有 Timeline /// void PauseAll(); /// /// 停止所有 Timeline /// void StopAll(); /// /// 重置所有 Timeline /// void ResetAll(); #endregion } }