162 lines
4.9 KiB
C#
162 lines
4.9 KiB
C#
using System;
|
||
using System.Threading;
|
||
using Cysharp.Threading.Tasks;
|
||
using Newtonsoft.Json;
|
||
using UnityEngine;
|
||
|
||
namespace Stary.Evo.StoryEditor
|
||
{
|
||
/// <summary>
|
||
/// 剧本播放器
|
||
/// </summary>
|
||
public static class ScriptPlayer
|
||
{
|
||
/// <summary>
|
||
/// 资源加载工具
|
||
/// </summary>
|
||
private static IResource _loader;
|
||
|
||
/// <summary>
|
||
/// 动画单次时长
|
||
/// </summary>
|
||
private const float AnimationTime = 0.2f;
|
||
/// <summary>
|
||
/// 刷新帧率
|
||
/// </summary>
|
||
private const float UpdateInterval = 0.02f;
|
||
|
||
/// <summary>
|
||
/// 字幕组件
|
||
/// </summary>
|
||
private static SpriteRenderer _caption;
|
||
/// <summary>
|
||
/// 音频组件
|
||
/// </summary>
|
||
private static AudioSource _audio;
|
||
|
||
/// <summary>
|
||
/// 当前执行的剧本
|
||
/// </summary>
|
||
private static GraphPlayer _graph;
|
||
|
||
/// <summary>
|
||
/// 初始化剧本播放器
|
||
/// </summary>
|
||
/// <param name="loader">资源加载工具</param>
|
||
/// <param name="audio">音频组件</param>
|
||
/// <param name="caption">字幕组件</param>
|
||
public static void Init(IResource loader, AudioSource audio = null, SpriteRenderer caption = null)
|
||
{
|
||
_loader = loader;
|
||
_caption = caption;
|
||
_audio = audio;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 释放资源
|
||
/// </summary>
|
||
public static void Release()
|
||
{
|
||
_loader = null;
|
||
_caption = null;
|
||
_audio = null;
|
||
Resources.UnloadUnusedAssets();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 播放剧本
|
||
/// </summary>
|
||
/// <param name="packageID">包体ID</param>
|
||
/// <param name="scriptName">剧本名称(不用加_txt后缀)</param>
|
||
public static async UniTask Play(string packageID, string scriptName)
|
||
{
|
||
// 资源加载工具排空
|
||
if (_loader == null)
|
||
{
|
||
Debug.LogError("资源加载工具未准备好");
|
||
return;
|
||
}
|
||
|
||
// 加载剧本
|
||
ResourcePathData path = new(packageID,scriptName);
|
||
var json = await _loader.Load<TextAsset>(path);
|
||
var scriptData = JsonConvert.DeserializeObject<GraphData>(json.text, new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All });
|
||
if (scriptData == null)
|
||
{
|
||
Debug.LogError($"剧本加载失败:[{path.packageID}]{path.path}");
|
||
return;
|
||
}
|
||
|
||
// 解析并执行剧本
|
||
_graph = new(scriptData, _loader);
|
||
await _graph.Execute();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 播放剧本段落
|
||
/// </summary>
|
||
/// <param name="para">段落数据</param>
|
||
/// <param name="ct">CT</param>
|
||
public static async UniTask PlayScriptPara(ScriptParagraphNodePlayer para, CancellationToken ct)
|
||
{
|
||
// 设置变量
|
||
if (_caption)
|
||
_caption.sprite = await _loader.Load<Sprite>(para.CaptionPath);
|
||
if (_audio)
|
||
_audio.clip = await _loader.Load<AudioClip>(para.AudioPath);
|
||
|
||
// 淡入
|
||
await SetCaptionColor(1,ct);
|
||
|
||
// 等音频播放完
|
||
if (_audio)
|
||
{
|
||
_audio.Play();
|
||
await UniTask.Delay(TimeSpan.FromSeconds(_audio.clip.length), cancellationToken:ct);
|
||
}
|
||
|
||
// 淡出
|
||
await SetCaptionColor(0, ct);
|
||
await UniTask.Delay(TimeSpan.FromSeconds(AnimationTime), cancellationToken:ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 停止剧本
|
||
/// </summary>
|
||
public static async UniTask Stop()
|
||
{
|
||
_graph.Stop();
|
||
|
||
await SetCaptionColor(0, CancellationToken.None);
|
||
|
||
ReleaseGraph();
|
||
}
|
||
|
||
public static void ReleaseGraph() => _graph = null;
|
||
|
||
private static async UniTask DoAnim(Action animAction, CancellationToken ct)
|
||
{
|
||
float time = 0;
|
||
while (time < AnimationTime)
|
||
{
|
||
animAction?.Invoke();
|
||
await UniTask.Delay(TimeSpan.FromSeconds(UpdateInterval), cancellationToken: ct);
|
||
time+=UpdateInterval;
|
||
}
|
||
}
|
||
|
||
private static async UniTask SetCaptionColor(int alpha, CancellationToken ct)
|
||
{
|
||
var isAdd = alpha > _caption.color.a;
|
||
|
||
var speed = Mathf.Abs(_caption.color.a - alpha) / AnimationTime * UpdateInterval;
|
||
if (speed == 0)
|
||
return;
|
||
|
||
await DoAnim(() =>
|
||
{
|
||
_caption.color = new(1, 1, 1, _caption.color.a + (isAdd ? speed : -speed));
|
||
}, ct);
|
||
}
|
||
}
|
||
} |