http://lib.csdn.net/article/unity3d/38463

作者:IceFantasyLcj

  大家好,我是雨中祈雨。一直以来,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

  另外,如下代码也可以为指定的按钮添加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

  这两做法同样适用于为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

  还有一种方法就是使用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

  这样的话也可以监听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

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

    public void OnScroll(GameObject go,float value)
{
//执行事件
}
  • 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
/*请移除原先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

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

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

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

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

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

    http://blog.csdn.net/icefantasylcj/article/details/49450555 大家好,我是雨中祈雨.一直以来,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. iOS自学-监听按钮点击、提醒框

    //事件监听的问题 CGRect btn2Frame = CGRectMake(100.0, 150.0, 60.0, 44.0); //两种不同的方式创建 UIButton *btn2 = [UIB ...

随机推荐

  1. java20

    1:递归(理解) (1)方法定义中调用方法本身的现象 举例:老和尚给小和尚讲故事,我们学编程 (2)递归的注意事项: A:要有出口,否则就是死递归 B:次数不能过多,否则内存溢出 C:构造方法不能递归 ...

  2. jsp实验二

    1.编写一个简单的留言薄,写入留言提交后,显示留言内容 2.编写一个实现页面计数的计数器.思考,如果要求当刷新页面时,不增加计数. 3.编写一个简易购物车,实现向购物车添加商品.思考,如果增加清空购物 ...

  3. [Linux]使用PHP编写Gearman的Worker守护进程

    在我之前的文章中,介绍过Gearman的使用.在我的项目中,我使用了PHP来编写一直运行的Worker.如果按照Gearman官方推荐的例子,只是简单的一个循环来等待任务,会有一些问题,包括:1.当代 ...

  4. JavaScript高级程序设计学习笔记--错误处理与调试

    try-catch语句 只要代码中包含finally子句,则无论try或catch语句块中包含什么代码--甚至return语句,都不会阻止finally子句的执行,来看下面这个函数: function ...

  5. ul、li分列显示

    目的很简单:有一个 ul>li 列表,默认为单列显示,把它变为两列显示. 方法1,使用DIV+CSS代码: <style type="text/css"> .my ...

  6. 3D场景定位的一些资源

    利用多张影像对小物体进行拍摄,进而进行三维重建,是计算机视觉中的重要问题之一. 目前对此研究最全面的网站是:http://vision.middlebury.edu/mview/eval/ 目前最优秀 ...

  7. php 冒泡 快速 选择 插入算法 四种基本算法

    php四种基础算法:冒泡,选择,插入和快速排序法 来源:PHP100中文网 | 时间:2013-10-29 15:24:57 | 阅读数:120854 [导读] 许多人都说 算法是程序的核心,一个程序 ...

  8. psql-09表:视图和索引

    视图 由查询语句定义的虚拟表;从视图中看到的数据可能来自数据库中的一张或多张表,也可能来自外部; 使用视图的原因一般有: 使复制的查询易于理解和使用; 安全原因; 表一些函数返回的结果映射成视图; 一 ...

  9. amd和CMD

    AMD(Modules/Asynchronous-Definition).CMD(Common Module Definition)规范区别? Asynchronous Module Definiti ...

  10. D3.js部署node环境开发

    总结一段D3.js部署node环境的安装过程 准备阶段: 首先电脑上要安装node环境,这个阶段过滤掉,如果node环境都不会装,那就别玩基于node环境搞的其他东西了. 搭建环境: 我在自己的F:系 ...