149 lines
4.5 KiB
C#
149 lines
4.5 KiB
C#
|
|
using System;
|
|||
|
|
using System.Threading;
|
|||
|
|
using Cysharp.Threading.Tasks;
|
|||
|
|
using DG.Tweening;
|
|||
|
|
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 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);
|
|||
|
|
|
|||
|
|
// 淡入
|
|||
|
|
_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);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 停止剧本
|
|||
|
|
/// </summary>
|
|||
|
|
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;
|
|||
|
|
}
|
|||
|
|
}
|