using System.Collections; using System.Collections.Generic; using UnityEngine; using ChivaXR; using Sirenix.OdinInspector; using System.Linq; using System.Text.RegularExpressions; using UnityEngine.Events; /// /// UnityAnimation动画片段创建器 /// public class UnityAnimationDataCreator : SerializedMonoBehaviour { public Animation targetAnimation; [TableList(MaxScrollViewHeight = 300, ShowPaging = true, NumberOfItemsPerPage = 10)] public List animationDatas = new List(); /// /// 临时存储动画片段名称 /// private List tempData = new List(); public UnityAction EnterCurrentAniData; [ShowIf("IsCreatData")] [Button("创建当前Animation的Data列表")] public void CreatorAnimationDatas() { tempData.Clear(); foreach (AnimationState state in targetAnimation) { tempData.Add(state.name); } IOrderedEnumerable recordDataEnumerables = tempData.OrderBy( x => float.Parse(Regex.Match(x, "\\d+(\\.?\\d?)").Value)); foreach (var item in recordDataEnumerables) { AniData tempData = new GameObject("").AddComponent(); tempData.transform.parent = this.transform; AniDriver_UnityAnimation tempAniDriver = new AniDriver_UnityAnimation(); tempAniDriver.animation = targetAnimation; tempAniDriver.aniName = item; tempAniDriver.animationSequence = AnimationSequence.waitFinished; tempData.AnimationDriverDatas.Add(tempAniDriver); tempData.aniName = targetAnimation.name + "/" + item; tempData.aniDescriptioin = "播放动画" + tempData.aniName; tempData.gameObject.name = tempData.aniName; animationDatas.Add(new AniDataContainer(tempData)); } } public bool IsCreatData() { return animationDatas.Count == 0; } /// /// 播放 /// /// public void SetAniDataState(string aniDataName, Animation_State aniState) { if (animationDatas.Where(s => s.AniDataName == aniDataName).Count() > 0) { AniDataContainer tempAniData = animationDatas.Where(s => s.AniDataName == aniDataName).First(); switch (aniState) { case Animation_State.initState: tempAniData.aniData.SetInitState(); break; case Animation_State.finishedState: tempAniData.aniData.SetFinishedState(); break; } } else { Debug.LogError("无该动画片段--->" + aniDataName); } } private IEnumerable GetAnimationDataNames() { return animationDatas.Select(s => new ValueDropdownItem(s.AniDataName, s.AniDataName)); } #region AnimationStateController /// /// 当前步骤在List中的索引(从0开始) /// public int CurrentListID { get { if ((currentStepID - 1) >= 0 && ((currentStepID - 1) < CurrentListsCount)) { return currentStepID - 1; } Debug.LogError("当前步骤超出List范围"); return 0; } } /// /// 当前List步骤数量 /// public int CurrentListsCount { get { return animationDatas.Count; } } [HorizontalGroup("JumpState")] [Button("上一步")] public void PreProcess() { JumpProcess(currentStepID - 1); } [HorizontalGroup("JumpState")] [Button("下一步")] public void EnterNextProcess() { JumpProcess(currentStepID + 1); } [HorizontalGroup("JumpState")] [Button("初始化动画组")] /// ///初始化步骤状态 /// public void InitStepState() { for (int i = animationDatas.Count - 1; i >= 0; i--) { SetAniDataState(animationDatas[i].AniDataName, Animation_State.initState); } Debug.Log("初始化跳转至第一步"); currentStepID = 1; RefreshAniData(); } [Button("播放当前动画")] public void PlayCurrentAniData() { animationDatas[CurrentListID].aniData.PlayData(); } [HorizontalGroup("JumpAni")] [ValueDropdown("GetProcessAniDataNames")] public string jumpTargetAnimation; private IEnumerable GetProcessAniDataNames() { return animationDatas.Select(s => new ValueDropdownItem(s.AniDataName, s.AniDataName)); } [HorizontalGroup("JumpAni")] [Button("跳转到对应动画")] public void JumpToTargetAnimation() { JumpProcess(jumpTargetAnimation); } [BoxGroup("目前动画信息")] [GUIColor(0.7f, 1, 0.7f)] public GameObject currentAniDataContainer; [BoxGroup("目前动画信息")] [GUIColor(0.7f, 1, 0.7f)] [ReadOnly] /// /// 当前步骤(从1开始) /// public int currentStepID = 1; [BoxGroup("目前动画信息")] public string currentAniClipName; [BoxGroup("目前动画信息")] [Range(0, 1)] [OnValueChanged("AniDataProcessChange")] public float currentAniDataProcess; [BoxGroup("目前动画信息")] [ReadOnly] public int currentAniFrame; public void AniDataProcessChange() { if (targetAnimation == null) return; AnimationState aniState = targetAnimation[currentAniClipName]; aniState.enabled = true; aniState.speed = 0; aniState.weight = 1; aniState.normalizedTime = currentAniDataProcess; targetAnimation.Sample(); aniState.enabled = false; float totalFrame = aniState.length / (1 / aniState.clip.frameRate); currentAniFrame = Mathf.RoundToInt((totalFrame * aniState.normalizedTime) % totalFrame); } /// /// 刷新当前播放信息 /// private void RefreshAniData() { currentAniDataContainer = GameObject.Find(animationDatas[currentStepID - 1].AniDataName); currentAniClipName = animationDatas[currentStepID - 1].AniDataName.Split('/')[1]; currentAniDataProcess = 0; currentAniFrame = 0; } /// /// 跳步 /// public void JumpProcess(int targetStepID) { //步骤错误 if (targetStepID < 1 || targetStepID > CurrentListsCount) { Debug.LogError("流程跳转:无目标步骤"); return; } if (targetStepID == currentStepID) { SetAniDataState(animationDatas[CurrentListID].AniDataName, Animation_State.initState); } //向前跳步 else if (targetStepID < currentStepID) { for (int i = currentStepID - 1; i >= targetStepID - 1; i--) { SetAniDataState(animationDatas[i].AniDataName, Animation_State.initState); } } //向后跳步 else { for (int i = currentStepID - 1; i <= targetStepID - 1; i++) { if (i.Equals(targetStepID - 1)) { SetAniDataState(animationDatas[i].AniDataName, Animation_State.initState); } else { SetAniDataState(animationDatas[i].AniDataName, Animation_State.finishedState); } } } currentStepID = targetStepID; RefreshAniData(); EnterCurrentAniData?.Invoke(animationDatas[CurrentListID].aniData); } /// /// 跳步 /// /// 目标步骤ID /// 是否在编辑器状态下 /// 是否执行当前步骤 public void JumpProcess(string aniName) { int targetStepID = 0; if (animationDatas.Where(s => s.AniDataName == aniName).Count() > 0) { AniDataContainer tempAniData = animationDatas.Where(s => s.AniDataName == aniName).First(); targetStepID = animationDatas.IndexOf(tempAniData)+1; } else { return; } //步骤错误 if (targetStepID < 1 || targetStepID > CurrentListsCount) { Debug.LogError("流程跳转:无目标步骤"); return; } if (targetStepID == currentStepID) { SetAniDataState(animationDatas[CurrentListID].AniDataName, Animation_State.initState); } //向前跳步 else if (targetStepID < currentStepID) { for (int i = currentStepID - 1; i >= targetStepID - 1; i--) { SetAniDataState(animationDatas[i].AniDataName, Animation_State.initState); } } //向后跳步 else { for (int i = currentStepID - 1; i <= targetStepID - 1; i++) { if (i.Equals(targetStepID - 1)) { SetAniDataState(animationDatas[i].AniDataName, Animation_State.initState); } else { SetAniDataState(animationDatas[i].AniDataName, Animation_State.finishedState); } } } currentStepID = targetStepID; RefreshAniData(); EnterCurrentAniData?.Invoke(animationDatas[CurrentListID].aniData); } #endregion }