using System.Collections.Generic; using DG.Tweening; using Stary.Evo; using Stary.Evo.AudioCore; using Stary.Evo.TableTextConversion; using UnityEngine; using YooAsset; namespace Main { public interface IDigitalHuman : ISystem { void LoadKKController(Transform parent); void AddPointData(DigitalHumanPointData pointData); void SetStartState(); void SetPositionOfPoint(Transform pointTransform); void SetPositionOfPoint(); void SetIdleState(KKIdleStateParam param); void SetTalkState(AudioClip clip, List info); void SetTalkState(AudioClip clip, Sprite icon); void SetTalkState(AudioClip clip); void SetTalkState(Sprite icon); void KillTalkState(); void SetHintState(bool isContinue); void SetReactState(); void SetDigitalHumanCoord(Vector3 position, Vector3 scale); void SetEndState(); } public class DigitalHuman : AbstractSystem, IDigitalHuman { private GameObject kkController; private Transform fxFlowing; private KKFsmSystem fsmSystem; /// /// 点位位置数据 /// private List points = new List(); protected override void OnInit() { } public async void LoadKKController(Transform parent) { var package = YooAssets.TryGetPackage("Main"); if (package != null) { var handle = package.LoadAssetAsync(R.Res.Main.prefabs.kkcontroller_prefab); await handle.Task; kkController = handle.InstantiateSync(parent); fxFlowing = kkController.transform.Find("fx_spiraltrail_flowing"); fsmSystem = new KKFsmSystem(kkController); fsmSystem.AddState(new KKIdleState(fsmSystem)); fsmSystem.AddState(new KKHintState(fsmSystem)); fsmSystem.AddState(new KKGuideState(fsmSystem)); fsmSystem.AddState(new KKReactState(fsmSystem)); fsmSystem.AddState(new KKTalkState(fsmSystem)); fsmSystem.AddState(new KKRunState(fsmSystem)); fsmSystem.AddState(new KKStartState(fsmSystem)); fsmSystem.AddState(new KKEndState(fsmSystem)); fsmSystem.SetCurState(nameof(DefaultState)); } } public void AddPointData(DigitalHumanPointData pointData) { for (int i = 0; i < points.Count; i++) { if (points[i].Name != pointData.Name) { points.Add(pointData); } else { Debug.Log("UnityEvo:点位数据存在重复,数字人无法设置点位位置:" + pointData.Name); } } } /// /// 开场动画 /// public void SetStartState() { fsmSystem.SetCurState(nameof(KKStartState)); } /// /// 设置到达点位位置 /// public void SetPositionOfPoint(Transform pointTransform) { fsmSystem.SetCurState(nameof(KKGuideState), pointTransform); } /// /// 设置到达点位位置 /// public void SetPositionOfPoint() { if (points.Count > 0) { int index = -1; for (int i = 0; i < points.Count; i++) { if (AppConfig.PackageDomainName == points[i].Name) { index = i; break; } } if (index != -1 && index + 1 < points.Count) { fsmSystem.SetCurState(nameof(KKGuideState), points[index + 1].pointTransform); } } } /// /// 设置idle站立状态 /// /// 是否指引玩家靠近 public void SetIdleState(KKIdleStateParam param) { fsmSystem.SetCurState(nameof(KKIdleState), (object)param); } /// /// 设置讲解状态 /// public void SetTalkState(AudioClip clip, Sprite icon) { fsmSystem.SetCurState(nameof(KKTalkState), clip, icon); } public void SetTalkState(AudioClip clip) { fsmSystem.SetCurState(nameof(KKTalkState), clip, (Sprite)null); } public void SetTalkState(Sprite icon) { fsmSystem.SetCurState(nameof(KKTalkState), (AudioClip)null, icon); } /// /// 设置讲解状态 /// public void SetTalkState(AudioClip clip, List info) { fsmSystem.SetCurState(nameof(KKTalkState), clip, info); } /// /// 强制打断讲解状态 /// public void KillTalkState() { AudioCoreManager.StopVoice(); fsmSystem.CloseImage(); fsmSystem.CloseText(); } /// /// 设置问答反馈状态 /// /// 正确还是错误 public void SetHintState(bool isContinue) { fsmSystem.SetCurState(nameof(KKHintState), (object)isContinue); } /// /// 设置鼓掌状态 /// public void SetReactState() { fsmSystem.SetCurState(nameof(KKReactState)); } /// /// 设置虚拟人坐标 /// /// /// public void SetDigitalHumanCoord(Vector3 position, Vector3 scale) { fsmSystem.SetCurState(nameof(KKRunState)); kkController.transform.DOMove(position, 2f).OnComplete(() => { fsmSystem.SetCurState(nameof(KKIdleState), (object)KKIdleStateParam.NotVoice); }); kkController.transform.DOScale(scale, 2f); if (fxFlowing != null) fxFlowing.transform.DOScale(scale, 2f); } public void SetEndState() { fsmSystem.SetCurState(nameof(KKEndState)); } public override void Dispose() { fsmSystem = null; if (kkController != null) { GameObject.Destroy(kkController); kkController = null; } } } }