Files
Main/Assets/Editor/DIY/AnimPlayEditor/AnimPlayEditor.cs

334 lines
12 KiB
C#
Raw Permalink Normal View History

2025-01-25 04:38:09 +08:00
using Thousandto.Launcher.ExternalLibs;
using System;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;
using UnityEngine.Animations;
using UnityEngine.Playables;
namespace Thousandto.DIY.UniScene
{
public class AnimPlayEditor : EditorWindow
{
[MenuItem("Window/PlayableAnimation &6")]
static void Open()
{
var win = (AnimPlayEditor)EditorWindow.GetWindow(typeof(AnimPlayEditor));
win.Show();
}
private const float FrameWidthMaxScale = 1f;
private const float FrameWidthMinScale = 0.3f;
private float _curFrameWidthScale = 1f;
private int _curSelectFrame = 0;
private Vector2 _scrollPos = Vector2.zero;
private const int PageFrameCount = 301;
private AnimationClip _curSelectClip = null;
private AnimListScript _curPlayAnim = null;
private bool _isPlaying = false;
private float _playTimer = 0f;
private string[] _animNameList = new string[] { "1111", "2222"};
private List<AnimationClip> _animList = null;
private int _curSelectIndex = 0;
private bool _draging = false;
private PlayableGraph _graph;
private AnimationPlayableOutput _output;
private AnimationClipPlayable _animPlayable;
#region//属性
private float CurFrameWidth
{
get
{
return _curFrameWidthScale * 20;
}
}
public static bool IsOpen { get; private set; }
#endregion
private void CreatePlayable()
{
if(_graph.IsValid())
{
_graph.Destroy();
}
var animator = _curPlayAnim.GetComponent<Animator>();
_graph = PlayableGraph.Create();
_output = AnimationPlayableOutput.Create(_graph, "output", animator);
_graph.SetTimeUpdateMode(DirectorUpdateMode.Manual);
}
private void SetPlayClip(AnimationClip clip)
{
if(_animPlayable.IsValid())
{
_animPlayable.Destroy();
}
_curSelectClip = clip;
_curSelectClip.legacy = false;
_animPlayable = AnimationClipPlayable.Create(_graph, clip);
_output.SetSourcePlayable(_animPlayable);
}
private void OnClipGUI()
{
var clipFrameCount = (int)(_curSelectClip.length / (1f / 30f));
_scrollPos = GUILayout.BeginScrollView(_scrollPos, true, false);
int drawFrameCount = Math.Max(PageFrameCount, clipFrameCount);
var spaceCount = (int)(CurFrameWidth * drawFrameCount);
GUILayout.Box("", GUILayout.Width(spaceCount + 30));
Vector2 size = new Vector2(2, 50);
Vector2 pos = Vector2.zero;
Rect boxRect = new Rect();
Rect textRect = new Rect();
textRect.size = new Vector2(30, 20);
GUIStyle textStyle = new GUIStyle();
textStyle.alignment = TextAnchor.MiddleCenter;
GUIStyle eventStyle = new GUIStyle();
eventStyle.alignment = TextAnchor.MiddleCenter;
eventStyle.fontSize = 10;
int diffIndex = Mathf.RoundToInt(24f / CurFrameWidth);
for (int i = 0; i < drawFrameCount; ++i)
{
pos.x = i * CurFrameWidth + 10;
textRect.position = new Vector2(pos.x - 15, 0);
if (i % 5 == 0)
{
GUI.Label(textRect, i.ToString(), textStyle);
boxRect.size = new Vector2(2, 240);
pos.y = 20;
boxRect.position = pos;
}
else
{
pos.y = 25;
boxRect.size = new Vector2(2, 230);
boxRect.position = pos;
}
if (i < clipFrameCount)
{
GUI.color = Color.white;
}
else
{
GUI.color = Color.black;
}
GUI.Box(boxRect, string.Empty);
pos.x -= (CurFrameWidth / 2 - 4);
boxRect.position = pos;
boxRect.size = new Vector2(CurFrameWidth, 200);
if (_draging && boxRect.Contains(Event.current.mousePosition))
{
_curSelectFrame = i;
_isPlaying = false;
}
}
GUI.color = Color.red;
boxRect.position = new Vector2(_curSelectFrame * CurFrameWidth + 10, 0);
boxRect.size = new Vector2(2, 280);
GUI.Box(boxRect, string.Empty);
GUI.color = Color.white;
GUILayout.EndScrollView();
}
private void OnGUI()
{
var selectGo = UnityEditor.Selection.activeGameObject;
if (selectGo != null)
{
var animScript = selectGo.GetComponent<AnimListScript>();
if (animScript != null)
{
if (_curPlayAnim != animScript)
{
//重新设置动作
_curPlayAnim = animScript;
CreatePlayable();
_isPlaying = false;
_animNameList = null;
//选择默认动作
var animList = _curPlayAnim.GetAnimListByEditor();
var selfAnimList = _curPlayAnim.GetSelfAnimList();
if (animList.Count > 0 || selfAnimList.Count > 0)
{
for(int i = animList.Count - 1; i >= 0; --i)
{
if (animList[i] == null)
{
animList.RemoveAt(i);
}
}
for (int i = selfAnimList.Count - 1; i >= 0; --i)
{
if (selfAnimList[i] == null)
{
selfAnimList.RemoveAt(i);
}
}
_curSelectFrame = 0;
_curSelectIndex = 0;
_animNameList = new string[animList.Count + selfAnimList.Count];
_animList = new List<AnimationClip>(animList.Count + selfAnimList.Count);
for (int i = 0; i < selfAnimList.Count; ++i)
{
_animNameList[i] = selfAnimList[i].name;
_animList.Add(selfAnimList[i]);
}
for (int i = 0; i < animList.Count; ++i)
{
_animNameList[i + selfAnimList.Count] = animList[i].name;
_animList.Add(animList[i]);
}
SetPlayClip(_animList[0]);
}
else
{
_curSelectClip = null;
}
}
}
}
switch (Event.current.type)
{
case EventType.ScrollWheel:
{
float oldScale = _curFrameWidthScale;
_curFrameWidthScale -= Event.current.delta.y * 0.05f;
if (_curFrameWidthScale > FrameWidthMaxScale)
{
_curFrameWidthScale = FrameWidthMaxScale;
}
if (_curFrameWidthScale < FrameWidthMinScale)
{
_curFrameWidthScale = FrameWidthMinScale;
}
}
break;
case EventType.MouseDown:
{
if (Event.current.button == 0)
{
//左键
_draging = true;
}
}
break;
case EventType.MouseUp:
{
if (Event.current.button == 0)
{
//左键
_draging = false;
}
}
break;
}
if (_curPlayAnim != null)
{
if (_animList != null && _animList.Count > 0)
{
if (_curSelectClip != null)
{
if (!_animList.Contains(_curSelectClip))
{
//不是自己的动作,重新设置动作
SetPlayClip(_animList[0]);
}
}
else
{
//没有动作,重新设置动作
SetPlayClip(_animList[0]);
}
}
else
{
EditorGUILayout.LabelField("动作列表为空");
//动作列表为空
_curSelectClip = null;
}
if (_animNameList != null && _animNameList.Length > 0)
{
EditorGUILayout.BeginHorizontal();
var newSelect = EditorGUILayout.Popup(_curSelectIndex, _animNameList, GUILayout.Width(100));
if (_curSelectIndex != newSelect)
{
_curSelectIndex = newSelect;
SetPlayClip(_animList[_curSelectIndex]);
_isPlaying = false;
_curSelectFrame = 0;
_draging = false;
}
if(!_isPlaying)
{
if (GUILayout.Button("播放", GUILayout.Width(100)))
{
_isPlaying = true;
}
}
else
{
if (GUILayout.Button("停止", GUILayout.Width(100)))
{
_isPlaying = false;
_playTimer = 0f;
}
}
EditorGUILayout.EndHorizontal();
if (_curSelectClip != null)
{
OnClipGUI();
}
}
}
else
{
EditorGUILayout.LabelField("请选择正确的AnimListScript动作组件");
}
Repaint();
}
private void Update()
{
if (_curSelectClip != null)
{
if (_isPlaying)
{
_playTimer += Time.deltaTime;
if (_playTimer > _curSelectClip.length)
{
_playTimer -= _curSelectClip.length;
}
_animPlayable.SetTime(_playTimer);
_graph.Evaluate();
_curSelectFrame = (int)(_playTimer / (1f / 30f));
}
else
{
var time = _curSelectFrame * (1f / 30f);
if (time > _curSelectClip.length)
{
time = _curSelectClip.length;
}
_animPlayable.SetTime(time);
_graph.Evaluate();
}
}
}
}
}