「Unity3D」(4)使用AnimBool自定义Inspector动画效果

Unity自己的组件,Inspector面板都有动画效果,本文将会结合UGUI中ImageEditor的动画效果,介绍一下Inspector动画效果如何实现。UGUI的源码,这里获取 UGUIImageEditor

首先看一下,ImageEditor面板的动画效果。

ImageType的切换,会有动画显示不同的内容区域。对应源码我们看到,每个动画都要对应一个AnimBool对象。

  • 第一步,定义AnimBool。
AnimBool m_ShowSlicedOrTiled;
AnimBool m_ShowSliced;
AnimBool m_ShowFilled;
AnimBool m_ShowType;
  • 第二步,在OnEnable回调函数里初始化AnimBool对象。于此同时,需要注册valueChanged的监听事件,Repaint为父类函数。
protected override void OnEnable()
{
    // ...
    m_ShowType          = new AnimBool(m_Sprite.objectReferenceValue != null);
    m_ShowSlicedOrTiled = new AnimBool(!m_Type.hasMultipleDifferentValues && typeEnum == Image.Type.Sliced);
    m_ShowSliced        = new AnimBool(!m_Type.hasMultipleDifferentValues && typeEnum == Image.Type.Sliced);
    m_ShowFilled        = new AnimBool(!m_Type.hasMultipleDifferentValues && typeEnum == Image.Type.Filled);

    m_ShowType.valueChanged.AddListener(Repaint);
    m_ShowSlicedOrTiled.valueChanged.AddListener(Repaint);
    m_ShowSliced.valueChanged.AddListener(Repaint);
    m_ShowFilled.valueChanged.AddListener(Repaint);

    // ...
}
  • 第三步,在OnDisable回调函数里,也要同步移除Repaint事件。
protected override void OnDisable()
{
     m_ShowType.valueChanged.RemoveListener(Repaint);
     m_ShowSlicedOrTiled.valueChanged.RemoveListener(Repaint);
     m_ShowSliced.valueChanged.RemoveListener(Repaint);
     m_ShowFilled.valueChanged.RemoveListener(Repaint);
}
  • 第四步,在OnInspectorGUI中使用AnimBool对象。
public override void OnInspectorGUI()
{
    // ...
    m_ShowSlicedOrTiled.target = showSlicedOrTiled;
    m_ShowSliced.target        = (showSlicedOrTiled && !m_Type.hasMultipleDifferentValues && typeEnum == Image.Type.Sliced);
    m_ShowFilled.target        = (!m_Type.hasMultipleDifferentValues && typeEnum == Image.Type.Filled);

    // ...

    if (EditorGUILayout.BeginFadeGroup(m_ShowType.faded))
        TypeGUI();
    EditorGUILayout.EndFadeGroup();

    if (EditorGUILayout.BeginFadeGroup(m_ShowNativeSize.faded))
    {
        EditorGUI.indentLevel++;
        EditorGUILayout.PropertyField(m_PreserveAspect);
        EditorGUI.indentLevel--;
    }
    EditorGUILayout.EndFadeGroup();

   // ...
}

BeginFadeGroup配合AnimBool的faded属性完成动画。当动画完成时候BeginFadeGroup返回true,这时就可以绘制面板属性了。AnimBool的faded属性是float类型,由系统tween动画驱动。而动画触发是由AnimBool的target属性来控制的。

AnimBool的构造函数有4个重载函数,能够设置初始化的动画是否执行,和动画完成的回调函数。

最后

理论上,面板上的属性都可以添加动画,来控制显示和隐藏的效果。只是写起来有些费事,需要额外的努力,可是为什么Unity的组件都添加了动画效果了呢 ?可能有钱也有闲,加个动画用起来感觉棒棒的。


「动画很好,就是费事」

猜你喜欢

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