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. MySQL MHA 搭建&测试

    一:背景介绍 MHA(Master HA)是一款开源的MySQL的高可用工具,能在MySQL主从复制的基础上,实现自动化主服务器故障转移.虽然MHA试图从宕机的主服务器上保存二进制日志,但并不是总是可 ...

  2. wow经典台词

    永恒岛,磐皂在玄牛上场时喊:你能否独立山巅,任由风霜侵袭,直至沧海变为桑田,高山沉入海底?风刀霜剑,四面受敌.不动如山,亘古不移. 巫妖王:当一切结束,你会跪求我的宽恕...而我,会拒绝你! 伊利丹: ...

  3. yii中的cookie的发送和读取

    cookies: //新创建的cookie会从本地传到服务器上,然后从服务器获取. (1) cookie的发送 $cookies = Yii::$app->response->cookie ...

  4. 如何在WIN2008或WIN2012 64位系统安装32位SQL2000

    如何在WIN2008或WIN2012 64位系统安装32位SQL2000 在日常服务器,云服务器或VPS中,因尔特网络工程师遇到部分使用了WIN2008 或WN2012 64位系统的用户需要安装SQL ...

  5. spark伪分布式安装

    一,在官网下载对应的版本http://spark.apache.org/downloads.html 二在linux中解压下来的spark包   三:配置环境变量     (1)在/etc/profi ...

  6. PHP实现四种基本排序算法

    前提:分别用冒泡排序法,快速排序法,选择排序法,插入排序法将下面数组中的值按照从小到大的顺序进行排序. $arr(1,43,54,62,21,66,32,78,36,76,39); 1. 冒泡排序 思 ...

  7. JS将指定的时间戳转为UTC时间

    Js中获取时间戳可用var dayMiliseconds = parseInt(new Date().valueOf());Js的时间戳单位为毫秒(1s = 1000 ms),下面是一个将制定的格式转 ...

  8. GnuStep使用

    gcc -o main main1.m -I/GNUstep/System/Library/Headers -fconstant-string-class=NSConstantString -L/GN ...

  9. Codeforces Round #363 (Div. 2)

    A题 http://codeforces.com/problemset/problem/699/A 非常的水,两个相向而行,且间距最小的点,搜一遍就是答案了. #include <cstdio& ...

  10. 我的c++学习(11)数组和指针

    使用数组显示斐波那契数列 #include "stdafx.h" using namespace std; #include<iostream> int _tmain( ...