using System; using System.Threading; using Cysharp.Threading.Tasks; using DG.Tweening; using Newtonsoft.Json; using UnityEngine; namespace Stary.Evo.StoryEditor { /// /// 剧本播放器 /// public static class ScriptPlayer { /// /// 资源加载工具 /// private static IResource _loader; /// /// 动画单次时长 /// private const float AnimationTime = 0.2f; /// /// 字幕组件 /// private static SpriteRenderer _caption; /// /// 音频组件 /// private static AudioSource _audio; /// /// 当前执行的剧本 /// private static GraphPlayer _graph; /// /// 初始化剧本播放器 /// /// 资源加载工具 /// 音频组件 /// 字幕组件 public static void Init(IResource loader, AudioSource audio = null, SpriteRenderer caption = null) { _loader = loader; _caption = caption; _audio = audio; } /// /// 释放资源 /// public static void Release() { _loader = null; _caption = null; _audio = null; Resources.UnloadUnusedAssets(); } /// /// 播放剧本 /// /// 包体ID /// 剧本名称(不用加_txt后缀) 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(path); var scriptData = JsonConvert.DeserializeObject(json.text, new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All }); if (scriptData == null) { Debug.LogError($"剧本加载失败:[{path.packageID}]{path.path}"); return; } // 解析并执行剧本 _graph = new(scriptData, _loader); await _graph.Execute(); } /// /// 播放剧本段落 /// /// 段落数据 /// CT public static async UniTask PlayScriptPara(ScriptParagraphNodePlayer para, CancellationToken ct) { // 设置变量 if (_caption) _caption.sprite = await _loader.Load(para.CaptionPath); if (_audio) _audio.clip = await _loader.Load(para.AudioPath); // 淡入 _caption?.DOColor(Color.white, AnimationTime); _audio?.DOFade(1, AnimationTime); await UniTask.Delay(TimeSpan.FromSeconds(AnimationTime), cancellationToken:ct); // 等音频播放完 if (_audio) { _audio.Play(); await UniTask.Delay(TimeSpan.FromSeconds(_audio.clip.length), cancellationToken:ct); } // 淡出 _caption?.DOColor(Color.clear, AnimationTime); _audio?.DOFade(0, AnimationTime); await UniTask.Delay(TimeSpan.FromSeconds(AnimationTime), cancellationToken:ct); } /// /// 停止剧本 /// public static async UniTask Stop() { _graph.Stop(); var hasAnim = false; if (_caption && _caption.color != Color.clear) { _caption?.DOColor(Color.clear, AnimationTime); hasAnim = true; } if (_audio && _audio.volume > 0) { _audio?.DOFade(0, AnimationTime); hasAnim = true; } if(hasAnim) await UniTask.Delay(TimeSpan.FromSeconds(AnimationTime)); ReleaseGraph(); } public static void ReleaseGraph() => _graph = null; } }