using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEditor; using System.Linq; using System.Text.RegularExpressions; namespace ChivaXR { /// /// Animation组件编辑状态(Scene运行) /// public class AnimationEditorWindows : EditorWindow { [MenuItem("ChivaTool/AniEditor& &#I")] public static void ShowWindows() { EditorWindow.GetWindow().Show(); } public Animation _animation; //片段 public float AnimationMaxFrame { get { if (!_animation) return 0; return _animation.clip.length * _animation.clip.frameRate; } } public float _minValue = 0; //区间最小值 public float _maxValue = 1; //区间最大值 public int _minFrame; //区间最小值帧数 public int _maxFrame; //区间最大值帧数 public float _value; //Clip片段指定Value public bool _isStartAni; //是否开启动画控制 List animationClipNames = new List(); private void OnEnable() { EditorApplication.update += EditorStateUpdate; } private void OnDisable() { EditorApplication.update -= EditorStateUpdate; } public void OnGUI() { EditorGUILayout.Space(); this._animation = EditorGUILayout.ObjectField("", this._animation, typeof(Animation), true) as Animation; _minFrame = Mathf.Clamp(EditorGUILayout.IntField("StartFrame:", _minFrame), 0, Mathf.FloorToInt(AnimationMaxFrame)); _maxFrame = Mathf.Clamp(EditorGUILayout.IntField("EndFrame:", _maxFrame), 0, Mathf.FloorToInt(AnimationMaxFrame)); UpdateFrameToValue(); EditorGUILayout.MinMaxSlider("动画区间选择", ref _minValue, ref _maxValue, 0, 1); UpdateValueToFrame(); _value = EditorGUILayout.Slider("动画区间进度", _value, _minValue, _maxValue); EditorGUILayout.TextField("动画名称:" + GetCurrentClipName() + "----当前帧:" + GetCurrentFrame() ); GUILayout.BeginHorizontal(); if (GUILayout.Button("上一片段")) { if (CheckClipNames() && animationClipNames.IndexOf(this._animation.clip.name) > 0) { this._animation.clip = this._animation[animationClipNames[animationClipNames.IndexOf(this._animation.clip.name) - 1]].clip; _minFrame = 0; _maxFrame = Mathf.FloorToInt(AnimationMaxFrame); } } if (GUILayout.Button("下一片段")) { if (CheckClipNames() && animationClipNames.IndexOf(this._animation.clip.name) < animationClipNames.Count - 1) { this._animation.clip = this._animation[animationClipNames[animationClipNames.IndexOf(this._animation.clip.name) + 1]].clip; _minFrame = 0; _maxFrame = Mathf.FloorToInt(AnimationMaxFrame); } } GUILayout.EndHorizontal(); if (!_isStartAni) { if (GUILayout.Button("开启动画控制器")) { _isStartAni = true; } } else { if (GUILayout.Button("关闭动画控制器")) { _isStartAni = false; } } } public void UpdateValueToFrame() { if (!_animation) return; _minFrame = Mathf.RoundToInt(AnimationMaxFrame * _minValue); _maxFrame = Mathf.RoundToInt(AnimationMaxFrame * _maxValue); } public bool CheckClipNames() { if (this._animation == null) return false; if (this._animation && this.animationClipNames.Count > 0) return true; animationClipNames.Clear(); foreach (AnimationState state in this._animation) { animationClipNames.Add(state.name); } animationClipNames = animationClipNames.OrderBy( x => float.Parse(Regex.Match(x, "\\d+(\\.?\\d?)").Value)).ToList(); return true; } public void UpdateFrameToValue() { if (!_animation) return; _minValue = _minFrame / AnimationMaxFrame; _maxValue = _maxFrame / AnimationMaxFrame; } private void EditorStateUpdate() { SetCurrentAni(); } public void SetCurrentAni() { if (_animation == null || !_isStartAni) return; AnimationState aniState = _animation[_animation.clip.name]; aniState.enabled = true; aniState.speed = 0; aniState.weight = 1; aniState.normalizedTime = _value; _animation.Sample(); aniState.enabled = false; } public int GetCurrentFrame() { if (!_animation) { return 0; } return Mathf.RoundToInt(AnimationMaxFrame * _value); } public string GetCurrentClipName() { if(!_animation) { return ""; } return _animation.clip.name; } } }