341 lines
10 KiB
C#
341 lines
10 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);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 等待已在播放的 Timeline 结束(不重新从头播放)。
|
|
/// </summary>
|
|
public IEnumerator WaitTimelineAsync(string timelineName)
|
|
{
|
|
var (directorName, _) = ParseTimelineName(timelineName);
|
|
if (!_timelineDict.TryGetValue(directorName, out var directorHandler))
|
|
{
|
|
Debug.LogError($"Timeline {timelineName} not found (directorName: {directorName})");
|
|
yield break;
|
|
}
|
|
|
|
yield return directorHandler.WaitUntilStoppedAsync();
|
|
}
|
|
|
|
#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
|
|
}
|
|
}
|