http://blog.csdn.net/icefantasylcj/article/details/49450555

  大家好,我是雨中祈雨。一直以来,CSDN都是我最好的编程助手。这是我在CSDN的第一篇关于Unity3D的博客,其实也就是记录我在学习Unity3D时遇到的一些小问题从不懂到有所了解的过程。另一方面,如果能帮助到遇到过同样问题的Unity3D初学者朋友们,那就再好不过了。

  NGUI是一款非常好用的Unity3D插件,其简单的操作、强大的分辨率自适应以及效果良好的缓动动画等等都是大家青睐于它的原因。今天我就和大家分享一下我在实现NGUI事件监听过程中遇到的一些问题及其解决方法。 
  为按钮添加OnClick事件是比较简单的,做法是将需要在按钮点击时调用的公有方法写在一个继承自MonoBehavior类的脚本中,并将该脚本绑定在任意GameObject对象上,然后将该GameObject拖动至UIButton Script上的OnClick事件栏上即可。

using UnityEngine;
using System.Collections; public class UIController : MonoBehaviour { public void OnButtonClick()
{
Debug.Log("呀,被点到了!");
} }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

  另外,如下代码也可以为指定的按钮添加OnClick事件。 
  

using UnityEngine;
using System.Collections; public class UIController : MonoBehaviour { private UIButton button; void Awake()
{
//假设场景中有个名为Button的GameObject,获取其上绑定的按钮组件
button = GameObject.Find("Button").GetComponent<UIButton>();
} void Start()
{
button.onClick.Add(new EventDelegate(onButtonClick)); #region UI Listener
void onButtonClick()
{
Debug.Log("触发按钮点击事件。");
}
#endregion
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

  这两做法同样适用于为Slider、ProgressBar等组件添加事件,也算比较方便,而且有助于UI事件的统一管理。不足之处就是需要执行拖动的步骤,而且对按钮来言,只能监听单一的OnClick事件。当遇到需要监听按钮的OnHover、OnDragOver等事件时,这种做法便无能为力了。 
  对于需要监听按钮其他事件的情况(此处以OnHover事件为例),一种方法是自己重载UIButton的OnHover等函数:

    //自定义类CustomButton,继承自NGUI的UIButton
public class CustomButton : UIButton { //重载OnHover函数
protected override void OnHover(bool isOver)
{
//base能够调用基类的同名函数,有点类似于java中的
//super关键字 Q.Q
base.OnHover(isOver);
if (isOver)
{
Debug.Log("执行按钮的Hover事件。");
}
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

  还有一种方法就是使用UIEventListener去处理各种UI事件,这种方法也是雨松大神向我们推荐过的一种方法(雨松大神威武)。学过Java的朋友们知道,Java中的观察者(Observer)模式在监听各种事件时那是相当的方便。而C#中也有一个同样很优秀的事件(Event)和委托(Delegate)机制。其实文章开始的那种拖动的方法也使用了事件委托机制,在此我就不赘述事件委托机制的原理,只给大家介绍这种机制在NGUI事件监听中的运用。 
仍以OnHover为例:

using UnityEngine;
using System.Collections; public class UIController : MonoBehaviour { private GameObject go_TestButton; void Awake()
{
//获取Button或者其他组件的GameObject对象
go_TestButton = GameObject.Find("UI Root/StartUI/ButtonAnchor/Button");
} void Start()
{
UIEventListener.Get(go_TestButton).onHover = OnButtonHover;
//此处可以使用+=运算符添加多个事件
//如:UIEventListener.Get(go_TestButton).onHover += OnButtonHover;
} public void OnButtonHover(GameObject btn,bool isOver)
{
if (isOver)
{
Debug.Log("执行"+btn.name+"按钮的OnHover事件");
}
} }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

  这样的话也可以监听Button的其他事件。不过,对于其他的事件来说,相应的函数参数也要进行改变。因为不同委托的事件类型是不一样的。看UIEventListener源码:

    //delegate 委托关键字
//其形式有点类似于C的函数指针-_-
public delegate void VoidDelegate (GameObject go);
public delegate void BoolDelegate (GameObject go, bool state);
public delegate void FloatDelegate (GameObject go, float delta);
public delegate void VectorDelegate (GameObject go, Vector2 delta);
public delegate void ObjectDelegate (GameObject go, GameObject draggedObject);
public delegate void KeyCodeDelegate (GameObject go, KeyCode key); public VoidDelegate onSubmit;
public VoidDelegate onClick;
public VoidDelegate onDoubleClick;
public BoolDelegate onHover;
public BoolDelegate onPress;
public BoolDelegate onSelect;
public FloatDelegate onScroll;
public VectorDelegate onDrag;
public ObjectDelegate onDrop;
public KeyCodeDelegate onKey;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

  不同委托对应着不同的函数以及函数形参。对于onScroll事件来说,函数的写法就应该这样:

    public void OnScroll(GameObject go,float value)
{
//执行事件
}
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

  好了,以上就是使用UIEventListener监听UI事件的方法了。感兴趣的朋友可以去深入了解一下事件委托机制,对于提高编程的效率还是很有帮助的。

  但是,有的同学可能会觉得,第一种方法挺好用的,不仅简单粗暴,而且管理起来也挺方便的,有没有什么办法向OnClick那样将其他的事件列表显示在Inspector面板上呢?答案是有的。这里就要用到Unity3D的Editor类了,这个类的作用就是允许用户对Unity3D编辑器进行一些修改。此处简易改编的原理请去NGUI的源码中探索(提示:UIButtonEditor类)~

话不多说上代码(仍是以Button的OnHover事件为例):

/*这个类请放在Unity3D Assets根目录的Editor目录下*/
using UnityEngine;
using UnityEditor; [CanEditMultipleObjects]
#if UNITY_3_5
[CustomEditor(typeof(CustomButton))]
#else
[CustomEditor(typeof(CustomButton), true)]
#endif public class CustomButtonEditor : UIButtonEditor{ //重载UIButtonEditor的DrawProperties方法,
//用于在Inspector面板上显示用户自定义的内容
protected override void DrawProperties()
{
base.DrawProperties(); CustomButton cButton = target as CustomButton; NGUIEditorTools.DrawEvents("Mouse Over", cButton, cButton.mouseOver); NGUIEditorTools.DrawEvents("Mouse Out", cButton, cButton.mouseOut);
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
/*请移除原先Button上的UIButton脚本,并绑定这个继承自UIButton的脚本*/
using UnityEngine;
using System.Collections;
using System.Collections.Generic; public class CustomButton : UIButton
{ public List<EventDelegate> mouseOver = new List<EventDelegate>(); public List<EventDelegate> mouseOut = new List<EventDelegate>(); protected override void OnHover(bool isOver)
{
base.OnHover(isOver); if (current == null && isEnabled)
{
current = this;
if (isOver)
{
EventDelegate.Execute(mouseOver);
}
else
{
EventDelegate.Execute(mouseOut);
}
current = null;
}
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

  由于我水平有限,不清楚如和将OnHover传出的isOver参数传入EventDelegate类的成员中,只好分别定义两个事件MouseOver与MouseOut,还请了解的朋友指点。

  接下来该怎么做……大家都懂了吧?(真·直接拖动法什么的最喜欢了) 
上图:

  这是我第一次写博客,很多地方可能表达的都很不到位,还望大家海涵。希望能对同为Unity3D的初学者朋友们起到一定的帮助作用。谢谢!

【转】 NGUI 监听按钮除OnClick外其他事件的方法,附简易改编的UIButton类的更多相关文章

  1. 【转】监听按钮除OnClick外其他事件的方法,附简易改编的UIButton类

    http://lib.csdn.net/article/unity3d/38463 作者:IceFantasyLcj 大家好,我是雨中祈雨.一直以来,CSDN都是我最好的编程助手.这是我在CSDN的第 ...

  2. ButtonAddListener监听按钮点击事件

    ButtonAddListener监听按钮点击事件 using UnityEngine; using System.Collections; using UnityEngine.UI; using U ...

  3. xcode UIButton创建、监听按钮点击、自定义按钮 、状态 、内边距

    代码创建 //创建UIButton UIButton * btnType=[[UIButton alloc]init]; //设置UIControlStateNormal状态下的文字颜色 [btnTy ...

  4. swift项目第七天:构建访客界面以及监听按钮点击

    一:访客界面效果如图 二:xib封装访客视图的view 1:业务逻辑分析:1:由于用户未登录时要显示访客视图,要先进行判断用户是否登录,未登录则显示访客视图,登录则显示正常的登陆界面,由于要在四个子控 ...

  5. ipv4、ipv6的socket同时监听“bind: Address already in use”的解决方法

    创建ipv4和ipv6的socket,同时监听某个端口的ipv4和ipv6报文,运行时bind函数执行失败,提示“bind: Address already in use”.原因:ipv6的socke ...

  6. jQuery-使用hover(fn,fn)函数监听mouseover和mouseout两个事件

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  7. VueApp监听手机物理返回键的事件

    代码 第一步创建js文件夹子 在main里面引用   JS文本内容如下 //监听手机物理返回键的事件 document.addEventListener('plusready', function() ...

  8. Android 监听按钮的点击事件

    onClick事件1.Button和ImageButton都拥有一个onClick事件 通过自身的.setOnClickListener(OnClickListener)方法添加点击事件2.所有的控件 ...

  9. NGUI监听事件

    using UnityEngine; using System.Collections; public class UIDataHandler : MonoBehaviour { public UII ...

随机推荐

  1. 读书笔记<白帽子讲web安全>

    2016年3月24日 09:34:32 星期四 ddos攻击: 一种: 随机生成ip, 去建立链接, 由于http/tcp握手协议原理, 发送应答报文时因为ip无效会导致等待重发, 这种行为可以通过电 ...

  2. Angular2 架构

      1. 说明 Angular 2 是一个用 HTML 和 JavaScript (或者可以编译成JavaScript)来构建应用程序的框架.该框架包含了一系列的库. 在 Angular 里,我们这样 ...

  3. HDU 5102 The K-th Distance(模拟)

    题意:输入一棵树,输出前k小的点对最短距离dis(i,j)的和. 模拟,官方题解说得很清楚了.不重复了. http://bestcoder.hdu.edu.cn/ 需要注意的是,复杂度要O(n+k), ...

  4. resin 安装配置

    resin (下载免费版 4) 前提:已经安装了Java运行环境,resin的安装需要jdk的支持   一.安装 1.cd /usr/local/src wget http://www.caucho. ...

  5. 【转】Java开发中JDBC连接数据库代码和步骤总结

    (转自:http://www.cnblogs.com/hongten/archive/2011/03/29/1998311.html) JDBC连接数据库 创建一个以JDBC连接数据库的程序,包含7个 ...

  6. Lamp搭建bugfree

    1.下载bugfree安装包 2.将bugfree安装包解压到/home/wwwroot/default目录下 unzip bugfree.zip  -d /home/wwwroot/default/ ...

  7. Jetty官方文档翻译

    最近在学习Jetty,没有找到合适的资料,所有只能看官方文档了,但是只有英文的,想着自己翻译着学也是学还不如把学习的过程放到网上,也可以给需要的人看,英文水平毕竟有限,也是用有道翻译着来的,不过也加了 ...

  8. 在ASP.NET MVC项目中使用React

    (此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:最近在开发钉钉的微应用,考虑到性能和UI库的支持,遂采用了React来开发前端. 目前 ...

  9. Objective-C 中self.与_访问方式的区别

    Objective-C中属性self.a与_a访问的区别: 在OC中我们可以通过指令@property定义属性. OC对属性封装了许多方法,同时也会自动实现一些方法,相比实例变量,感觉更加面向对象些. ...

  10. zorka源码解读之tracer内部实现

    核心类: ZorkaAsyncThread.java protected BlockingQueue<T> submitQueue; /** * Processes single item ...