Files
aibis-dream/Assets/Scripts/SceneManagement/TimelineKit/TimelineCenter.cs
T

326 lines
9.8 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using AibisDream.Kit;
using AibisDream.SaveSystem;
using UnityEngine;
namespace AibisDream
{
public class TimelineCenter : SingletonBase<TimelineCenter>, ITimelineCenter
{
private readonly Dictionary<string, DirectorHandler> _timelineDict = new();
/// <summary>
/// 私有构造函数,供单例工具使用
/// </summary>
private TimelineCenter() { }
public void RegisterDirector(DirectorHandler directorHandler)
{
_timelineDict.Add(directorHandler.timelineName, directorHandler);
}
public void UnregisterDirector(DirectorHandler directorHandler)
{
_timelineDict.Remove(directorHandler.timelineName);
}
/// <summary>
/// 解析 timelineName,返回 (directorName, addressableKey 或 null)
/// 格式:仅 DirectorName 或 DirectorName/AddressableKey
/// </summary>
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));
}
// -------------------------- 播放控制 --------------------------
/// <summary>
/// 播放 Timeline。timelineName 支持两种格式:仅 DirectorName(播放自带)或 DirectorName/AddressableKey(从 Addressables 加载播放)
/// </summary>
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 状态查询
/// <summary>
/// 获取当前播放时间
/// </summary>
/// <param name="name">Timeline 名称</param>
/// <returns>当前播放时间</returns>
double GetPlaybackTime(string name);
/// <summary>
/// 获取总时长
/// </summary>
/// <param name="name">Timeline 名称</param>
/// <returns>总时长</returns>
double GetDuration(string name);
#endregion
#region 扩展操作
/// <summary>
/// 设置播放速度
/// </summary>
/// <param name="name">Timeline 名称</param>
/// <param name="speed">播放速度</param>
void SetPlaybackSpeed(string name, float speed);
/// <summary>
/// 跳转到指定时间点
/// </summary>
/// <param name="name">Timeline 名称</param>
/// <param name="time">时间点(秒)</param>
void SeekToTime(string name, double time);
#endregion
#region 批量操作
/// <summary>
/// 暂停所有 Timeline
/// </summary>
void PauseAll();
/// <summary>
/// 停止所有 Timeline
/// </summary>
void StopAll();
/// <summary>
/// 重置所有 Timeline
/// </summary>
void ResetAll();
#endregion
}
}