「Unity3D」(11) Inspector FadeGroup动画嵌套问题和实现Tween Ease效果

本文将讨论面板属性Inspector的动画,也就是BeginFadeGroup与EndFadeGroup,嵌套使用问题的形成和解决。以及如何应用Tween Ease的各种效果到Inspector动画控制上。

FadeGroup动画嵌套

当一对[BeginFadeGroup, EndFadeGroup]嵌套在,另一对[BeginFadeGroup, EndFadeGroup]之中的时候,会产生动画匹配错误,也就是BeginFadeGroup对应了错误的EndFadeGroup。如下图所示:

可以看到,OuterData的动画直接匹配到了,Data1的动画上了。也就是,OuterData折叠到Data1的位置,动画就结束了。代码如下:

public class FadeGroupTest : MonoBehaviour 
{
    // 外层对象包含三个内层对象
    public OuterData outerData;

    [System.Serializable]
    public class OuterData
    {
        public InnerData data1;
        public InnerData data2;
        public InnerData data3;
    }

    [System.Serializable]
    public class InnerData
    {
        public int a;
        public int b;
        public int c;
    }
}
[CustomEditor(typeof(FadeGroupTest))]
public class FadeGroupTestEditor : Editor
{
    private SerializedProperty outer;
    private AnimBool           outerAnim;
    private AnimBool           innerAnim;

    private SerializedProperty inner1;
    private SerializedProperty inner2;
    private SerializedProperty inner3;

    private void OnEnable()
    {
        this.outer     = this.serializedObject.FindProperty("outerData");
        // 外层动画
        this.outerAnim = new AnimBool(true);
        this.outerAnim.valueChanged.AddListener(this.Repaint);

        // 内层动画     
        this.innerAnim = new AnimBool(true);
        this.innerAnim.valueChanged.AddListener(this.Repaint);

        this.inner1    = this.outer.FindPropertyRelative("data1");
        this.inner2    = this.outer.FindPropertyRelative("data2");
        this.inner3    = this.outer.FindPropertyRelative("data3");
    }


    private void OnDisable()
    {
        this.outerAnim.valueChanged.RemoveListener(this.Repaint);
        this.innerAnim.valueChanged.RemoveListener(this.Repaint);
    }


    public override void OnInspectorGUI()
    {
        this.serializedObject.Update();

        this.outerAnim.target = EditorGUILayout.PropertyField(this.outer);
        // 外层动画
        if (EditorGUILayout.BeginFadeGroup(this.outerAnim.faded)) 
        {
            EditorGUI.indentLevel++;


            this.innerAnim.target = EditorGUILayout.PropertyField(this.inner1);
            // 内层动画
            if (EditorGUILayout.BeginFadeGroup(this.innerAnim.faded)) 
            {
                EditorGUILayout.BeginVertical(GUI.skin.box);
                EditorGUILayout.PropertyField(this.inner1.FindPropertyRelative("a"));
                EditorGUILayout.PropertyField(this.inner1.FindPropertyRelative("b"));
                EditorGUILayout.PropertyField(this.inner1.FindPropertyRelative("c"));
                EditorGUILayout.EndVertical();
            }
            // 内层动画结束
            // 外层动画开始,会匹配到这个结束,产生错误
            EditorGUILayout.EndFadeGroup(); 


            EditorGUILayout.PropertyField(this.inner2, true);
            EditorGUILayout.PropertyField(this.inner3, true);
            EditorGUI.indentLevel--;
        }
        // 外层动画结束
        EditorGUILayout.EndFadeGroup();

        this.serializedObject.ApplyModifiedProperties();
    }
}

解决嵌套错误的办法有两种

第一种,使用动画条件判断

// 当外层动画不在运行,或是内层动画运行时,这时候才关闭EndFadeGroup,否则跳过关闭函数。
// 这样就可以避免BeginFadeGroup匹配错误了
if (this.outerAnim.isAnimating == false || this.innerAnim.isAnimating)
{
    EditorGUILayout.EndFadeGroup();
}

第二种,使用垂直布局

// 垂直布局整体套在动画外面,就可以防止动画匹配的错乱问题
EditorGUILayout.BeginVertical(GUI.skin.box);
this.innerAnim.target = EditorGUILayout.PropertyField(this.inner1);
if (EditorGUILayout.BeginFadeGroup(this.innerAnim.faded))
{
    EditorGUILayout.PropertyField(this.inner1.FindPropertyRelative("a"));
    EditorGUILayout.PropertyField(this.inner1.FindPropertyRelative("b"));
    EditorGUILayout.PropertyField(this.inner1.FindPropertyRelative("c"));

}
EditorGUILayout.EndFadeGroup();
// 垂直布局结束
EditorGUILayout.EndVertical();

使用Tween Ease来驱动FadeGroup动画

AnimBool本身是一个Tween的实现,但只有Mathf.Lerp一种缓动算法,而BeginFadeGroup(float)需要的只是一个当前动画位置的值,我们可以自己实现各种Tween Ease缓动算法,来实现各种效果。比如下面这个BounceOut:

实现思路有两种:

  1. 手动实现编辑器的Tween和Ease,并使用它来生成BeginFadeGroup的value数值。
  2. 手动扩展AnimBool的实现,使其具有切换TweenEase算法的功能。

「动画是体验」

猜你喜欢

转载自blog.csdn.net/tom_221x/article/details/79665715