Unity實戰之制作動畫編輯器

為瞭更方便地為UI視圖添加動畫,將動畫的編輯功能封裝在瞭UI View類中,可以通過編輯器快速的為視圖編輯動畫。動畫分為兩種類型,一種是Unity中的Animator動畫,該類型直接通過一個字符串類型變量記錄動畫State狀態的名稱即可,播放時調用Animator類中的Play方法傳入該名稱。另一種是DoTween動畫,支持視圖的移動、旋轉、縮放、淡入淡出動畫的編輯:

首先看一下動畫相關的幾個類的數據結構:

using System;
using UnityEngine;
using DG.Tweening;
 
namespace SK.Framework
{
    /// <summary>
    /// UI移動動畫
    /// </summary>
    [Serializable]
    public class UIMoveAnimation
    {
        public enum MoveMode
        {
            MoveIn,
            MoveOut
        }
        /// <summary>
        /// UI移動動畫方向
        /// </summary>
        public enum UIMoveAnimationDirection
        {
            Left,
            Right,
            Top,
            Bottom,
            TopLeft,
            TopRight,
            MiddleCenter,
            BottomLeft,
            BottomRight,
        }
        public float duration = 1f;
 
        public float delay;
 
        public Ease ease = Ease.Linear;
 
        public UIMoveAnimationDirection direction = UIMoveAnimationDirection.Left;
 
        public bool isCustom;
 
        public Vector3 startValue;
 
        public Vector3 endValue;
 
        public MoveMode moveMode = MoveMode.MoveIn;
 
        public Tween Play(RectTransform target, bool instant = false)
        {
            Vector3 pos = Vector3.zero;
            float xOffset = target.rect.width / 2 + target.rect.width * target.pivot.x;
            float yOffset = target.rect.height / 2 + target.rect.height * target.pivot.y;
            switch (direction)
            {
                case UIMoveAnimationDirection.Left: pos = new Vector3(-xOffset, 0f, 0f); break;
                case UIMoveAnimationDirection.Right: pos = new Vector3(xOffset, 0f, 0f); break;
                case UIMoveAnimationDirection.Top: pos = new Vector3(0f, yOffset, 0f); break;
                case UIMoveAnimationDirection.Bottom: pos = new Vector3(0f, -yOffset, 0f); break;
                case UIMoveAnimationDirection.TopLeft: pos = new Vector3(-xOffset, yOffset, 0f); break;
                case UIMoveAnimationDirection.TopRight: pos = new Vector3(xOffset, yOffset, 0f); break;
                case UIMoveAnimationDirection.MiddleCenter: pos = Vector3.zero; break;
                case UIMoveAnimationDirection.BottomLeft: pos = new Vector3(-xOffset, -yOffset, 0f); break;
                case UIMoveAnimationDirection.BottomRight: pos = new Vector3(xOffset, -yOffset, 0f); break;
            }
            switch (moveMode)
            {
                case MoveMode.MoveIn:
                    target.anchoredPosition3D = isCustom ? startValue : pos;
                    return target.DOAnchorPos3D(endValue, instant ? 0f : duration).SetDelay(instant ? 0f : delay).SetEase(ease);
                case MoveMode.MoveOut:
                    target.anchoredPosition3D = startValue;
                    return target.DOAnchorPos3D(isCustom ? endValue : pos, instant ? 0f : duration).SetDelay(instant ? 0f : delay).SetEase(ease);
                default: return null;
            }
        }
    }
}
using System;
using UnityEngine;
using DG.Tweening;
 
namespace SK.Framework
{
    /// <summary>
    /// UI旋轉動畫
    /// </summary>
    [Serializable]
    public class UIRotateAnimation
    {
        public float duration = 1f;
 
        public float delay;
 
        public Ease ease = Ease.Linear;
 
        public Vector3 startValue;
 
        public Vector3 endValue;
 
        public RotateMode rotateMode = RotateMode.Fast;
 
        public bool isCustom;
 
        public Tween Play(RectTransform target, bool instant = false)
        {
            if (isCustom)
            {
                target.localRotation = Quaternion.Euler(startValue);
            }
            return target.DORotate(endValue, instant ? 0f : duration, rotateMode).SetDelay(instant ? 0f : delay).SetEase(ease);
        }
    }
}
using System;
using UnityEngine;
using DG.Tweening;
 
namespace SK.Framework
{
    /// <summary>
    /// UI縮放動畫
    /// </summary>
    [Serializable]
    public class UIScaleAnimation
    {
        public float duration = 1f;
 
        public float delay;
 
        public Ease ease = Ease.Linear;
 
        public Vector3 startValue = Vector3.zero;
 
        public Vector3 endValue = Vector3.one;
 
        public bool isCustom;
 
        public Tween Play(RectTransform target, bool instant = false)
        {
            if (isCustom)
            {
                target.localScale = startValue;
            }
            return target.DOScale(endValue, instant ? 0f : duration).SetDelay(instant ? 0f : delay).SetEase(ease);
        }
    }
}
using System;
using DG.Tweening;
using UnityEngine;
 
namespace SK.Framework
{
    /// <summary>
    /// UI淡入淡出動畫
    /// </summary>
    [Serializable]
    public class UIFadeAnimation
    {
        public float duration = 1f;
 
        public float delay;
 
        public Ease ease = Ease.Linear;
 
        public float startValue;
 
        public float endValue = 1f;
 
        public bool isCustom;
 
        public Tween Play(CanvasGroup target, bool instant = false)
        {
            if (isCustom)
            {
                target.alpha = startValue;
            }
            return target.DOFade(endValue, instant ? 0f : duration).SetDelay(instant ? 0f : delay).SetEase(ease);
        }
    }
}
namespace SK.Framework
{
    /// <summary>
    /// UI動畫類型
    /// </summary>
    public enum UIAnimationType
    {
        /// <summary>
        /// DoTween動畫
        /// </summary>
        Tween,
        /// <summary>
        /// Animator動畫
        /// </summary>
        Animator,
    }
}
using System;
using UnityEngine;
 
namespace SK.Framework
{
    /// <summary>
    /// UI動畫
    /// </summary>
    [Serializable]
    public class UIAnimation
    {
        public UIAnimationType animationType = UIAnimationType.Tween;
 
        public string stateName;
 
        public bool moveToggle;
 
        public UIMoveAnimation moveAnimation;
 
        public bool rotateToggle;
 
        public UIRotateAnimation rotateAnimation;
 
        public bool scaleToggle;
 
        public UIScaleAnimation scaleAnimation;
 
        public bool fadeToggle;
 
        public UIFadeAnimation fadeAnimation;
 
        public bool HasTweenAnimation
        {
            get
            {
                return moveToggle || rotateToggle || scaleToggle || fadeToggle;
            }
        }
 
        public IChain Play(UIView view, bool instant = false, Action callback = null)
        {
            switch (animationType)
            {
                case UIAnimationType.Tween:
                    if (HasTweenAnimation)
                    {
                        var chain = view.Sequence();
                        var cc = new ConcurrentChain();
                        if (moveToggle) cc.Tween(() => moveAnimation.Play(view.RectTransform, instant));
                        if (rotateToggle) cc.Tween(() => rotateAnimation.Play(view.RectTransform, instant));
                        if (scaleToggle) cc.Tween(() => scaleAnimation.Play(view.RectTransform, instant));
                        if (fadeToggle) cc.Tween(() => fadeAnimation.Play(view.CanvasGroup, instant));
                        chain.Append(cc).Event(() => callback?.Invoke()).Begin();
                        return chain;
                    }
                    else
                    {
                        callback?.Invoke();
                        return null;
                    }
                case UIAnimationType.Animator:
                    return view.Sequence()
                        .Animation(view.GetComponent<Animator>(), stateName)
                        .Event(() => callback?.Invoke())
                        .Begin();
                default: return null;
            }
        }
    }
}

在UI View類中的相關變量如下:

using System;
using UnityEngine.Events;
 
namespace SK.Framework
{
    [Serializable]
    public class ViewVisibilityChangedEvent
    {
        public UIAnimation animation = new UIAnimation();
 
        public UnityEvent onBeginEvent;
 
        public UnityEvent onEndEvent;
    }
}

為UI View創建Custom Editor:

using System;
using UnityEngine;
using UnityEditor;
using DG.Tweening;
using System.Reflection;
using UnityEditor.Animations;
using UnityEditor.AnimatedValues;
 
namespace SK.Framework
{
    [CustomEditor(typeof(UIView), true)]
    public class UIViewInspector : Editor
    {
        private enum Menu
        {
            Animation,
 
            UnityEvent,
        }
 
        private UIView Target;
 
        private SerializedProperty variables;
        private ViewVisibilityChangedEvent onShow;
        private ViewVisibilityChangedEvent onHide;
 
        private static string uiViewOnShowFoldout = "UIView OnShow Foldout";
        private static string uiViewOnHideFoldout = "UIView OnHide Foldout";
        private bool onShowFoldout;
        private bool onHideFoldout;
 
        private Menu onShowMenu = Menu.Animation;
        private Menu onHideMenu = Menu.Animation;
 
        private SerializedProperty onShowBeginEvent;
        private SerializedProperty onShowEndEvent;
        private SerializedProperty onHideBeginEvent;
        private SerializedProperty onHideEndEvent;
 
        private AnimBool onShowMoveAnimBool;
        private AnimBool onShowRotateAnimBool;
        private AnimBool onShowScaleAnimBool;
        private AnimBool onShowFadeAnimBool;
 
        private AnimBool onHideMoveAnimBool;
        private AnimBool onHideRotateAnimBool;
        private AnimBool onHideScaleAnimBool;
        private AnimBool onHideFadeAnimBool;
 
 
        private const float titleWidth = 80f;
        private const float labelWidth = 60f;
 
        public override void OnInspectorGUI()
        {
            if (Target == null)
            {
                Target = target as UIView;
                onShow = typeof(UIView).GetField("onVisible", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(Target) as ViewVisibilityChangedEvent;
                onHide = typeof(UIView).GetField("onInvisible", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(Target) as ViewVisibilityChangedEvent;
 
                variables = serializedObject.FindProperty("variables");
                onShowFoldout = EditorPrefs.GetBool(uiViewOnShowFoldout);
                onHideFoldout = EditorPrefs.GetBool(uiViewOnHideFoldout);
 
                onShowBeginEvent = serializedObject.FindProperty("onVisible").FindPropertyRelative("onBeginEvent");
                onShowEndEvent = serializedObject.FindProperty("onVisible").FindPropertyRelative("onEndEvent");
                onHideBeginEvent = serializedObject.FindProperty("onInvisible").FindPropertyRelative("onBeginEvent");
                onHideEndEvent = serializedObject.FindProperty("onInvisible").FindPropertyRelative("onEndEvent");
 
                onShowMoveAnimBool = new AnimBool(onShow.animation.moveToggle, Repaint);
                onShowRotateAnimBool = new AnimBool(onShow.animation.rotateToggle, Repaint);
                onShowScaleAnimBool = new AnimBool(onShow.animation.scaleToggle, Repaint);
                onShowFadeAnimBool = new AnimBool(onShow.animation.fadeToggle, Repaint);
 
                onHideMoveAnimBool = new AnimBool(onHide.animation.moveToggle, Repaint);
                onHideRotateAnimBool = new AnimBool(onHide.animation.rotateToggle, Repaint);
                onHideScaleAnimBool = new AnimBool(onHide.animation.scaleToggle, Repaint);
                onHideFadeAnimBool = new AnimBool(onHide.animation.fadeToggle, Repaint);
            }
 
            EditorGUILayout.PropertyField(variables);
 
            //On Show 折疊欄
            var newOnShowFoldout = EditorGUILayout.Foldout(onShowFoldout, "On Visible", true);
            if (newOnShowFoldout != onShowFoldout)
            {
                onShowFoldout = newOnShowFoldout;
                EditorPrefs.SetBool(uiViewOnShowFoldout, onShowFoldout);
            }
            //Show
            if (onShowFoldout)
            {
                GUILayout.BeginHorizontal();
                Color color = GUI.color;
                GUI.color = onShowMenu == Menu.Animation ? Color.cyan : color;
                if (GUILayout.Button("Animation", "ButtonLeft"))
                {
                    onShowMenu = Menu.Animation;
                }
                GUI.color = onShowMenu == Menu.UnityEvent ? Color.cyan : color;
                if (GUILayout.Button("Event", "ButtonRight"))
                {
                    onShowMenu = Menu.UnityEvent;
                }
                GUI.color = color;
                GUILayout.EndHorizontal();
                switch (onShowMenu)
                {
                    case Menu.Animation:
                        //Animation Type
                        GUILayout.BeginHorizontal();
                        GUILayout.Label("Mode", GUILayout.Width(titleWidth));
                        var newOnShowAnimationType = (UIAnimationType)EditorGUILayout.EnumPopup(onShow.animation.animationType);
                        if (newOnShowAnimationType != onShow.animation.animationType)
                        {
                            Undo.RecordObject(Target, "On Show Animation Type");
                            onShow.animation.animationType = newOnShowAnimationType;
                            EditorUtility.SetDirty(Target);
                        }
                        GUILayout.EndHorizontal();
 
                        UIAnimation animation = onShow.animation;
                        switch (animation.animationType)
                        {
                            case UIAnimationType.Tween:
                                //Move、Rotate、Scale、Fade
                                GUILayout.BeginHorizontal();
                                {
                                    GUI.color = animation.moveToggle ? color : Color.gray;
                                    if (GUILayout.Button(EditorGUIUtility.IconContent("MoveTool"), "ButtonLeft", GUILayout.Width(25f)))
                                    {
                                        Undo.RecordObject(Target, "On Show Animation Move Toggle");
                                        animation.moveToggle = !animation.moveToggle;
                                        onShowMoveAnimBool.target = animation.moveToggle;
                                        EditorUtility.SetDirty(Target);
                                    }
                                    GUI.color = animation.rotateToggle ? color : Color.gray;
                                    if (GUILayout.Button(EditorGUIUtility.IconContent("RotateTool"), "ButtonMid", GUILayout.Width(25f)))
                                    {
                                        Undo.RecordObject(Target, "On Show Animation Rotate Toggle");
                                        animation.rotateToggle = !animation.rotateToggle;
                                        onShowRotateAnimBool.target = animation.rotateToggle;
                                        EditorUtility.SetDirty(Target);
                                    }
                                    GUI.color = animation.scaleToggle ? color : Color.gray;
                                    if (GUILayout.Button(EditorGUIUtility.IconContent("ScaleTool"), "ButtonMid", GUILayout.Width(25f)))
                                    {
                                        Undo.RecordObject(Target, "On Show Animation Scale Toggle");
                                        animation.scaleToggle = !animation.scaleToggle;
                                        onShowScaleAnimBool.target = animation.scaleToggle;
                                        EditorUtility.SetDirty(Target);
                                    }
                                    GUI.color = animation.fadeToggle ? color : Color.gray;
                                    if (GUILayout.Button(EditorGUIUtility.IconContent("ViewToolOrbit"), "ButtonRight", GUILayout.Width(25f)))
                                    {
                                        Undo.RecordObject(Target, "On Show Animation Fade Toggle");
                                        animation.fadeToggle = !animation.fadeToggle;
                                        onShowFadeAnimBool.target = animation.fadeToggle;
                                        EditorUtility.SetDirty(Target);
                                    }
                                    GUI.color = color;
                                }
                                GUILayout.EndHorizontal();
 
                                //MoveAnimation
                                var moveAnimation = animation.moveAnimation;
                                if (EditorGUILayout.BeginFadeGroup(onShowMoveAnimBool.faded))
                                {
                                    GUILayout.BeginHorizontal("Badge");
                                    {
                                        GUILayout.BeginVertical();
                                        {
                                            GUILayout.Space(40f);
                                            GUILayout.Label(EditorGUIUtility.IconContent("MoveTool"));
                                        }
                                        GUILayout.EndVertical();
 
                                        GUILayout.BeginVertical();
                                        {
                                            //Duration、Delay
                                            GUILayout.BeginHorizontal();
                                            {
                                                GUILayout.Label("Duration", GUILayout.Width(labelWidth));
                                                var newDuration = EditorGUILayout.FloatField(moveAnimation.duration);
                                                if (newDuration != moveAnimation.duration)
                                                {
                                                    Undo.RecordObject(Target, "On Show Animation Move Duration");
                                                    moveAnimation.duration = newDuration;
                                                    EditorUtility.SetDirty(Target);
                                                }
 
                                                GUILayout.Label("Delay", GUILayout.Width(labelWidth - 20f));
                                                var newDelay = EditorGUILayout.FloatField(moveAnimation.delay);
                                                if (newDelay != moveAnimation.delay)
                                                {
                                                    Undo.RecordObject(Target, "On Show Animation Move Delay");
                                                    moveAnimation.delay = newDelay;
                                                    EditorUtility.SetDirty(Target);
                                                }
                                            }
                                            GUILayout.EndHorizontal();
 
                                            //Is Custom
                                            GUILayout.BeginHorizontal();
                                            {
                                                GUILayout.Label("From", GUILayout.Width(labelWidth - 2f));
                                                if (GUILayout.Button(moveAnimation.isCustom ? "Custom Position" : "Direction", "DropDownButton"))
                                                {
                                                    GenericMenu gm = new GenericMenu();
                                                    gm.AddItem(new GUIContent("Direction"), !moveAnimation.isCustom, () => { moveAnimation.isCustom = false; EditorUtility.SetDirty(Target); });
                                                    gm.AddItem(new GUIContent("Custom Position"), moveAnimation.isCustom, () => { moveAnimation.isCustom = true; EditorUtility.SetDirty(Target); });
                                                    gm.ShowAsContext();
                                                }
                                            }
                                            GUILayout.EndHorizontal();
 
                                            //From
                                            GUILayout.BeginHorizontal();
                                            {
                                                GUILayout.Label(GUIContent.none, GUILayout.Width(labelWidth));
                                                if (moveAnimation.isCustom)
                                                {
                                                    Vector3 newStartValue = EditorGUILayout.Vector3Field(GUIContent.none, moveAnimation.startValue);
                                                    if (newStartValue != moveAnimation.startValue)
                                                    {
                                                        Undo.RecordObject(Target, "On Show Animation Move From");
                                                        moveAnimation.startValue = newStartValue;
                                                        EditorUtility.SetDirty(Target);
                                                    }
                                                }
                                                else
                                                {
                                                    var newMoveDirection = (UIMoveAnimationDirection)EditorGUILayout.EnumPopup(moveAnimation.direction);
                                                    if (newMoveDirection != moveAnimation.direction)
                                                    {
                                                        Undo.RecordObject(Target, "On Show Animation Move Direction");
                                                        moveAnimation.direction = newMoveDirection;
                                                        EditorUtility.SetDirty(Target);
                                                    }
                                                }
                                            }
                                            GUILayout.EndHorizontal();
 
                                            //To
                                            GUILayout.BeginHorizontal();
                                            {
                                                GUILayout.Label("To", GUILayout.Width(labelWidth));
                                                Vector3 newEndValue = EditorGUILayout.Vector3Field(GUIContent.none, moveAnimation.endValue);
                                                if (newEndValue != moveAnimation.endValue)
                                                {
                                                    Undo.RecordObject(Target, "On Show Animation Move To");
                                                    moveAnimation.endValue = newEndValue;
                                                    EditorUtility.SetDirty(Target);
                                                }
                                            }
                                            GUILayout.EndHorizontal();
 
                                            //Ease
                                            GUILayout.BeginHorizontal();
                                            {
                                                GUILayout.Label("Ease", GUILayout.Width(labelWidth));
                                                var newEase = (Ease)EditorGUILayout.EnumPopup(moveAnimation.ease);
                                                if (newEase != moveAnimation.ease)
                                                {
                                                    Undo.RecordObject(Target, "On Show Animation Move Ease");
                                                    moveAnimation.ease = newEase;
                                                    EditorUtility.SetDirty(Target);
                                                }
                                            }
                                            GUILayout.EndHorizontal();
                                        }
                                        GUILayout.EndVertical();
                                    }
                                    GUILayout.EndHorizontal();
                                }
                                EditorGUILayout.EndFadeGroup();
 
                                //RotateAnimation
                                var rotateAnimation = animation.rotateAnimation;
                                if (EditorGUILayout.BeginFadeGroup(onShowRotateAnimBool.faded))
                                {
                                    GUILayout.BeginHorizontal("Badge");
                                    {
                                        GUILayout.BeginVertical();
                                        {
                                            GUILayout.Space(rotateAnimation.isCustom ? 50f : 40f);
                                            GUILayout.Label(EditorGUIUtility.IconContent("RotateTool"));
                                        }
                                        GUILayout.EndVertical();
 
                                        GUILayout.BeginVertical();
                                        {
                                            //Duration、Delay
                                            GUILayout.BeginHorizontal();
                                            {
                                                GUILayout.Label("Duration", GUILayout.Width(labelWidth));
                                                var newDuration = EditorGUILayout.FloatField(rotateAnimation.duration);
                                                if (newDuration != rotateAnimation.duration)
                                                {
                                                    Undo.RecordObject(Target, "On Show Animation Rotate Duration");
                                                    rotateAnimation.duration = newDuration;
                                                    EditorUtility.SetDirty(Target);
                                                }
 
                                                GUILayout.Label("Delay", GUILayout.Width(labelWidth - 20f));
                                                var newDelay = EditorGUILayout.FloatField(rotateAnimation.delay);
                                                if (newDelay != rotateAnimation.delay)
                                                {
                                                    Undo.RecordObject(Target, "On Show Animation Rotate Delay");
                                                    rotateAnimation.delay = newDelay;
                                                    EditorUtility.SetDirty(Target);
                                                }
                                            }
                                            GUILayout.EndHorizontal();
 
                                            //Is Custom
                                            GUILayout.BeginHorizontal();
                                            {
                                                GUILayout.Label("From", GUILayout.Width(labelWidth - 2f));
                                                if (GUILayout.Button(rotateAnimation.isCustom ? "Fixed Rotation" : "Current Rotation", "DropDownButton"))
                                                {
                                                    GenericMenu gm = new GenericMenu();
                                                    gm.AddItem(new GUIContent("Current Rotation"), !rotateAnimation.isCustom, () => { rotateAnimation.isCustom = false; EditorUtility.SetDirty(Target); });
                                                    gm.AddItem(new GUIContent("Fixed Rotation"), rotateAnimation.isCustom, () => { rotateAnimation.isCustom = true; EditorUtility.SetDirty(Target); });
                                                    gm.ShowAsContext();
                                                }
                                            }
                                            GUILayout.EndHorizontal();
 
                                            if (rotateAnimation.isCustom)
                                            {
                                                //From
                                                GUILayout.BeginHorizontal();
                                                {
                                                    GUILayout.Label(GUIContent.none, GUILayout.Width(labelWidth));
                                                    Vector3 newStartValue = EditorGUILayout.Vector3Field(GUIContent.none, rotateAnimation.startValue);
                                                    if (newStartValue != rotateAnimation.startValue)
                                                    {
                                                        Undo.RecordObject(Target, "On Show Animation Rotate From");
                                                        rotateAnimation.startValue = newStartValue;
                                                        EditorUtility.SetDirty(Target);
                                                    }
                                                }
                                                GUILayout.EndHorizontal();
                                            }
 
                                            //To
                                            GUILayout.BeginHorizontal();
                                            {
                                                GUILayout.Label("To", GUILayout.Width(labelWidth));
                                                Vector3 newEndValue = EditorGUILayout.Vector3Field(GUIContent.none, rotateAnimation.endValue);
                                                if (newEndValue != rotateAnimation.endValue)
                                                {
                                                    Undo.RecordObject(Target, "On Show Animation Rotate To");
                                                    rotateAnimation.endValue = newEndValue;
                                                    EditorUtility.SetDirty(Target);
                                                }
                                            }
                                            GUILayout.EndHorizontal();
 
                                            //Rotate Mode
                                            GUILayout.BeginHorizontal();
                                            {
                                                GUILayout.Label("Mode", GUILayout.Width(labelWidth));
                                                var newRotateMode = (RotateMode)EditorGUILayout.EnumPopup(rotateAnimation.rotateMode);
                                                if (newRotateMode != rotateAnimation.rotateMode)
                                                {
                                                    Undo.RecordObject(Target, "On Show Animation Rotate Mode");
                                                    rotateAnimation.rotateMode = newRotateMode;
                                                    EditorUtility.SetDirty(Target);
                                                }
                                            }
                                            GUILayout.EndHorizontal();
 
                                            //Ease
                                            GUILayout.BeginHorizontal();
                                            {
                                                GUILayout.Label("Ease", GUILayout.Width(labelWidth));
                                                var newEase = (Ease)EditorGUILayout.EnumPopup(rotateAnimation.ease);
                                                if (newEase != rotateAnimation.ease)
                                                {
                                                    Undo.RecordObject(Target, "On Show Animation Rotate Ease");
                                                    rotateAnimation.ease = newEase;
                                                    EditorUtility.SetDirty(Target);
                                                }
                                            }
                                            GUILayout.EndHorizontal();
                                        }
                                        GUILayout.EndVertical();
                                    }
                                    GUILayout.EndHorizontal();
                                }
                                EditorGUILayout.EndFadeGroup();
 
                                //ScaleAnimation
                                var scaleAnimation = animation.scaleAnimation;
                                if (EditorGUILayout.BeginFadeGroup(onShowScaleAnimBool.faded))
                                {
                                    GUILayout.BeginHorizontal("Badge");
                                    {
                                        GUILayout.BeginVertical();
                                        {
                                            GUILayout.Space(scaleAnimation.isCustom ? 40f : 30f);
                                            GUILayout.Label(EditorGUIUtility.IconContent("ScaleTool"));
                                        }
                                        GUILayout.EndVertical();
 
                                        GUILayout.BeginVertical();
                                        {
                                            //Duration、Delay
                                            GUILayout.BeginHorizontal();
                                            {
                                                GUILayout.Label("Duration", GUILayout.Width(labelWidth));
                                                var newDuration = EditorGUILayout.FloatField(scaleAnimation.duration);
                                                if (newDuration != scaleAnimation.duration)
                                                {
                                                    Undo.RecordObject(Target, "On Show Animation Scale Duration");
                                                    scaleAnimation.duration = newDuration;
                                                    EditorUtility.SetDirty(Target);
                                                }
 
                                                GUILayout.Label("Delay", GUILayout.Width(labelWidth - 20f));
                                                var newDelay = EditorGUILayout.FloatField(scaleAnimation.delay);
                                                if (newDelay != scaleAnimation.delay)
                                                {
                                                    Undo.RecordObject(Target, "On Show Animation Scale Delay");
                                                    scaleAnimation.delay = newDelay;
                                                    EditorUtility.SetDirty(Target);
                                                }
                                            }
                                            GUILayout.EndHorizontal();
 
                                            //Is Custom
                                            GUILayout.BeginHorizontal();
                                            {
                                                GUILayout.Label("From", GUILayout.Width(labelWidth - 2f));
                                                if (GUILayout.Button(scaleAnimation.isCustom ? "Fixed Scale" : "Current Scale", "DropDownButton"))
                                                {
                                                    GenericMenu gm = new GenericMenu();
                                                    gm.AddItem(new GUIContent("Current Scale"), !scaleAnimation.isCustom, () => { scaleAnimation.isCustom = false; EditorUtility.SetDirty(Target); });
                                                    gm.AddItem(new GUIContent("Fixed Scale"), scaleAnimation.isCustom, () => { scaleAnimation.isCustom = true; EditorUtility.SetDirty(Target); });
                                                    gm.ShowAsContext();
                                                }
                                            }
                                            GUILayout.EndHorizontal();
 
                                            if (scaleAnimation.isCustom)
                                            {
                                                //From
                                                GUILayout.BeginHorizontal();
                                                {
                                                    GUILayout.Label(GUIContent.none, GUILayout.Width(labelWidth));
                                                    Vector3 newStartValue = EditorGUILayout.Vector3Field(GUIContent.none, scaleAnimation.startValue);
                                                    if (newStartValue != scaleAnimation.startValue)
                                                    {
                                                        Undo.RecordObject(Target, "On Show Animation Scale From");
                                                        scaleAnimation.startValue = newStartValue;
                                                        EditorUtility.SetDirty(Target);
                                                    }
                                                }
                                                GUILayout.EndHorizontal();
                                            }
 
                                            //To
                                            GUILayout.BeginHorizontal();
                                            {
                                                GUILayout.Label("To", GUILayout.Width(labelWidth));
                                                Vector3 newEndValue = EditorGUILayout.Vector3Field(GUIContent.none, scaleAnimation.endValue);
                                                if (newEndValue != scaleAnimation.endValue)
                                                {
                                                    Undo.RecordObject(Target, "On Show Animation Scale To");
                                                    scaleAnimation.endValue = newEndValue;
                                                    EditorUtility.SetDirty(Target);
                                                }
                                            }
                                            GUILayout.EndHorizontal();
 
                                            //Ease
                                            GUILayout.BeginHorizontal();
                                            {
                                                GUILayout.Label("Ease", GUILayout.Width(labelWidth));
                                                var newEase = (Ease)EditorGUILayout.EnumPopup(scaleAnimation.ease);
                                                if (newEase != scaleAnimation.ease)
                                                {
                                                    Undo.RecordObject(Target, "On Show Animation Scale Ease");
                                                    scaleAnimation.ease = newEase;
                                                    EditorUtility.SetDirty(Target);
                                                }
                                            }
                                            GUILayout.EndHorizontal();
                                        }
                                        GUILayout.EndVertical();
                                    }
                                    GUILayout.EndHorizontal();
                                }
                                EditorGUILayout.EndFadeGroup();
 
                                //FadeAnimation
                                var fadeAnimation = animation.fadeAnimation;
                                if (EditorGUILayout.BeginFadeGroup(onShowFadeAnimBool.faded))
                                {
                                    GUILayout.BeginHorizontal("Badge");
                                    {
                                        GUILayout.BeginVertical();
                                        {
                                            GUILayout.Space(fadeAnimation.isCustom ? 40f : 30f);
                                            GUILayout.Label(EditorGUIUtility.IconContent("ViewToolOrbit"));
                                        }
                                        GUILayout.EndVertical();
 
                                        GUILayout.BeginVertical();
                                        {
                                            //Duration、Delay
                                            GUILayout.BeginHorizontal();
                                            {
                                                GUILayout.Label("Duration", GUILayout.Width(labelWidth));
                                                var newDuration = EditorGUILayout.FloatField(fadeAnimation.duration);
                                                if (newDuration != fadeAnimation.duration)
                                                {
                                                    Undo.RecordObject(Target, "On Show Animation Fade Duration");
                                                    fadeAnimation.duration = newDuration;
                                                    EditorUtility.SetDirty(Target);
                                                }
 
                                                GUILayout.Label("Delay", GUILayout.Width(labelWidth - 20f));
                                                var newDelay = EditorGUILayout.FloatField(fadeAnimation.delay);
                                                if (newDelay != fadeAnimation.delay)
                                                {
                                                    Undo.RecordObject(Target, "On Show Animation Fade Delay");
                                                    fadeAnimation.delay = newDelay;
                                                    EditorUtility.SetDirty(Target);
                                                }
                                            }
                                            GUILayout.EndHorizontal();
 
                                            //Is Custom
                                            GUILayout.BeginHorizontal();
                                            {
                                                GUILayout.Label("From", GUILayout.Width(labelWidth - 2f));
                                                if (GUILayout.Button(fadeAnimation.isCustom ? "Fixed Alpha" : "Current Alpha", "DropDownButton"))
                                                {
                                                    GenericMenu gm = new GenericMenu();
                                                    gm.AddItem(new GUIContent("Current Alpha"), !fadeAnimation.isCustom, () => { fadeAnimation.isCustom = false; EditorUtility.SetDirty(Target); });
                                                    gm.AddItem(new GUIContent("Fixed Alpha"), fadeAnimation.isCustom, () => { fadeAnimation.isCustom = true; EditorUtility.SetDirty(Target); });
                                                    gm.ShowAsContext();
                                                }
                                            }
                                            GUILayout.EndHorizontal();
 
                                            if (fadeAnimation.isCustom)
                                            {
                                                //From
                                                GUILayout.BeginHorizontal();
                                                {
                                                    GUILayout.Label(GUIContent.none, GUILayout.Width(labelWidth));
                                                    float newStartValue = EditorGUILayout.FloatField(GUIContent.none, fadeAnimation.startValue);
                                                    if (newStartValue != fadeAnimation.startValue)
                                                    {
                                                        Undo.RecordObject(Target, "On Show Animation Fade From");
                                                        fadeAnimation.startValue = newStartValue;
                                                        EditorUtility.SetDirty(Target);
                                                    }
                                                }
                                                GUILayout.EndHorizontal();
                                            }
 
                                            //To
                                            GUILayout.BeginHorizontal();
                                            {
                                                GUILayout.Label("To", GUILayout.Width(labelWidth));
                                                float newEndValue = EditorGUILayout.FloatField(GUIContent.none, fadeAnimation.endValue);
                                                if (newEndValue != fadeAnimation.endValue)
                                                {
                                                    Undo.RecordObject(Target, "On Show Animation Fade To");
                                                    fadeAnimation.endValue = newEndValue;
                                                    EditorUtility.SetDirty(Target);
                                                }
                                            }
                                            GUILayout.EndHorizontal();
 
                                            //Ease
                                            GUILayout.BeginHorizontal();
                                            {
                                                GUILayout.Label("Ease", GUILayout.Width(labelWidth));
                                                var newEase = (Ease)EditorGUILayout.EnumPopup(fadeAnimation.ease);
                                                if (newEase != fadeAnimation.ease)
                                                {
                                                    Undo.RecordObject(Target, "On Show Animation Fade Ease");
                                                    fadeAnimation.ease = newEase;
                                                    EditorUtility.SetDirty(Target);
                                                }
                                            }
                                            GUILayout.EndHorizontal();
                                        }
                                        GUILayout.EndVertical();
                                    }
                                    GUILayout.EndHorizontal();
                                }
                                EditorGUILayout.EndFadeGroup();
 
                                break;
                            case UIAnimationType.Animator:
                                var animator = Target.GetComponent<Animator>();
                                if (animator != null)
                                {
                                    var animatorController = animator.runtimeAnimatorController as AnimatorController;
                                    var stateMachine = animatorController.layers[0].stateMachine;
                                    if (stateMachine.states.Length == 0)
                                    {
                                        EditorGUILayout.HelpBox("no animator state was found.", MessageType.Info);
                                    }
                                    else
                                    {
                                        string[] stateNames = new string[stateMachine.states.Length];
                                        for (int i = 0; i < stateNames.Length; i++)
                                        {
                                            stateNames[i] = stateMachine.states[i].state.name;
                                        }
                                        var index = Array.FindIndex(stateNames, m => m == animation.stateName);
 
                                        GUILayout.BeginHorizontal();
                                        GUILayout.Label("State Name", GUILayout.Width(titleWidth));
                                        var newIndex = EditorGUILayout.Popup(index, stateNames);
                                        if (newIndex != index)
                                        {
                                            Undo.RecordObject(Target, "Show Animation State Name");
                                            animation.stateName = stateNames[newIndex];
                                            EditorUtility.SetDirty(Target);
                                        }
                                        GUILayout.EndHorizontal();
                                    }
                                }
                                else
                                {
                                    EditorGUILayout.HelpBox("no animator component on this view.", MessageType.Error);
                                }
                                break;
                            default:
                                break;
                        }
                        break;
                    case Menu.UnityEvent:
                        //OnBeginEvent、OnEndEvent
                        EditorGUILayout.PropertyField(onShowBeginEvent);
                        EditorGUILayout.PropertyField(onShowEndEvent);
                        break;
                    default:
                        break;
                }
            }
 
            //On Hide 折疊欄
            var newOnHideFoldout = EditorGUILayout.Foldout(onHideFoldout, "On Invisible", true);
            if (newOnHideFoldout != onHideFoldout)
            {
                onHideFoldout = newOnHideFoldout;
                EditorPrefs.SetBool(uiViewOnHideFoldout, onHideFoldout);
            }
            //Hide
            if (onHideFoldout)
            {
                GUILayout.BeginHorizontal();
                Color color = GUI.color;
                GUI.color = onHideMenu == Menu.Animation ? Color.cyan : color;
                if (GUILayout.Button("Animation", "ButtonLeft"))
                {
                    onHideMenu = Menu.Animation;
                }
                GUI.color = onHideMenu == Menu.UnityEvent ? Color.cyan : color;
                if (GUILayout.Button("Event", "ButtonRight"))
                {
                    onHideMenu = Menu.UnityEvent;
                }
                GUI.color = color;
                GUILayout.EndHorizontal();
 
                switch (onHideMenu)
                {
                    case Menu.Animation:
                        //Animation Type
                        GUILayout.BeginHorizontal();
                        GUILayout.Label("Mode", GUILayout.Width(titleWidth));
                        var newOnHideAnimationType = (UIAnimationType)EditorGUILayout.EnumPopup(onHide.animation.animationType);
                        if (newOnHideAnimationType != onHide.animation.animationType)
                        {
                            Undo.RecordObject(Target, "On Hide Animation Type");
                            onHide.animation.animationType = newOnHideAnimationType;
                        }
                        GUILayout.EndHorizontal();
 
                        UIAnimation animation = onHide.animation;
                        switch (animation.animationType)
                        {
                            case UIAnimationType.Tween:
                                //Move、Rotate、Scale、Fade
                                GUILayout.BeginHorizontal();
                                {
                                    GUI.color = animation.moveToggle ? color : Color.gray;
                                    if (GUILayout.Button(EditorGUIUtility.IconContent("MoveTool"), "ButtonLeft", GUILayout.Width(25f)))
                                    {
                                        Undo.RecordObject(Target, "On Hide Animation Move Toggle");
                                        animation.moveToggle = !animation.moveToggle;
                                        onHideMoveAnimBool.target = animation.moveToggle;
                                        EditorUtility.SetDirty(Target);
                                    }
                                    GUI.color = animation.rotateToggle ? color : Color.gray;
                                    if (GUILayout.Button(EditorGUIUtility.IconContent("RotateTool"), "ButtonMid", GUILayout.Width(25f)))
                                    {
                                        Undo.RecordObject(Target, "On Hide Animation Rotate Toggle");
                                        animation.rotateToggle = !animation.rotateToggle;
                                        onHideRotateAnimBool.target = animation.rotateToggle;
                                        EditorUtility.SetDirty(Target);
                                    }
                                    GUI.color = animation.scaleToggle ? color : Color.gray;
                                    if (GUILayout.Button(EditorGUIUtility.IconContent("ScaleTool"), "ButtonMid", GUILayout.Width(25f)))
                                    {
                                        Undo.RecordObject(Target, "On Hide Animation Scale Toggle");
                                        animation.scaleToggle = !animation.scaleToggle;
                                        onHideScaleAnimBool.target = animation.scaleToggle;
                                        EditorUtility.SetDirty(Target);
                                    }
                                    GUI.color = animation.fadeToggle ? color : Color.gray;
                                    if (GUILayout.Button(EditorGUIUtility.IconContent("ViewToolOrbit"), "ButtonRight", GUILayout.Width(25f)))
                                    {
                                        Undo.RecordObject(Target, "On Hide Animation Fade Toggle");
                                        animation.fadeToggle = !animation.fadeToggle;
                                        onHideFadeAnimBool.target = animation.fadeToggle;
                                        EditorUtility.SetDirty(Target);
                                    }
                                    GUI.color = color;
                                }
                                GUILayout.EndHorizontal();
 
                                //MoveAnimation
                                var moveAnimation = animation.moveAnimation;
                                if (EditorGUILayout.BeginFadeGroup(onHideMoveAnimBool.faded))
                                {
                                    GUILayout.BeginHorizontal("Badge");
                                    {
                                        GUILayout.BeginVertical();
                                        {
                                            GUILayout.Space(40f);
                                            GUILayout.Label(EditorGUIUtility.IconContent("MoveTool"));
                                        }
                                        GUILayout.EndVertical();
 
                                        GUILayout.BeginVertical();
                                        {
                                            //Duration、Delay
                                            GUILayout.BeginHorizontal();
                                            {
                                                GUILayout.Label("Duration", GUILayout.Width(labelWidth));
                                                var newDuration = EditorGUILayout.FloatField(moveAnimation.duration);
                                                if (newDuration != moveAnimation.duration)
                                                {
                                                    Undo.RecordObject(Target, "On Hide Animation Move Duration");
                                                    moveAnimation.duration = newDuration;
                                                    EditorUtility.SetDirty(Target);
                                                }
 
                                                GUILayout.Label("Delay", GUILayout.Width(labelWidth - 20f));
                                                var newDelay = EditorGUILayout.FloatField(moveAnimation.delay);
                                                if (newDelay != moveAnimation.delay)
                                                {
                                                    Undo.RecordObject(Target, "On Hide Animation Move Delay");
                                                    moveAnimation.delay = newDelay;
                                                    EditorUtility.SetDirty(Target);
                                                }
                                            }
                                            GUILayout.EndHorizontal();
 
                                            //From
                                            GUILayout.BeginHorizontal();
                                            {
                                                GUILayout.Label("From", GUILayout.Width(labelWidth));
                                                Vector3 newStartValue = EditorGUILayout.Vector3Field(GUIContent.none, moveAnimation.startValue);
                                                if (newStartValue != moveAnimation.startValue)
                                                {
                                                    Undo.RecordObject(Target, "On Hide Animation Move From");
                                                    moveAnimation.startValue = newStartValue;
                                                    EditorUtility.SetDirty(Target);
                                                }
                                            }
                                            GUILayout.EndHorizontal();
 
                                            //Is Custom
                                            GUILayout.BeginHorizontal();
                                            {
                                                GUILayout.Label("To", GUILayout.Width(labelWidth - 2f));
                                                if (GUILayout.Button(moveAnimation.isCustom ? "Custom Position" : "Direction", "DropDownButton"))
                                                {
                                                    GenericMenu gm = new GenericMenu();
                                                    gm.AddItem(new GUIContent("Direction"), !moveAnimation.isCustom, () => { moveAnimation.isCustom = false; EditorUtility.SetDirty(Target); });
                                                    gm.AddItem(new GUIContent("Custom Position"), moveAnimation.isCustom, () => { moveAnimation.isCustom = true; EditorUtility.SetDirty(Target); });
                                                    gm.ShowAsContext();
                                                }
                                            }
                                            GUILayout.EndHorizontal();
 
                                            //To
                                            GUILayout.BeginHorizontal();
                                            {
                                                GUILayout.Label(GUIContent.none, GUILayout.Width(labelWidth));
                                                if (moveAnimation.isCustom)
                                                {
                                                    Vector3 newEndValue = EditorGUILayout.Vector3Field(GUIContent.none, moveAnimation.endValue);
                                                    if (newEndValue != moveAnimation.endValue)
                                                    {
                                                        Undo.RecordObject(Target, "On Hide Animation Move End");
                                                        moveAnimation.endValue = newEndValue;
                                                        EditorUtility.SetDirty(Target);
                                                    }
                                                }
                                                else
                                                {
                                                    var newMoveDirection = (UIMoveAnimationDirection)EditorGUILayout.EnumPopup(moveAnimation.direction);
                                                    if (newMoveDirection != moveAnimation.direction)
                                                    {
                                                        Undo.RecordObject(Target, "On Hide Animation Move Direction");
                                                        moveAnimation.direction = newMoveDirection;
                                                        EditorUtility.SetDirty(Target);
                                                    }
                                                }
                                            }
                                            GUILayout.EndHorizontal();
 
                                            //Ease
                                            GUILayout.BeginHorizontal();
                                            {
                                                GUILayout.Label("Ease", GUILayout.Width(labelWidth));
                                                var newEase = (Ease)EditorGUILayout.EnumPopup(moveAnimation.ease);
                                                if (newEase != moveAnimation.ease)
                                                {
                                                    Undo.RecordObject(Target, "On Hide Animation Move Ease");
                                                    moveAnimation.ease = newEase;
                                                    EditorUtility.SetDirty(Target);
                                                }
                                            }
                                            GUILayout.EndHorizontal();
                                        }
                                        GUILayout.EndVertical();
                                    }
                                    GUILayout.EndHorizontal();
                                }
                                EditorGUILayout.EndFadeGroup();
 
                                //RotateAnimation
                                var rotateAnimation = animation.rotateAnimation;
                                if (EditorGUILayout.BeginFadeGroup(onHideRotateAnimBool.faded))
                                {
                                    GUILayout.BeginHorizontal("Badge");
                                    {
                                        GUILayout.BeginVertical();
                                        {
                                            GUILayout.Space(rotateAnimation.isCustom ? 50f : 40f);
                                            GUILayout.Label(EditorGUIUtility.IconContent("RotateTool"));
                                        }
                                        GUILayout.EndVertical();
 
                                        GUILayout.BeginVertical();
                                        {
                                            //Duration、Delay
                                            GUILayout.BeginHorizontal();
                                            {
                                                GUILayout.Label("Duration", GUILayout.Width(labelWidth));
                                                var newDuration = EditorGUILayout.FloatField(rotateAnimation.duration);
                                                if (newDuration != rotateAnimation.duration)
                                                {
                                                    Undo.RecordObject(Target, "On Hide Animation Rotate Duration");
                                                    rotateAnimation.duration = newDuration;
                                                    EditorUtility.SetDirty(Target);
                                                }
 
                                                GUILayout.Label("Delay", GUILayout.Width(labelWidth - 20f));
                                                var newDelay = EditorGUILayout.FloatField(rotateAnimation.delay);
                                                if (newDelay != rotateAnimation.delay)
                                                {
                                                    Undo.RecordObject(Target, "On Hide Animation Rotate Delay");
                                                    rotateAnimation.delay = newDelay;
                                                    EditorUtility.SetDirty(Target);
                                                }
                                            }
                                            GUILayout.EndHorizontal();
 
                                            //Is Custom
                                            GUILayout.BeginHorizontal();
                                            {
                                                GUILayout.Label("From", GUILayout.Width(labelWidth - 2f));
                                                if (GUILayout.Button(rotateAnimation.isCustom ? "Fixed Rotation" : "Current Rotation", "DropDownButton"))
                                                {
                                                    GenericMenu gm = new GenericMenu();
                                                    gm.AddItem(new GUIContent("Current Rotation"), !rotateAnimation.isCustom, () => { rotateAnimation.isCustom = false; EditorUtility.SetDirty(Target); });
                                                    gm.AddItem(new GUIContent("Fixed Rotation"), rotateAnimation.isCustom, () => { rotateAnimation.isCustom = true; EditorUtility.SetDirty(Target); });
                                                    gm.ShowAsContext();
                                                }
                                            }
                                            GUILayout.EndHorizontal();
 
                                            if (rotateAnimation.isCustom)
                                            {
                                                //From
                                                GUILayout.BeginHorizontal();
                                                {
                                                    GUILayout.Label(GUIContent.none, GUILayout.Width(labelWidth));
                                                    Vector3 newStartValue = EditorGUILayout.Vector3Field(GUIContent.none, rotateAnimation.startValue);
                                                    if (newStartValue != rotateAnimation.startValue)
                                                    {
                                                        Undo.RecordObject(Target, "On Hide Animation Rotate From");
                                                        rotateAnimation.startValue = newStartValue;
                                                        EditorUtility.SetDirty(Target);
                                                    }
                                                }
                                                GUILayout.EndHorizontal();
                                            }
 
                                            //To
                                            GUILayout.BeginHorizontal();
                                            {
                                                GUILayout.Label("To", GUILayout.Width(labelWidth));
                                                Vector3 newEndValue = EditorGUILayout.Vector3Field(GUIContent.none, rotateAnimation.endValue);
                                                if (newEndValue != rotateAnimation.endValue)
                                                {
                                                    Undo.RecordObject(Target, "On Hide Animation Rotate To");
                                                    rotateAnimation.endValue = newEndValue;
                                                    EditorUtility.SetDirty(Target);
                                                }
                                            }
                                            GUILayout.EndHorizontal();
 
                                            //Rotate Mode
                                            GUILayout.BeginHorizontal();
                                            {
                                                GUILayout.Label("Mode", GUILayout.Width(labelWidth));
                                                var newRotateMode = (RotateMode)EditorGUILayout.EnumPopup(rotateAnimation.rotateMode);
                                                if (newRotateMode != rotateAnimation.rotateMode)
                                                {
                                                    Undo.RecordObject(Target, "On Hide Animation Rotate Mode");
                                                    rotateAnimation.rotateMode = newRotateMode;
                                                    EditorUtility.SetDirty(Target);
                                                }
                                            }
                                            GUILayout.EndHorizontal();
 
                                            //Ease
                                            GUILayout.BeginHorizontal();
                                            {
                                                GUILayout.Label("Ease", GUILayout.Width(labelWidth));
                                                var newEase = (Ease)EditorGUILayout.EnumPopup(rotateAnimation.ease);
                                                if (newEase != rotateAnimation.ease)
                                                {
                                                    Undo.RecordObject(Target, "On Hide Animation Rotate Ease");
                                                    rotateAnimation.ease = newEase;
                                                    EditorUtility.SetDirty(Target);
                                                }
                                            }
                                            GUILayout.EndHorizontal();
                                        }
                                        GUILayout.EndVertical();
                                    }
                                    GUILayout.EndHorizontal();
                                }
                                EditorGUILayout.EndFadeGroup();
 
                                //ScaleAnimation
                                var scaleAnimation = animation.scaleAnimation;
                                if (EditorGUILayout.BeginFadeGroup(onHideScaleAnimBool.faded))
                                {
                                    GUILayout.BeginHorizontal("Badge");
                                    {
                                        GUILayout.BeginVertical();
                                        {
                                            GUILayout.Space(scaleAnimation.isCustom ? 40f : 30f);
                                            GUILayout.Label(EditorGUIUtility.IconContent("ScaleTool"));
                                        }
                                        GUILayout.EndVertical();
 
                                        GUILayout.BeginVertical();
                                        {
                                            //Duration、Delay
                                            GUILayout.BeginHorizontal();
                                            {
                                                GUILayout.Label("Duration", GUILayout.Width(labelWidth));
                                                var newDuration = EditorGUILayout.FloatField(scaleAnimation.duration);
                                                if (newDuration != scaleAnimation.duration)
                                                {
                                                    Undo.RecordObject(Target, "On Hide Animation Scale Duration");
                                                    scaleAnimation.duration = newDuration;
                                                    EditorUtility.SetDirty(Target);
                                                }
 
                                                GUILayout.Label("Delay", GUILayout.Width(labelWidth - 20f));
                                                var newDelay = EditorGUILayout.FloatField(scaleAnimation.delay);
                                                if (newDelay != scaleAnimation.delay)
                                                {
                                                    Undo.RecordObject(Target, "On Hide Animation Scale Delay");
                                                    scaleAnimation.delay = newDelay;
                                                    EditorUtility.SetDirty(Target);
                                                }
                                            }
                                            GUILayout.EndHorizontal();
 
                                            //Is Custom
                                            GUILayout.BeginHorizontal();
                                            {
                                                GUILayout.Label("From", GUILayout.Width(labelWidth - 2f));
                                                if (GUILayout.Button(scaleAnimation.isCustom ? "Fixed Scale" : "Current Scale", "DropDownButton"))
                                                {
                                                    GenericMenu gm = new GenericMenu();
                                                    gm.AddItem(new GUIContent("Current Scale"), !scaleAnimation.isCustom, () => { scaleAnimation.isCustom = false; EditorUtility.SetDirty(Target); });
                                                    gm.AddItem(new GUIContent("Fixed Scale"), scaleAnimation.isCustom, () => { scaleAnimation.isCustom = true; EditorUtility.SetDirty(Target); });
                                                    gm.ShowAsContext();
                                                }
                                            }
                                            GUILayout.EndHorizontal();
 
                                            if (scaleAnimation.isCustom)
                                            {
                                                //From
                                                GUILayout.BeginHorizontal();
                                                {
                                                    GUILayout.Label(GUIContent.none, GUILayout.Width(labelWidth));
                                                    Vector3 newStartValue = EditorGUILayout.Vector3Field(GUIContent.none, scaleAnimation.startValue);
                                                    if (newStartValue != scaleAnimation.startValue)
                                                    {
                                                        Undo.RecordObject(Target, "On Hide Animation Scale From");
                                                        scaleAnimation.startValue = newStartValue;
                                                        EditorUtility.SetDirty(Target);
                                                    }
                                                }
                                                GUILayout.EndHorizontal();
                                            }
 
                                            //To
                                            GUILayout.BeginHorizontal();
                                            {
                                                GUILayout.Label("To", GUILayout.Width(labelWidth));
                                                Vector3 newEndValue = EditorGUILayout.Vector3Field(GUIContent.none, scaleAnimation.endValue);
                                                if (newEndValue != scaleAnimation.endValue)
                                                {
                                                    Undo.RecordObject(Target, "On Hide Animation Scale To");
                                                    scaleAnimation.endValue = newEndValue;
                                                    EditorUtility.SetDirty(Target);
                                                }
                                            }
                                            GUILayout.EndHorizontal();
 
                                            //Ease
                                            GUILayout.BeginHorizontal();
                                            {
                                                GUILayout.Label("Ease", GUILayout.Width(labelWidth));
                                                var newEase = (Ease)EditorGUILayout.EnumPopup(scaleAnimation.ease);
                                                if (newEase != scaleAnimation.ease)
                                                {
                                                    Undo.RecordObject(Target, "On Hide Animation Scale Ease");
                                                    scaleAnimation.ease = newEase;
                                                    EditorUtility.SetDirty(Target);
                                                }
                                            }
                                            GUILayout.EndHorizontal();
                                        }
                                        GUILayout.EndVertical();
                                    }
                                    GUILayout.EndHorizontal();
                                }
                                EditorGUILayout.EndFadeGroup();
 
                                //FadeAnimation
                                var fadeAnimation = animation.fadeAnimation;
                                if (EditorGUILayout.BeginFadeGroup(onHideFadeAnimBool.faded))
                                {
                                    GUILayout.BeginHorizontal("Badge");
                                    {
                                        GUILayout.BeginVertical();
                                        {
                                            GUILayout.Space(fadeAnimation.isCustom ? 40f : 30f);
                                            GUILayout.Label(EditorGUIUtility.IconContent("ViewToolOrbit"));
                                        }
                                        GUILayout.EndVertical();
 
                                        GUILayout.BeginVertical();
                                        {
                                            //Duration、Delay
                                            GUILayout.BeginHorizontal();
                                            {
                                                GUILayout.Label("Duration", GUILayout.Width(labelWidth));
                                                var newDuration = EditorGUILayout.FloatField(fadeAnimation.duration);
                                                if (newDuration != fadeAnimation.duration)
                                                {
                                                    Undo.RecordObject(Target, "On Hide Animation Fade Duration");
                                                    fadeAnimation.duration = newDuration;
                                                    EditorUtility.SetDirty(Target);
                                                }
 
                                                GUILayout.Label("Delay", GUILayout.Width(labelWidth - 20f));
                                                var newDelay = EditorGUILayout.FloatField(fadeAnimation.delay);
                                                if (newDelay != fadeAnimation.delay)
                                                {
                                                    Undo.RecordObject(Target, "On Hide Animation Fade Delay");
                                                    fadeAnimation.delay = newDelay;
                                                    EditorUtility.SetDirty(Target);
                                                }
                                            }
                                            GUILayout.EndHorizontal();
 
                                            //Is Custom
                                            GUILayout.BeginHorizontal();
                                            {
                                                GUILayout.Label("From", GUILayout.Width(labelWidth - 2f));
                                                if (GUILayout.Button(fadeAnimation.isCustom ? "Fixed Alpha" : "Current Alpha", "DropDownButton"))
                                                {
                                                    GenericMenu gm = new GenericMenu();
                                                    gm.AddItem(new GUIContent("Current Alpha"), !fadeAnimation.isCustom, () => { fadeAnimation.isCustom = false; EditorUtility.SetDirty(Target); });
                                                    gm.AddItem(new GUIContent("Fixed Alpha"), fadeAnimation.isCustom, () => { fadeAnimation.isCustom = true; EditorUtility.SetDirty(Target); });
                                                    gm.ShowAsContext();
                                                }
                                            }
                                            GUILayout.EndHorizontal();
 
                                            if (fadeAnimation.isCustom)
                                            {
                                                //From
                                                GUILayout.BeginHorizontal();
                                                {
                                                    GUILayout.Label(GUIContent.none, GUILayout.Width(labelWidth));
                                                    float newStartValue = EditorGUILayout.FloatField(GUIContent.none, fadeAnimation.startValue);
                                                    if (newStartValue != fadeAnimation.startValue)
                                                    {
                                                        Undo.RecordObject(Target, "On Hide Animation Fade From");
                                                        fadeAnimation.startValue = newStartValue;
                                                        EditorUtility.SetDirty(Target);
                                                    }
                                                }
                                                GUILayout.EndHorizontal();
                                            }
 
                                            //To
                                            GUILayout.BeginHorizontal();
                                            {
                                                GUILayout.Label("To", GUILayout.Width(labelWidth));
                                                float newEndValue = EditorGUILayout.FloatField(GUIContent.none, fadeAnimation.endValue);
                                                if (newEndValue != fadeAnimation.endValue)
                                                {
                                                    Undo.RecordObject(Target, "On Hide Animation Fade To");
                                                    fadeAnimation.endValue = newEndValue;
                                                    EditorUtility.SetDirty(Target);
                                                }
                                            }
                                            GUILayout.EndHorizontal();
 
                                            //Ease
                                            GUILayout.BeginHorizontal();
                                            {
                                                GUILayout.Label("Ease", GUILayout.Width(labelWidth));
                                                var newEase = (Ease)EditorGUILayout.EnumPopup(fadeAnimation.ease);
                                                if (newEase != fadeAnimation.ease)
                                                {
                                                    Undo.RecordObject(Target, "On Hide Animation Fade Ease");
                                                    fadeAnimation.ease = newEase;
                                                    EditorUtility.SetDirty(Target);
                                                }
                                            }
                                            GUILayout.EndHorizontal();
                                        }
                                        GUILayout.EndVertical();
                                    }
                                    GUILayout.EndHorizontal();
                                }
                                EditorGUILayout.EndFadeGroup();
 
                                break;
                            case UIAnimationType.Animator:
                                var animator = Target.GetComponent<Animator>();
                                if (animator != null)
                                {
                                    var animatorController = animator.runtimeAnimatorController as AnimatorController;
                                    var stateMachine = animatorController.layers[0].stateMachine;
                                    if (stateMachine.states.Length == 0)
                                    {
                                        EditorGUILayout.HelpBox("no animator state was found.", MessageType.Info);
                                    }
                                    else
                                    {
                                        string[] stateNames = new string[stateMachine.states.Length];
                                        for (int i = 0; i < stateNames.Length; i++)
                                        {
                                            stateNames[i] = stateMachine.states[i].state.name;
                                        }
                                        var index = Array.FindIndex(stateNames, m => m == animation.stateName);
                                        GUILayout.BeginHorizontal();
                                        GUILayout.Label("State Name", GUILayout.Width(titleWidth));
                                        var newIndex = EditorGUILayout.Popup(index, stateNames);
                                        if (newIndex != index)
                                        {
                                            Undo.RecordObject(Target, "Show Animation State Name");
                                            animation.stateName = stateNames[newIndex];
                                            EditorUtility.SetDirty(Target);
                                        }
                                        GUILayout.EndHorizontal();
                                    }
                                }
                                else
                                {
                                    EditorGUILayout.HelpBox("no animator component on this view.", MessageType.Error);
                                }
                                break;
                            default:
                                break;
                        }
                        break;
                    case Menu.UnityEvent:
                        //OnBeginEvent、OnEndEvent
                        EditorGUILayout.PropertyField(onHideBeginEvent);
                        EditorGUILayout.PropertyField(onHideEndEvent);
                        break;
                    default:
                        break;
                }
            }
 
            serializedObject.ApplyModifiedProperties();
        }
    }
}

以上就是Unity實戰之制作動畫編輯器的詳細內容,更多關於Unity動畫編輯器的資料請關註WalkonNet其它相關文章!

推薦閱讀: