首页 > Unity3D频道 > 【Unity3D研究院之游戏开发】 > Unity3D研究院之将UI的点击事件渗透下去(九十)
2016
09-05

Unity3D研究院之将UI的点击事件渗透下去(九十)

处理UI还有3D模型的点击推荐使用UGUI的这套事件系统,因为使用起来比较简洁,不需要自己用代码来发送射线,并且可以很好的处理同时点击UI和3D模型上。

1.给3D摄像机挂一个Physics Raycaster组件。Event Mask过滤掉UI.

2.用unity自带的Event Trigger 或者   http://www.xuanyusong.com/archives/3325 就可以对UI 或者 3D模型进行点击事件的监听了

3.OK 当UI与模型相互叠加的时候,优先响应UI,并且响应最前面的UI.

4.如下图所示,前面是UI后面是3D模型,被挡住的模型或者UI是不会被响应的。

Unity3D研究院之将UI的点击事件渗透下去(九十) - 雨松MOMO程序研究院 - 1

 

假如想把点击的事件透下去,让所有的UI或者模型都能正确的响应事件,怎么办呢?

代码: 把这段脚本挂在最前面的UI上。 然后当接收到点击事件后,调用PassEvent把当前的事件透下去。由于UGUI的事件有很多种,比如点击 、抬起、拖动、落下、第二个参数就是ExecuteEvents.Handler 把对应的Handler传进去就行了。

这样UI下面那些对应接收点击事件的地方都可以响应到了。。如下图所示,我点击在前面的UI后面的消息也能响应到了。

Unity3D研究院之将UI的点击事件渗透下去(九十) - 雨松MOMO程序研究院 - 2

最后编辑:
作者:雨松MOMO
专注移动互联网,Unity3D游戏开发
捐 赠写博客不易,如果您想请我喝一杯星巴克的话?就进来看吧!

Unity3D研究院之将UI的点击事件渗透下去(九十)》有 17 条评论

  1. sober 说:

    雨松大大为什么,下面的按钮注册的方法会响应两次啊

  2. Mr.秦 说:

    大神我是U5.6.2版本的也会栈溢出,我把按下和抬起注释了,虽然不报溢出了,但是unity直接卡死了。。。

  3. 席郭亮 说:

    请教一下,能不能让外部导入的模型,也能有这个监听点击的能力呀,测试了出了ugui的物体,其他的都不能被点击到

  4. Godhandsxx 说:

    unity5.5.2f1版本,把脚本挂在UI上,一点Unity就挂了,报错“堆栈溢出”

    • 十三 说:

      如果两个都挂了这个脚本的,在重叠区域好像会出现堆栈很深的问题,在RaycastAll之前加个标志位,表示这个事件已经透传过,如果传回到自己,就忽略掉,然后在透传结束,将标志位设置回来
      if(hasPassedEvent)
      {
      return;
      }
      hasPassedEvent = true;

      List results = new List();
      EventSystem.current.RaycastAll(data, results);
      GameObject current = gameObject;
      for (int i = 0; i < results.Count; i++)
      {
      if (current != results[i].gameObject)
      {
      if(ExecuteEvents.Execute(results[i].gameObject, data, function))
      {
      break;
      }
      //RaycastAll后ugui会自己排序,如果你只想响应透下去的最近的一个响应,这里ExecuteEvents.Execute后直接break就行。
      }
      }
      results.Clear();

      hasPassedEvent = false;

  5. 雨松MOMO 说:

    不是吧, 我测试了一下没有啊, 你说的是PC上的hightlight状态吧?

  6. 村长 说:

    我有一个小疑问,希望雨松大神解惑:在MonoBehaviour 里,有一组OnMouseEnter, OnMouseDown, OnMouseUp 方法,将写有这些方法的脚本挂在3d空间里的Mesh上,也可以检测到S是否被鼠标点击或移入的事件。如果如大神所说,建议3d的game object 也使用 UGUI的这套事件系统来做事件监听, 那么这套系统相比之前我提到的Monobehaviour里的内置方法,有什么优势?望大神指点。

  7. 陈昌权 说:

    这个会造成内存泄漏,能帮看看吗?头疼死了。IEnumerator GoDownLoadStart(){//Resources.UnloadUnusedAssets();Debug.Log (“开始下载器2” url);WWW www = new WWW (url);while (!www.isDone) {Debug.Log (string.Format(“下载中:{0}”,www.progress));yield return null;}if (www.error != null) {Debug.Log (“下载错误:” http://www.error);}else {File.WriteAllBytes(path,www.bytes);Debug.Log (“下载完成,大小:” http://www.bytesDownloaded “字节”);}Debug.Log (“清除镜像”);www.assetBundle.Unload (false);Debug.Log (“清除垃圾”);www.Dispose ();Debug.Log (“清除未引用”);www = null;Debug.Log (“www=null”);Resources.UnloadUnusedAssets();Debug.Log (“清除GC”);GC.Collect ();Destroy (this.gameObject);}

  8. 陈昌权 说:

    这个会造成内存泄漏,能帮看看吗?头疼死了。IEnumerator GoDownLoadStart() { //Resources.UnloadUnusedAssets(); Debug.Log (“开始下载器2″+url); WWW www = new WWW (url); while (!www.isDone) { Debug.Log (string.Format(“下载中:{0}”,www.progress)); yield return null; } if (www.error != null) { Debug.Log (“下载错误:”+www.error); } else { File.WriteAllBytes(path,www.bytes); Debug.Log (“下载完成,大小:” + http://www.bytesDownloaded+ “字节”); } Debug.Log (“清除镜像”); http://www.assetBundle.Unload (false); Debug.Log (“清除垃圾”); http://www.Dispose (); Debug.Log (“清除未引用”); www = null; Debug.Log (“www=null”); Resources.UnloadUnusedAssets(); Debug.Log (“清除GC”); GC.Collect (); Destroy (this.gameObject); }

  9. cokefenta 说:

    雨凇大大,我用ugui构建完ui系统后,当用鼠标点击其中一个button后,在按下键盘的方向键,就会对ui中的button进行选择,如何解决这个bug啊?

留下一个回复

你的email不会被公开。