【转】 NGUI 监听按钮除OnClick外其他事件的方法,附简易改编的UIButton类
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类的更多相关文章
- 【转】监听按钮除OnClick外其他事件的方法,附简易改编的UIButton类
http://lib.csdn.net/article/unity3d/38463 作者:IceFantasyLcj 大家好,我是雨中祈雨.一直以来,CSDN都是我最好的编程助手.这是我在CSDN的第 ...
- ButtonAddListener监听按钮点击事件
ButtonAddListener监听按钮点击事件 using UnityEngine; using System.Collections; using UnityEngine.UI; using U ...
- xcode UIButton创建、监听按钮点击、自定义按钮 、状态 、内边距
代码创建 //创建UIButton UIButton * btnType=[[UIButton alloc]init]; //设置UIControlStateNormal状态下的文字颜色 [btnTy ...
- swift项目第七天:构建访客界面以及监听按钮点击
一:访客界面效果如图 二:xib封装访客视图的view 1:业务逻辑分析:1:由于用户未登录时要显示访客视图,要先进行判断用户是否登录,未登录则显示访客视图,登录则显示正常的登陆界面,由于要在四个子控 ...
- ipv4、ipv6的socket同时监听“bind: Address already in use”的解决方法
创建ipv4和ipv6的socket,同时监听某个端口的ipv4和ipv6报文,运行时bind函数执行失败,提示“bind: Address already in use”.原因:ipv6的socke ...
- jQuery-使用hover(fn,fn)函数监听mouseover和mouseout两个事件
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- VueApp监听手机物理返回键的事件
代码 第一步创建js文件夹子 在main里面引用 JS文本内容如下 //监听手机物理返回键的事件 document.addEventListener('plusready', function() ...
- Android 监听按钮的点击事件
onClick事件1.Button和ImageButton都拥有一个onClick事件 通过自身的.setOnClickListener(OnClickListener)方法添加点击事件2.所有的控件 ...
- NGUI监听事件
using UnityEngine; using System.Collections; public class UIDataHandler : MonoBehaviour { public UII ...
随机推荐
- ajax提交form表单资料详细汇总
一.ajax提交form表单和不同的form表单的提交主要区别在于,ajax提交表单是异步提交的,而普通的是同步提交的表单.通过在后台与服务器进行少量数据交换,ajax 可以使网页实现异步更新.这意味 ...
- Android笔记:异步消息处理
1. Message Message 是在线程之间传递的消息,它可以在内部携带少量的信息,用于在不同线程之间交换数据.上一小节中我们使用到了Message 的what 字段,除此之外还可以使用arg1 ...
- (转)Java中使用Jedis操作Redis
转自http://www.cnblogs.com/liuling/p/2014-4-19-04.html 使用Java操作Redis需要jedis-2.1.0.jar,下载地址:http://file ...
- Linux系统virtualbox + ubuntu + xshell 问题与注意事项
序言:ubuntu闭源软件太多,一般不推荐使用:没钱可以使用centos.debian:有钱使用redhat 目前主流和常用的Linux版本主要有:1.Redhat 版本5.5和6.0最新:培训.学习 ...
- Python爬虫Scrapy框架入门(0)
想学习爬虫,又想了解python语言,有个python高手推荐我看看scrapy. scrapy是一个python爬虫框架,据说很灵活,网上介绍该框架的信息很多,此处不再赘述.专心记录我自己遇到的问题 ...
- Extjs DOM操作的几个类
Extjs提供了非常完善的DOM操作方法,可以方便的操作DOM.另外Extjs还可以方便的查询DOM元素,并把这些DOM元素封装成Ext.Element对象,通过Element对象我们可以操作DOM元 ...
- nuget packages batch install
d:\nuget\nuget.exe install EnterpriseLibrary.Common -NoCache -Verbosity detailed -OutputDirectory D: ...
- DevExpress的GridControl的实时加载数据解决方案(取代分页)
http://blog.csdn.net/educast/article/details/4769457 evExpress是一套第三方控件 其中有类似DataGridView的控件 今天把针对Dev ...
- http返回码301、302、307、305含义和区别
301永久重定向,302暂时移动,seo对301和302的处理不一样: 301和302会出现数据丢失问题,重定向后请求数据丢失: 307临时重定向,数据不会丢失:
- 【听说是线段树】bzoj1012 [JSOI2008]最大数maxnumber
一眼看题目吓了一跳:这TM不就是单调队列吗,200000又怎样,大不了我二分嘛 系统提示:成功开启 手残模式 开始瞎写: #include <cstdio> ]; ]; int m,mod ...