UGUI初探之Button

Button是Unity中最常用的组件之一。

来看下具体实现,继承自Selectable基类,并实现了IPointerClickHandlerISubmitHandler接口。

先看看官方对于Selectable类的描述:

Simple selectable object - derived from to create a selectable control.

译:简单可选择对象-从派生以创建可选择控件。

这是在Inspector面板下的显示:

Selectable类及其子类在某一特定时刻都有相对应的状态。并且定义了状态的变化表现。

可以从Transition处选择表现类型:

当前使用的表现为颜色的变化,下面的分别是切换图片、触发动画。

扫描二维码关注公众号,回复: 5821342 查看本文章

Navigation项可以选择导航方式,可以通过上下左右键来切换当前选中的Selectable对象(前提是当前有选中对象)。

通过查看Selectable类的代码发现:

 private static List<Selectable> s_List = new List<Selectable>();

里面定义了一个静态列表专门用来保存所有Selectable组件。每次切换时便从中取出正确的目标。

IPointerClickHandler接口应该是比较常用的,这里就不做赘述了。

ISubmitHandler接口里只定义了一个OnSubmit(BaseEventData eventData)方法。

当触发提交键的时候会调用当前选中物体OnSubmit方法。

我们可以在Input设置中查看默认的提交键:

默认有两个,一个为enter,一个为return

接下来看看Button类中具体做了些什么。

public class ButtonClickedEvent : UnityEvent {}

[FormerlySerializedAs("onClick")]
[SerializeField]
private ButtonClickedEvent m_OnClick = new ButtonClickedEvent();

protected Button(){}

public ButtonClickedEvent onClick
{
    get { return m_OnClick; }
    set { m_OnClick = value; }
}

首先,定义了一个继承自UnityEventButtonClickEvent事件类。

UnityEvent里封装了Invoke,AddListener,RemoveListener等方法。

平时绑定移除监听就是在m_Onclick中进行的。

private void Press()
{
    if (!IsActive() || !IsInteractable())
                return;

    UISystemProfilerApi.AddMarker("Button.onClick", this);
    m_OnClick.Invoke();
}

public virtual void OnPointerClick(PointerEventData eventData)
{
    if (eventData.button != PointerEventData.InputButton.Left)
        return;

    Press();
}

熟悉的OnPointerClick方法,仅当Left会触发Press()方法。

Press中也限定了同时满足IsActive()IsInteractable才会调用m_Onclick绑定的监听

通过不断的追溯IsActive()最终定位到了isActiveAndEnabled这个字段。通过意思来推测ActiveEnable均为true时才返回true

这里我想提出一个疑问,为什么会有Activetrue这个条件,难道这个Button即使Activefalse时也能监听到点击?那么是不是可以大胆臆测一下其实Activefalse的Button还在场景中原来的位置,只是没有渲染出来?那是不是所有GameObject都是这样处理的?这个问题等我以后来解决。

public virtual void OnSubmit(BaseEventData eventData)
{
    Press();
    if (!IsActive() || !IsInteractable())
        return;

    DoStateTransition(SelectionState.Pressed, false);
    StartCoroutine(OnFinishSubmit());
}

private IEnumerator OnFinishSubmit()
{
    var fadeTime = colors.fadeDuration;
    var elapsedTime = 0f;

    while (elapsedTime < fadeTime)
    {
        elapsedTime += Time.unscaledDeltaTime;
        yield return null;
    }

     DoStateTransition(currentSelectionState, false);
}

最后还有一个虚函数OnSubmit,我们发现这里也会调用Press()。

我们可以通过继承Button类重写OnSubmit方法来进行拓展。

但是多出来的状态转换和协程是做啥的,为什么OnPointerClick里没有?

还有什么情境下会用到这个东西?

等以后想到了到了再补充。

猜你喜欢

转载自blog.csdn.net/a977621265/article/details/86623952