Unity_UGUI_Buton底层探究

最近换了公司(仍然是实习狗),坐标在上海, 楼上是Unity总部。很开心~~
上海和广东差别 并不是很大。就是天气比较冷,口味偏甜, 这家公司是创业公司,做教育类应用的, VR/AR MR 等, 第一天 就要上手SDK,也不是很难,Zspace的 相对VRTK来说 比较 简单,开发工程中遇到Button交互,所以要对它进行 重写,设备是 用射线进行 探测,
其实 重写Button也比较简单,也可以不用重写, 但还是建议重写会比较好。
之前有写过射线交互的例子
https://blog.csdn.net/qq2512667/article/details/79493117
https://blog.csdn.net/qq2512667/article/details/79842850
原理都差不多的, 射线交互 现在用的挺多的,

NGUI 用的就是射线探测
但UGUI不是,是根据坐标,射线,结合去判断的·。
Button
Button 继承自 Selectable
官方源码

在这里插入图片描述

FormerlySerializedAs( "“onClick”) ButtonClickEvent m_Onclick
这个特性就是备胎特性,当Onclick被删除 后, Onlickx序列化后就存在 m_Onclick 中

DoStateTransition(currentSelectionState, false);
DoStateTransition
这个 方法 比较重要,就是设置Button的交互转换状态,在重写的时候。需要用到这个方法。

这个方法就是转换 Button的状态

Selectable这个类 继承 UIBehaviour
在这里插入图片描述

还 继承到UIBehaviour, 而且UIBehaviour 多个 UI 组件都回继承它, 具体是干什么的呢?
UIBehaviour 基本上所有的UI控件 都继承到它
生命周期函数 都这里,
以及一些 事件响应函数
在这里插入图片描述

继承自 MonoBehaviour 大家都熟悉

MonoBehaviour继承自 Behaviour
在这里插入图片描述
之前 很好奇 为什么 MonoBehaviour 里 可以使用Print() 打印函数 原来是在这里
这里还有 协同函数
其实 背后就是一个迭代器实现的。迭代器背后又是怎么实现的呢,其实就是一个状态机,
MoveNext()方法 依托于switch语句,根据状态机的状态,执行不同代码。

MonoBehaviour 是继承自Behaviour的
在这里插入图片描述
Behaviour是继承自 compont的
compont: 消耗性能的BroadcastMessage 名声 很差
在这里插入图片描述
最后就是UnityEngine 里的Object 基类了

在这里插入图片描述
Button——Selectable——UIBehaviour(生命周期函数)——Behaviou——Compoent——Object

重写思路,射线分为 射线进入, 射线停留,射线离开

因此 写3个方法 就可以了

事件 传递UML 类图(借助松阳大神的)
在这里插入图片描述
在这里插入图片描述
ClickHandler 响应 Click
在这里插入图片描述
OnFinishSubmit 这个方法就是 协程,具体就是 点了按钮之后回由个渐渐变色的过程。

最后再梳理一遍 Button

在这里插入图片描述
Button 继承的类, 事件系统是基于Unity的, 在移除 事件的时候,通过反射去对比

在这里插入图片描述
一个 无参 无返回 委托。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这里的UnityEventBase 类 从当一个中介者的角色,
移除监听 事件时,会调用InvokableCallList 类里的RemoveListener。
RemoveListener方法会调用BaseInvokableCall的 Find方法

这里的UnityEvent 在移除 事件时,会通过反射,取得MethodInfo 再去 对比。
在这里插入图片描述
这里不废话c#反射机制了。

EventSystem

优缺点。每次添加 监听 事件时,并没有对应的 事件码, 这样查找就要去 每个通过反射的方式去查找,比较消耗性能,而且添加 每个按钮响应事件 应该 ,给个事件Id ,才知道是哪个事件被触发了。管理很不方便。

下面是 重写 射线Button

public class RayButton : Button
{

    public UnityEngine.Events.UnityEvent MenuUIEvent;
    /// <summary>
    ///  视线进入 
    /// </summary>
    public virtual void RayEneter()
    {
        DoStateTransition(SelectionState.Highlighted, false);
    }
    /// <summary>
    /// 视线停留
    /// </summary>
    public virtual void RayStay()
    {
        ReSetButtonState();
    }

    /// <summary>
    ///  视线离开
    /// </summary>
    public virtual void RayExit()
    {
        DoStateTransition(SelectionState.Normal, false);
    }
    public virtual void TriggerEvent()
    {
        onClick.Invoke();//调用下 Click事件
        DoStateTransition(SelectionState.Pressed, false);
    }
    /// <summary>
    /// 事件完成
    /// </summary>
    public virtual void ReSetButtonState()
    {
        DoStateTransition(SelectionState.Highlighted, false);
    }

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值