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;
}
}
}