在unity中处理UI事件时,习惯了使用NGUI的UIEventListener,虽然UGUI也有AddListener,但是一个组件只能对应一个函数,不能在一个函数中同时处理多个事件,显得有些麻烦

因为主要平时Button用得比较多,这里以UGUI的Button为例,自己以UGUI的Button的AddListener模仿NGUI的UIEventListener做了一个小封装,能在一个函数处理多个Button

using UnityEngine;
using UnityEngine.UI;
using System.Collections; public class UGUIButtonEventListener : MonoBehaviour { public delegate void VoidDelegate(GameObject go); public VoidDelegate onClick; public static UGUIButtonEventListener GetClick(Button btn)
{
UGUIButtonEventListener listener = btn.GetComponent<UGUIButtonEventListener>();
if (listener == null)
listener = btn.gameObject.AddComponent<UGUIButtonEventListener>();
btn.onClick.AddListener(listener.OnClick);
return listener;
} void OnClick()
{
if (onClick != null)
onClick(gameObject);
}
}

测试代码:

using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using UnityEngine.EventSystems; public class test : MonoBehaviour
{
public Button[] btns;
void Start()
{
for (int i = 0; i < btns.Length; i++)
UGUIButtonEventListener.Get(btns[i]).onClick = OnClick;
} void OnClick(GameObject go)
{
print("name:"+go.name);
}
}

还有人给了另一个Button事件监听的方法,感觉也挺好用

using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using UnityEngine.EventSystems; public class test : MonoBehaviour
{
public Button[] btns;
void Start()
{
for (int i = 0; i < btns.Length; i++)
{
GameObject btnObj=btns[i].gameObject;
btns[i].onClick.AddListener(delegate(){OnClick(btnObj);});
}
} void OnClick(GameObject go)
{
print("name:"+go.name);
}
}

但是UI事件肯定不止Button的Click事件,如果所有事件都按照上面的方法来封装就显得有些杂乱了。所以自己再去看了看UGUI的一些事件接口,发现通过实现接口,就能封装了,比如IPointerClickHandler,可以实现Click事件,IPointerEnterHandler、IPointerExitHandler可以实现Hover事件。后来再在网上查了一些资料,发现了EventTrigger已经继承了所有接口,正好可以用来封装UIEventListener

实现代码如下:

using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using UnityEngine.EventSystems; public class UGUIEventListener:EventTrigger
{
public delegate void VoidDelegate(GameObject go);
public delegate void BoolDelegate(GameObject go, bool isValue);
public delegate void FloatDelegate(GameObject go, float fValue);
public delegate void IntDelegate(GameObject go, int iIndex);
public delegate void StringDelegate(GameObject go, string strValue); public VoidDelegate onSubmit;
public VoidDelegate onClick;
public BoolDelegate onHover;
public BoolDelegate onToggleChanged;
public FloatDelegate onSliderChanged;
public FloatDelegate onScrollbarChanged;
public IntDelegate onDrapDownChanged;
public StringDelegate onInputFieldChanged; public override void OnSubmit(BaseEventData eventData)
{
if (onSubmit != null)
onSubmit(gameObject);
}
public override void OnPointerEnter(PointerEventData eventData)
{
if (onHover != null)
onHover(gameObject, true);
}
public override void OnPointerClick(PointerEventData eventData)
{
if (onClick != null)
onClick(gameObject);
if (onToggleChanged != null)
onToggleChanged(gameObject, gameObject.GetComponent<Toggle>().isOn); }
public override void OnPointerExit(PointerEventData eventData)
{
if (onHover != null)
onHover(gameObject, false);
}
public override void OnDrag(PointerEventData eventData)
{
if (onSliderChanged != null)
onSliderChanged(gameObject, gameObject.GetComponent<Slider>().value);
if (onScrollbarChanged != null)
onScrollbarChanged(gameObject, gameObject.GetComponent<Scrollbar>().value); }
public override void OnSelect(BaseEventData eventData)
{
if (onDrapDownChanged != null)
onDrapDownChanged(gameObject, gameObject.GetComponent<Dropdown>().value);
}
public override void OnUpdateSelected(BaseEventData eventData)
{
if (onInputFieldChanged != null)
onInputFieldChanged(gameObject, gameObject.GetComponent<InputField>().text);
}
public override void OnDeselect(BaseEventData eventData)
{
if (onInputFieldChanged != null)
onInputFieldChanged(gameObject, gameObject.GetComponent<InputField>().text);
} public static UGUIEventListener Get(GameObject go)
{
UGUIEventListener listener =go.GetComponent<UGUIEventListener>();
if(listener==null) listener=go.AddComponent<UGUIEventListener>();
return listener;
}
}

测试代码如下:

using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using UnityEngine.EventSystems; public class test : MonoBehaviour
{
public Button[] btns;
public Scrollbar scrollbar;
void Start()
{
for (int i = 0; i < btns.Length; i++)
UGUIEventListener.Get(btns[i].gameObject).onClick = OnClick;
UGUIEventListener.Get(scrollbar.gameObject).onScrollbarChanged = OnScrollbarChanged;
} void OnClick(GameObject go)
{
print("name:"+go.name);
} void OnScrollbarChanged(GameObject go, float value)
{
print("name:" + go.name + " value:" + value);
}
}

最后,还有一个小东西,因为自己在做一些测试的时候,发现UGUI的点击事件与3D物体的射线碰撞,是会发生冲突的,理论上,自己在点击UI的时候,3D物体的射线碰撞检测就会取消,不能让他们同时响应,这里用一个函数就可以判断EventSystem.current.IsPointerOverGameObject()

using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using UnityEngine.EventSystems; public class test : MonoBehaviour
{
void Update()
{
if (EventSystem.current.IsPointerOverGameObject())
Debug.Log("鼠标在UI上");
else
Debug.Log("鼠标没在UI上");
}
}

UGUI实现NGUI的UIEventListener功能的更多相关文章

  1. 【转】UGUI VS NGUI

    原文:http://gad.qq.com/college/articledetail/7191053 注[1]:该比较是基于15年-16年期间使用NGUI(3.8.0版本)与UGUI(4.6.9版本) ...

  2. 转:UGUI与NGUI的区别与优缺点

    1. NGUI与UGUI的区别 1) uGUI的Canvas 有世界坐标和屏幕坐标   2) uGUI的Image可以使用material     3) UGUI通过Mask来裁剪,而NGUI通过Pa ...

  3. uGUI VS NGUI

    前言 这篇日志的比较是根据自己掌握知识所写的,请各路大神多多指教. 引擎版本: Unity 4.6 beta 两者区别 1.uGUI的Canvas 有世界坐标和屏幕坐标 2.uGUI的Button属性 ...

  4. Unity UGUI 实现简单拖拽功能

    说到拖拽,那必然离不开坐标,UGUI 的坐标有点不一样,它有两种坐标,一种是屏幕坐标,还有一种就是 UI 在Canvas内的坐标(暂时叫做ugui坐标),这两个坐标是不一样的,所以拖拽就需要转换. 因 ...

  5. Unity3D 使用Socket处理数据并将数据 在UGUI、NGUI上显示出来

    Unity3d 不支持C#的线程直接调用Unity3D 主线程才能实现的功能.例如:给UGUI text 赋值.改变Color值等.怎样解决这个问题呢?使用一个Loom脚本. 按照惯例贴上代码. 首先 ...

  6. UGUI和NGUI的优化分享

    学习资料 来自UWA的分享,针对于Unity 4.x 及5.3 以下版本,Unity5.5及更高版本可能适用. 文章:UWA技术直播视频集锦 UGUI &NGUI http://blog.uw ...

  7. NGUI实现ScrollView功能

    NGUI,目前Unity3D Assert Store中最火的2D图形界面工具. 本文假设读者有Unity3D使用经验.有基本了解.NGUI3.6.0 1.新建Pannel(Scroll View), ...

  8. Unity3d使用UGUI实现长按功能

    UGUI的Button组件只有OnClick事件的监听,要实现长按功能,要监听按下事件和抬起事件,所以要使用到EventTrigger组件中的OnPointerDown和OnPointerUp来监听. ...

  9. Unity NGUI和UGUI与模型、特效的层级关系

    目录 1.介绍两大UI插件NGUI和UGUI 2.unity渲染顺序控制方式 3.NGUI的控制 4.UGUI的控制 5.模型深度的控制 6.粒子特效深度控制 7.NGUI与模型和粒子特效穿插层级管理 ...

随机推荐

  1. JavaScript Window Navigator

    window.navigator 对象包含有关访问者浏览器的信息. Window Navigator window.navigator 对象在编写时可不使用 window 这个前缀. 实例 <d ...

  2. RX系列一 | ReactiveX根源 | 观察者模式分析

    RX系列一 | ReactiveX根源 | 观察者模式分析 Rx的响应式编程算是很火了,对吧,但是我的工作基本上就不会接触,所以学习的比较晚,到现在才分享给大家,我们一点点的去学,当你看完这整个系列的 ...

  3. Spring中配置DataSource的六种方式

    第一种:beans.xml <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource ...

  4. Docker学习笔记1:CentOS7 下安装Docker

    本文内容摘自官网:https://docs.docker.com/engine/installation/linux/centos/#/create-a-docker-group 注:本文是介绍Lin ...

  5. HBase的环境配置及其应用

    -------------------------------------------------------------------------------------- [版权申明:本文系作者原创 ...

  6. Swift:Minimizing Annotation with Type Inference

    许多程序猿更喜欢比如Python和Javascript这样的动态语言,因为这些语言并不要求程序猿为每个变量声明和管理它们的类型. 在大多数动态类型的语言里,变量可以是任何类型,而类型声明是可选的或者根 ...

  7. java获取ip的方式,注意多级代理的方式获取

    public String getIP() { String clientIP = ServletActionContext.getRequest().getHeader("x-forwar ...

  8. springMVC源码分析--异常处理机制HandlerExceptionResolver执行原理(二)

    上一篇博客springMVC源码分析--异常处理机制HandlerExceptionResolver简单示例(一)中我们简单地实现了一个异常处理实例,接下来我们要介绍一下HandlerExceptio ...

  9. FFmpeg的HEVC解码器源代码简单分析:解码器主干部分

    ===================================================== HEVC源代码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpe ...

  10. Spark-1.6.0中的Sort Based Shuffle源码解读

    从Spark-1.2.0开始,Spark的Shuffle由Hash Based Shuffle升级成了Sort Based Shuffle.即Spark.shuffle.manager从Hash换成了 ...