unity ngui 教程通过什么检测事件

NGUI 怎么判断我当前点击的是那个按钮【unity3d吧】_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:76,898贴子:
NGUI 怎么判断我当前点击的是那个按钮收藏
图片来自:如图, Button 的Label 是一样的, 我怎么判断点击的是哪个?
江苏盘锦天燃气模温机,一台省得让你怀疑人生的燃气锅炉
你点中的是有碰撞器的那个
求解怎么实现
此问题已解决,谢谢大家啦
UICamera.currentTouch.current
登录百度帐号推荐应用unity3d之游戏背包系统制作(NGUI事件监听器UIEventListener)
本次背包系统的demo也是我面试某大公司的机试题,现在把他拿出来好好用NGUI做了一下 感觉提高了不少 。注意哦
用的事件监听器UIEventListener,其实就是一个委托吧,真的超级方便超级好用的额!谁用谁知道!!用这个方法还能实现程美分开,程序美工同时开工
谁都不挨着谁 然后最后整合 PS:我师傅研究出来的 简直了!牛呆了! &
&新技能get起来~~
我就是实现了一个拖拽放下的功能,鼠标点中左边的图标拖入到右边的物品栏中,鼠标放在图表上能够提示技能图标文字解释,双击技能图标
提示已get 新技能。
本次测试一共写了三个脚本:
packagecontrol是用来写拖拽等等的,tooltips是写的关于技能介绍小窗的弹出的,used close
control是控制使用关闭的。
好啦,上代码了~~
packageControl:
using&UnityEngine;
using&System.Collections;
public&class&PackageControl&:&MonoBehaviour&{
&&&&public&GameObject&Used;//公开声明一个“已经使用”的物体
&&&&void&Start&()&{
&&&&&&&&UIEventListener&listener&=&UIEventListener.Get&(gameObject);//事件监听器
&&&&&&&&listener.onHover&+=&Hover;//鼠标移上图标的方法
&&&&&&&&listener.onDrag&+=&Drag;//鼠标拖拽的方法
&&&&&&&&listener.onPress&+=&Press;//鼠标按下的方法
&&&&&&&&listener.onDoubleClick&+=&Doubleclick;//双击图标的方法
//鼠标移上图标,鼠标在图标上则图标大小为(1,&1,&1),移开则为(0.76f,&0.76f,&0.76f)
&&&&private&void&Hover(GameObject&obj,bool&isOver)
&&&&&&&&if&(isOver)&{
&&&&&&&&&&&&this.transform.localScale&=&new&Vector3&(1,&1,&1);&&&&
&&&&&&&&}&else&{
&&&&&&&&&&&&this.transform.localScale&=&new&Vector3&(0.76f,&0.76f,&0.76f);&&&&
//鼠标拖动图标,delta为图标的位移量,拖动后的图标位置为:
图标初始位置+位移量
&&&&private&void&Drag(GameObject&obj,Vector2&delta)
&&&&&&&&this.transform.localPosition&=&
&&&&&&&&&&&&new&Vector3(transform.localPosition.x&+&delta.x,&
&&&&&&&&&&&&&&&&&&&&&&&&transform.localPosition.y&+&delta.y,&
&&&&&&&&&&&&&&&&&&&&&&&&transform.localPosition.z);
//鼠标按下抬起,鼠标抬起时图标大小变为初始大小
&&&&private&void&Press(GameObject&obj,bool&isDown)
&&&&&&&&if&(isDown)&{
&&&&&&&&}&else&{
&&&&&&&&&&&&this.transform.localScale&=&new&Vector3&(0.76f,&0.76f,&0.76f);
//双击图标,表示已经使用该技能的窗口显示出来
&&&&private&void&Doubleclick(GameObject&obj)
&&&&&&&&Used.SetActive&(true);
&&&&void&Update&()&{
TooltipsControl
using&UnityEngine;
using&System.Collections;
public&class&TooltipsControl&:&MonoBehaviour&{
//公开定义图标的技能介绍窗口
&&&&public&GameObject&tips1;
&&&&public&GameObject&tips4;
&&&&public&GameObject&tips7;
//公开定义需要监听的对象
&&&&public&GameObject&Items1;
&&&&public&GameObject&Items4;
&&&&public&GameObject&Items7;
&&&&void&Start&()&{
&&&&&&&&UIEventListener&listener&=&UIEventListener.Get&(Items1);
&&&&&&&&listener.onHover&+=&Hover1;//鼠标移上去的方法
&&&&&&&&listener&=&UIEventListener.Get&(Items4);
&&&&&&&&listener.onHover&+=&Hover4;//鼠标移上去的方法
&&&&&&&&listener&=&UIEventListener.Get&(Items7);
&&&&&&&&listener.onHover&+=&Hover7;//鼠标移上去的方法
&&&&private&void&Hover1(GameObject&obj,bool&isOver)
&&&&&&&&if&(isOver)&{
&&&&&&&&&&&&StartCoroutine(Show1());//鼠标移上图标,调用协同方法
&&&&&&&&}&else&{
&&&&private&void&Hover4(GameObject&obj,bool&isOver)
&&&&&&&&if&(isOver)&{
&&&&&&&&&&&&StartCoroutine(Show4());
&&&&&&&&}&else&{
&&&&&&&&&&&&
&&&&private&void&Hover7(GameObject&obj,bool&isOver)
&&&&&&&&if&(isOver)&{
&&&&&&&&&&&&StartCoroutine(Show7());
&&&&&&&&}&else&{
&&&&&&&&&&&&
&&&&void&Update&()&{
//协程方法控制技能介绍的窗口显示和隐藏
&&&&IEnumerator&Show1()
&&&&&&&&yield&return&new&WaitForSeconds&(1.0f);//鼠标移上图标等待1秒显示介绍窗口
&&&&&&&&tips1.SetActive&(true);
&&&&&&&&tips4.SetActive&(false);
&&&&&&&&tips7.SetActive&(false);
&&&&&&&&yield&return&new&WaitForSeconds&(1.5f);//介绍窗口显示1.5秒后隐藏
&&&&&&&&tips1.SetActive&(false);
&&&&&&&&tips4.SetActive&(false);
&&&&&&&&tips7.SetActive&(false);
&&&&IEnumerator&Show4()
&&&&&&&&yield&return&new&WaitForSeconds&(1.0f);
&&&&&&&&tips4.SetActive&(true);
&&&&&&&&tips1.SetActive&(false);
&&&&&&&&tips7.SetActive&(false);
&&&&&&&&yield&return&new&WaitForSeconds&(1.5f);
&&&&&&&&tips4.SetActive&(false);
&&&&&&&&tips1.SetActive&(false);
&&&&&&&&tips7.SetActive&(false);
&&&&IEnumerator&Show7()
&&&&&&&&yield&return&new&WaitForSeconds&(1.0f);
&&&&&&&&tips7.SetActive&(true);
&&&&&&&&tips4.SetActive&(false);
&&&&&&&&tips1.SetActive&(false);
&&&&&&&&yield&return&new&WaitForSeconds&(1.5f);
&&&&&&&&tips7.SetActive&(false);
&&&&&&&&tips4.SetActive&(false);
&&&&&&&&tips1.SetActive&(false);
UsedcloseControl
using&UnityEngine;
using&System.Collections;
public&class&UsedcloseControl&:&MonoBehaviour&{
&&&&public&GameObject&close;
&&&&void&Start&()&{
&&&&&&&&UIEventListener&listener&=&UIEventListener.Get&(gameObject);
&&&&&&&&listener.onClick&+=&Click;//单击按钮方法
&&&&private&void&Click(GameObject&obj)
&&&&&&&&close.SetActive&(false);//关闭提示已使用的窗口
&&&&void&Update&()&{
😄 新技能有木有get起来~~
&&UIEventListener真的很简单很方便噢~~
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。NGUI 按钮穿透到场景的问题,求助!!
比如在场景中有个Cube和一个NGUI按钮button,当鼠标OnMouseEnter后设置会变色,让button按钮正好在Cube之上的时候点击按钮,应该Cube不会变色,因为被挡住的原因嘛,可是3.6.8以上的NGUI却挡不住,又出发了NGUI按钮,又出发了场景中的Cube变色,可是老版本的NGUI却没这个问题!这是为什么呢???怎么才能让新的NGUI 挡住后面场景中的触发? &(单个Cube可以控制boxcollider的激活状态,可是要是大批量的就麻烦了)726 || this.offsetHeight>700){if(this.offsetWidth/726 > this.offsetHeight/700){this.width=726;}else{this.height=700;}}" style="max-width:726max-height:700" title="点击查看原图" onclick="if(this.parentNode.tagName!='A') window.open('/forum/attachment/1411/thread/2_2e.png');" />726 || this.offsetHeight>700){if(this.offsetWidth/726 > this.offsetHeight/700){this.width=726;}else{this.height=700;}}" style="max-width:726max-height:700" title="点击查看原图" onclick="if(this.parentNode.tagName!='A') window.open('/forum/attachment/1411/thread/2_4d.png');" />
要评论请先&或者&
如图,自己去尝试吧。
:如图,自己去尝试吧。 感谢回复~~我一个一个式了,不知道还是我操作的不对还是什么不对,要么连按钮都点不到,要么还是点按钮的时候穿透到后面把后面方块变色了~
你不能从代码上做文章吗?当点击到cube时,如同时触发了按钮事件,则cube不触发,说明同时点到了2个。但是按钮的优先级更大。
:你不能从代码上做文章吗?当点击到cube时,如同时触发了按钮事件,则cube不触发,说明同时点到了2个。但是按钮的优先级更大。 当有很多类型的cube的时候就不好这样控制了,因为你每个都要判断是否点击的是自己。和同事研究了很久找到一个办法,就是不用OnMouseEnter这样的一些触发事件,而用NGUI的OnPress这样的事件来控制点击,然后在主相机上添加一个UICamera这个NGUI的脚本,把Event Type调整到3DWorld,就可以了!
楼主你解决了吗??如果没有的话,我告诉你,你在Hierarchy中找到你的UIRoot,双击,你看下那个立方体区域(2DUI) 锥体(3DUI)和你的主摄像机的视锥有没有重叠的地方,如果有,把UIROOT拖走,拖到多远都可以。
:楼主你解决了吗??如果没有的话,我告诉你,你在Hierarchy中找到你的UIRoot,双击,你看下那个立方体区域(2DUI) 锥体(3DUI)和你的主摄像机的视锥有没有重叠的地方,如果有,把UIROOT拖走,拖到多远都可以。 解决了~·谢谢
:解决了~·谢谢 楼主怎么解决的?求指教
:楼主怎么解决的?求指教 就是不用 unity的的事件OnMouseEnter之类的,而用NGUI的事件OnPress之类的,再添加一个脚本在主相机UICamera,把这个脚本中的Event Type 选择为3DWorld
如果是UGUI该怎么办?NGUI的事件通知架构和源码剖析
NGUI的事件通知其实是由一个脚本UICamera来实现的,脚本的命名不是太好,其基本的原理很简单,在Update函数中检测用户输入,然后根据自己的策略分发到具体的物体。其定义了一些基本的通知回调函数,你可以查看具体的注释:
/// * OnHover (isOver) is sent when the mouse hovers over a collider or moves away.
/// * OnPress (isDown) is sent when a mouse button gets pressed on the collider.
/// * OnSelect (selected) is sent when a mouse button is first pressed on an object. Repeated presses won't result in an OnSelect(true).
/// * OnClick () is sent when a mouse is pressed and released on the same object.
UICamera.currentTouchID tells you which button was clicked.
/// * OnDoubleClick () is sent when the click happens twice within a fourth of a second.
UICamera.currentTouchID tells you which button was clicked.
/// * OnDragStart () is sent to a game object under the touch just before the OnDrag() notifications begin.
/// * OnDrag (delta) is sent to an object that's being dragged.
/// * OnDragOver (draggedObject) is sent to a game object when another object is dragged over its area.
/// * OnDragOut (draggedObject) is sent to a game object when another object is dragged out of its area.
/// * OnDragEnd () is sent to a dragged object when the drag event finishes.
/// * OnTooltip (show) is sent when the mouse hovers over a collider for some time without moving.
/// * OnScroll (float delta) is sent out when the mouse scroll wheel is moved.
/// * OnKey (KeyCode key) is sent when keyboard or controller input is used.
所以从字面上你就可以理解, 其提供了哪些事件通知,这些事件都是在在主线程中完成的。需要特别说明的是,NGUI有自己的事件通知,和MonoBehavior里面的函数OnMouseDown, OnMouseUp, OnMouseOver等消息处理函数重叠,所以只要我们使用了NGUI的处理框架以及NGUI的脚本,如UIButton,UISCrollView等,我们无需重载MonoBehavior的上述事件处理函数。 如果自己处理了,可能同一个用户输入会响应两次。
下面就简单介绍一下关键的函数或者结构体
通知函数, Notify
Generic notification function. Used in place of SendMessage to shorten the code and allow for more than one receiver.
static public void Notify (GameObject go, string funcName, object obj)
if (mNotifying) return;
mNotifying = true;
if (NGUITools.GetActive(go))
go.SendMessage(funcName, obj, SendMessageOptions.DontRequireReceiver);
if (mGenericHandler != null && mGenericHandler != go)
mGenericHandler.SendMessage(funcName, obj, SendMessageOptions.DontRequireReceiver);
mNotifying = false;
所以,消息通知是通过GameObject::SendMessage ()的方法来实现的,可以查看源码,等到funcName的名字都是上面的事件通知的名字,如: OnClick, OnHover, OnSelect等。
帮助函数,如何从一个屏幕上的位置信息,找到点击,触摸,滑过的物体
Returns the object under the specified position.
static public bool Raycast (Vector3 inPos)
for (int i = 0; i & list. ++i)
UICamera cam = list.buffer[i];
if (!cam.enabled || !NGUITools.GetActive(cam.gameObject)) continue;
currentCamera = cam.cachedC
Vector3 pos = currentCamera.ScreenToViewportPoint(inPos);
if (float.IsNaN(pos.x) || float.IsNaN(pos.y)) continue;
if (pos.x & 0f || pos.x & 1f || pos.y & 0f || pos.y & 1f) continue;
Ray ray = currentCamera.ScreenPointToRay(inPos);
int mask = currentCamera.cullingMask & (int)cam.eventReceiverM
float dist = (cam.rangeDistance & 0f) ? cam.rangeDistance : currentCamera.farClipPlane - currentCamera.nearClipP
if (cam.eventType == EventType.World_3D)
............
else if (cam.eventType == EventType.UI_3D)
RaycastHit[] hits = Physics.RaycastAll(ray, dist, mask);
if (hits.Length & 1)
for (int b = 0; b & hits.L ++b)
GameObject go = hits[b].collider.gameO
UIWidget w = go.GetComponent&UIWidget&();
if (w != null)
if (!w.isVisible) continue;
if (w.hitCheck != null && !w.hitCheck(hits[b].point)) continue;
UIRect rect = NGUITools.FindInParents&UIRect&(go);
if (rect != null && rect.finalAlpha & 0.001f) continue;
mHit.depth = NGUITools.CalculateRaycastDepth(go);
if (mHit.depth != int.MaxValue)
mHit.hit = hits[b];
mHit.point = hits[b].
mHit.go = hits[b].collider.gameO
mHits.Add(mHit);
mHits.Sort(delegate(DepthEntry r1, DepthEntry r2) { return pareTo(r1.depth); });
for (int b = 0; b & mHits. ++b)
#if UNITY_FLASH
if (IsVisible(mHits.buffer[b]))
if (IsVisible(ref mHits.buffer[b]))
lastHit = mHits[b].
hoveredObject = mHits[b].
lastWorldPosition = mHits[b].
mHits.Clear();
return true;
mHits.Clear();
else if (hits.Length == 1)
............
else if (cam.eventType == EventType.World_2D)
..............
else if (cam.eventType == EventType.UI_2D)
..............
return false;
ControlScheme
记录当前的输入的类型
public enum ControlScheme
Controller,
MouseOrTouch
下面是记录鼠标事件和触摸事件的结构体,个人认为实现的不大合理,把鼠标和触摸需要的信息混合在一起了, NGUI在实现中也把touch,mouse事件合并进行了处理。
Ambiguous mouse, touch, or controller event.
public class MouseOrTouch
public Vector2
public Vector2 lastP
public Vector2
public Vector2 totalD
public Camera pressedC
public GameO
public GameO
public GameO
public GameO
public float pressTime = 0f;
public float clickTime = 0f;
public ClickNotification clickNotification = ClickNotification.A
public bool touchBegan = true;
public bool pressStarted = false;
public bool dragStarted = false;
Delta time since the touch operation started.
public float deltaTime { get { return touchBegan ? RealTime.time - pressTime : 0f; } }
Returns whether this touch is currently over a UI element.
public bool isOverUI
return current != null && current != fallThrough && NGUITools.FindInParents&UIRoot&(current) != null;
处理输入的事件
void ProcessPress (bool pressed, float click, float drag)
if (pressed)
if (mTooltip != null) ShowTooltip(false);
currentTouch.pressStarted = true;
if (onPress != null && currentTouch.pressed)
onPress(currentTouch.pressed, false);
Notify(currentTouch.pressed, "OnPress", false);
currentTouch.pressed = currentTouch.
currentTouch.dragged = currentTouch.
currentTouch.clickNotification = ClickNotification.BasedOnD
currentTouch.totalDelta = Vector2.
currentTouch.dragStarted = false;
if (onPress != null && currentTouch.pressed)
onPress(currentTouch.pressed, true);
Notify(currentTouch.pressed, "OnPress", true);
if (currentTouch.pressed != mCurrentSelection)
if (mTooltip != null) ShowTooltip(false);
currentScheme = ControlScheme.T
selectedObject = currentTouch.
else if (currentTouch.pressed != null && (currentTouch.delta.sqrMagnitude != 0f || currentTouch.current != currentTouch.last))
currentTouch.totalDelta += currentTouch.
float mag = currentTouch.totalDelta.sqrM
bool justStarted = false;
if (!currentTouch.dragStarted && currentTouch.last != currentTouch.current)
currentTouch.dragStarted = true;
currentTouch.delta = currentTouch.totalD
isDragging = true;
if (onDragStart != null) onDragStart(currentTouch.dragged);
Notify(currentTouch.dragged, "OnDragStart", null);
if (onDragOver != null) onDragOver(currentTouch.last, currentTouch.dragged);
Notify(currentTouch.last, "OnDragOver", currentTouch.dragged);
isDragging = false;
else if (!currentTouch.dragStarted && drag & mag)
justStarted = true;
currentTouch.dragStarted = true;
currentTouch.delta = currentTouch.totalD
if (currentTouch.dragStarted)
if (mTooltip != null) ShowTooltip(false);
isDragging = true;
bool isDisabled = (currentTouch.clickNotification == ClickNotification.None);
if (justStarted)
if (onDragStart != null) onDragStart(currentTouch.dragged);
Notify(currentTouch.dragged, "OnDragStart", null);
if (onDragOver != null) onDragOver(currentTouch.last, currentTouch.dragged);
Notify(currentTouch.current, "OnDragOver", currentTouch.dragged);
else if (currentTouch.last != currentTouch.current)
if (onDragStart != null) onDragStart(currentTouch.dragged);
Notify(currentTouch.last, "OnDragOut", currentTouch.dragged);
if (onDragOver != null) onDragOver(currentTouch.last, currentTouch.dragged);
Notify(currentTouch.current, "OnDragOver", currentTouch.dragged);
if (onDrag != null) onDrag(currentTouch.dragged, currentTouch.delta);
Notify(currentTouch.dragged, "OnDrag", currentTouch.delta);
currentTouch.last = currentTouch.
isDragging = false;
if (isDisabled)
currentTouch.clickNotification = ClickNotification.N
else if (currentTouch.clickNotification == ClickNotification.BasedOnDelta && click & mag)
currentTouch.clickNotification = ClickNotification.N
/// &summary&
/// 处理Touch,和Mouse release事件。
/// &/summary&
void ProcessRelease (bool isMouse, float drag)
// Send out the unpress message
currentTouch.pressStarted =
if (mTooltip != null) ShowTooltip(false);
if (currentTouch.pressed != null)
// If there was a drag event in progress, make sure OnDragOut gets sent
if (currentTouch.dragStarted)
if (onDragOut != null) onDragOut(currentTouch.last, currentTouch.dragged);
Notify(currentTouch.last, "OnDragOut", currentTouch.dragged);
if (onDragEnd != null) onDragEnd(currentTouch.dragged);
Notify(currentTouch.dragged, "OnDragEnd", null);
// Send the notification of a touch ending
if (onPress != null) onPress(currentTouch.pressed, false);
Notify(currentTouch.pressed, "OnPress", false);
// Send a hover message to the object
if (isMouse)
if (onHover != null) onHover(currentTouch.current, true);
Notify(currentTouch.current, "OnHover", true);
mHover = currentTouch.
// If the button/touch was released on the same object, consider it a click and select it
if (currentTouch.dragged == currentTouch.current ||
(currentScheme != ControlScheme.Controller &&
currentTouch.clickNotification != ClickNotification.None &&
currentTouch.totalDelta.sqrMagnitude & drag))
if (currentTouch.pressed != mCurrentSelection)
mNextSelection =
mCurrentSelection = currentTouch.
if (onSelect != null) onSelect(currentTouch.pressed, true);
Notify(currentTouch.pressed, "OnSelect", true);
mNextSelection =
mCurrentSelection = currentTouch.
// If the touch should consider clicks, send out an OnClick notification
if (currentTouch.clickNotification != ClickNotification.None && currentTouch.pressed == currentTouch.current)
float time = RealTime.
if (onClick != null) onClick(currentTouch.pressed);
Notify(currentTouch.pressed, "OnClick", null);
if (currentTouch.clickTime + 0.35f & time)
if (onDoubleClick != null) onDoubleClick(currentTouch.pressed);
Notify(currentTouch.pressed, "OnDoubleClick", null);
currentTouch.clickTime =
else if (currentTouch.dragStarted) // The button/touch was released on a different object
// Send a drop notification (for drag & drop)
if (onDrop != null) onDrop(currentTouch.current, currentTouch.dragged);
Notify(currentTouch.current, "OnDrop", currentTouch.dragged);
currentTouch.dragStarted =
currentTouch.pressed =
currentTouch.dragged =
Update 函数,其处理UI 事件,并且发送给具体的物体和回调函数。
void Update ()
#if UNITY_EDITOR
if (!Application.isPlaying || !handlesEvents) return;
if (!handlesEvents) return;
if (useTouch) ProcessTouches ();
else if (useMouse) ProcessMouse();
..................
总结: 所有整个NGUI的事件处理通知都是由UICamera的update函数,分析当前帧的用户输入,然后发送时间给NGUI的UI控件,如UIButton,UIScrollView等。
看过本文的人也看了:
我要留言技术领域:
取消收藏确定要取消收藏吗?
删除图谱提示你保存在该图谱下的知识内容也会被删除,建议你先将内容移到其他图谱中。你确定要删除知识图谱及其内容吗?
删除节点提示无法删除该知识节点,因该节点下仍保存有相关知识内容!
删除节点提示你确定要删除该知识节点吗?NGUI的OnClick()能获取是按下的鼠标左键还是右键吗?
OnClick()中加Input.GetMouseButtonDown()判断不行,又不想写在Update里面。
求教NGUI中的点击能不能获取到鼠标按的哪个~~~
要评论请先&或者&
一看这ID 就知道是二娃这个坑货!!
这个只能自己写代码判断
currentTouch里有个id
左键右键都检测的
:左键右键都检测的 求指导,用什么检测啊
Input.GetMouseButtonDown(自己定参数)
这个是NGUI自带的事件实现的 &你可以去看下源码 反正左键右键有能触发OnClick
两个都相应吧~
&&void OnPress()
&& &{
&& & & &print(&asdasd&);
&& & & &if (Input.GetMouseButtonDown(1))
&& & & &if (Input.GetMouseButtonDown(0))
&& & & &{
&& & & & & &NGUITools.SetActive(Ngui, false);
&& & & & & &
&& & & &}
&& &}
我是这么搞的。还有更好的方法么?

我要回帖

更多关于 unity ngui 的文章

 

随机推荐