Unity UI(uGUI) 源码学习笔记(一) Button

Unity在4.6版本推出了自己的UI系统,虽然目前功能相比NGUI等成熟的Asset还比较少,但是使用它来开发游戏项目还是完全没有问题的。
而且Unity官方开源了UI系统的C#源代码,我们也可以学习一下Unity是如何实现这套UI系统的。

源代码下载

https://bitbucket.org/Unity-Technologies/ui
Unity是把代码放在了Bitbucket上面,通过SourceTree等客户端软件,就可以克隆整个项目到本地。
克隆到本地之后,可以是用Visual Studio或者MonoDevelop对源代码进行修改和编译。

从Button开始学习

首先从一个最简单的Button开始学习UI系统的源代码。
通过Button的源代码,再逐步去学习关联的源代码。

Button源代码

Button的Class位于UnityEngine.UI的package中,我们可以看到UISystem是有二个package的,UnityEngine是核心Class的实现,UnityEditor是对Editor的扩展,方便大家使用。
f:id:lvmingbei:20150512141848p:plain

通过上面的源代码我们可以看到,当前这个版本的Button Class只有74行代码,很适合用来入门用。

类的定义

public class Button : Selectable, IPointerClickHandler, ISubmitHandler

首先我们看Button类的定义,Button继承自Selectable,并且实现了两个接口IPointerClickHandlerISubmitHandler
通过Unity的文档我们可以得知,Selectable类是一种可以被选择的组件的基类,两个接口分别是接受OnPointerClick和OnSubmit两个CallBack方法。 以后再学习Selectable类的源代码,先继续向后读Button的代码。

// Event delegates triggered on click.
[FormerlySerializedAs("onClick")]
[SerializeField]
private ButtonClickedEvewnt m_OnClick = new ButtonClickedEvent();

这里定义了一个叫m_OnClick的变量,类型为ButtonClickedEvent。看命名应该是用来设置Button点击时候的事件。
ButtonClickedEvent是继承自UnityEvent的空Class。

我们继续往后看,后面是两个接口定义的CallBack方法的实现。

// Trigger all registered callbacks.
public virtual void OnPointerClick(PointerEventData eventData)
{
    if (eventData.button != PointerEventData.InputButton.Left)
        return;

    Press();
}

public virtual void OnSubmit(BaseEventData eventData)
{
    Press();

    // if we get set disabled during the press
    // don't run the coroutine.
    if (!IsActive() || !IsInteractable())
        return;

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

OnPointerClick方法是当点击Button时调用,首先判断是否为左键,如果是左键,就立即调用私有的Press方法。
Press方法是Invoke所有注册的onClick的CallBack方法。 OnSubmit方法是当提交的时候调用。 首先通过继承的DoStateTransition方法,显示Pressed状态的动画或者Fade效果,然后使用Coroutine等待Fade结束,再次调用DoStateTransition进行Button的状态迁移。

Button的源代码就简单分析到这里,再向下分析涉及到许多更底层的实现,后续会继续分析关联到的其他Class的代码。 包括一些Selectable(可选择组件基类),EventSystems(事件系统),InputModule(输入模块)等等。