一、先看下效果

Prefab结构

二、实现思路:

1、prefab上的Panel层级设置成较高

2、背景由5个UISprite拼接起来的,4个(L,R,U,D)当作遮罩,1个镂空(Hollow)当作点击触发(全部都有BoxCollider,并且都生效,有人会问这不就把后面的按钮也给拦截住了,后面会说为什么要这样)

3、4个遮罩的大小由Holow大小决定

4、Hollow绑定一个点击事件ClickCenter  (后面代码里有)

三、关键部分:

这里解释为什么上面要把Hollow也带上BoxCollider,目的是修正点击位置,只要是点Hollow上,就让NGUI只相应点击在Hollow中心点后面的第一个UIWidget,这样就可以避免因为点不准,拖拽的其他问题

如图,只要我点在篮筐里,就只响应红点下面的第一个控件

四、代码

其实就是NGUI的点击响应代码,位置传入的是Hollow的位置

  1. using System;
  2. using UnityEngine;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5.  
  6. public class NewbieGuide : MonoBehaviour
  7. {
  8.  
  9. public Transform Hollow;
  10.  
  11. bool IsVisible(Vector3 worldPoint, GameObject go)
  12. {
  13. UIPanel panel = NGUITools.FindInParents<UIPanel>(go);
  14.  
  15. while (panel != null)
  16. {
  17. if (!panel.IsVisible(worldPoint)) return false;
  18. panel = panel.parentPanel;
  19. }
  20. return true;
  21. }
  22.  
  23. struct DepthEntry
  24. {
  25. public int depth;
  26. public RaycastHit hit;
  27. public Vector3 point;
  28. public GameObject go;
  29. }
  30.  
  31. #if UNITY_FLASH
  32. static bool IsVisible (DepthEntry de)
  33. #else
  34. static bool IsVisible(ref DepthEntry de)
  35. #endif
  36. {
  37. UIPanel panel = NGUITools.FindInParents<UIPanel>(de.go);
  38.  
  39. while (panel != null)
  40. {
  41. if (!panel.IsVisible(de.point)) return false;
  42. panel = panel.parentPanel;
  43. }
  44. return true;
  45. }
  46.  
  47. void Notify(GameObject go, string funcName, object obj)
  48. {
  49. if (NGUITools.GetActive(go))
  50. {
  51. go.SendMessage(funcName, obj, SendMessageOptions.DontRequireReceiver);
  52. }
  53. }
  54.  
  55. public void ClickCenter()
  56. {
  57. DepthEntry mHit = new DepthEntry();
  58. BetterList<DepthEntry> mHits = new BetterList<DepthEntry>();
  59.  
  60. UICamera cam = UICamera.current;
  61.  
  62. UIEventTrigger.current = null;
  63.  
  64. // Convert to view space
  65. var currentCamera = cam.cachedCamera;
  66.  
  67. // Cast a ray into the screen
  68. var p = Hollow.transform.position;
  69. p.z = currentCamera.nearClipPlane;
  70. Ray ray = new Ray(p, Vector3.forward);
  71.  
  72. // Raycast into the screen
  73. int mask = currentCamera.cullingMask & (int)cam.eventReceiverMask;
  74. float dist = (cam.rangeDistance > 0f) ? cam.rangeDistance : currentCamera.farClipPlane - currentCamera.nearClipPlane;
  75.  
  76. RaycastHit[] hits = Physics.RaycastAll(ray, dist, mask);
  77.  
  78. if (hits.Length > )
  79. {
  80. for (int b = ; b < hits.Length; ++b)
  81. {
  82. GameObject go = hits[b].collider.gameObject;
  83.  
  84. if (go == Hollow.gameObject)
  85. continue;
  86.  
  87. UIWidget w = go.GetComponent<UIWidget>();
  88.  
  89. if (w != null)
  90. {
  91. if (!w.isVisible) continue;
  92. if (w.hitCheck != null && !w.hitCheck(hits[b].point)) continue;
  93. }
  94. else
  95. {
  96. UIRect rect = NGUITools.FindInParents<UIRect>(go);
  97. if (rect != null && rect.finalAlpha < 0.001f) continue;
  98. }
  99.  
  100. mHit.depth = NGUITools.CalculateRaycastDepth(go);
  101.  
  102. if (mHit.depth != int.MaxValue)
  103. {
  104. mHit.hit = hits[b];
  105. mHit.point = hits[b].point;
  106. mHit.go = hits[b].collider.gameObject;
  107. mHits.Add(mHit);
  108. }
  109. }
  110.  
  111. mHits.Sort(delegate(DepthEntry r1, DepthEntry r2) { return r2.depth.CompareTo(r1.depth); });
  112.  
  113. for (int b = ; b < mHits.size; ++b)
  114. {
  115. #if UNITY_FLASH
  116. if (IsVisible(mHits.buffer[b]))
  117. #else
  118. if (IsVisible(ref mHits.buffer[b]))
  119. #endif
  120. {
  121. Notify(mHits.buffer[b].go, "OnClick", null);
  122. return;
  123. }
  124. }
  125. mHits.Clear();
  126. }
  127. else if (hits.Length == )
  128. {
  129. GameObject go = hits[].collider.gameObject;
  130.  
  131. if (go == Hollow.gameObject)
  132. return;
  133.  
  134. UIWidget w = go.GetComponent<UIWidget>();
  135.  
  136. if (w != null)
  137. {
  138. if (!w.isVisible) return;
  139. if (w.hitCheck != null && !w.hitCheck(hits[].point)) return;
  140. }
  141. else
  142. {
  143. UIRect rect = NGUITools.FindInParents<UIRect>(go);
  144. if (rect != null && rect.finalAlpha < 0.001f) return;
  145. }
  146.  
  147. if (IsVisible(hits[].point, hits[].collider.gameObject))
  148. {
  149. Notify(hits[].collider.gameObject, "OnClick", null);
  150. return;
  151. }
  152. }
  153.  
  154. }
  155.  
  156. }

Unity3d 用NGUI制作做新手引导的思路的更多相关文章

  1. UNITY3D使用NGUI制作自适应UI的总结

    原地址:http://www.cnitblog.com/updraft/archive/2013/11/12/88801.html 制作自适应的几个方法1. 使用 UIROOT 里设置自定义高度的方法 ...

  2. [Unity3D]Unity3D叙利亚NGUI血液和技能的冷却效果

    ---------------------------------------------------------------------------------------------------- ...

  3. 关于NGUI制作图集在低内存设备上的注意事项

    正在写一个游戏.由于2D且比较简单.打算用NGUI全权搞定,对,游戏内容也用NGUI. 想的很好,做的很爽.PC上跑起来happy. 天杀的诺基亚出了个手机叫lumia520,可用内存512M.单个程 ...

  4. Unity3D使用碰撞体做触发器实现简单的自己主动开门

     在游戏制作中触发器的使用很的方便也很有用. 这一张我们简介一下怎样使用一个简单的触发器来实现自己主动开门关门的效果. 首先确保你已经对门进行了动画的设置. 详细流程例如以下. 选择Window- ...

  5. NGUI制作字体的三种方法

    主要参考两篇博文: (1).NGUI制作字体的三种方法 (2).使用位图字体工具BMFont从图片生成自定义字体 1.BMFont下载地址 http://www.angelcode.com/produ ...

  6. (转)NGUI制作转圈的技能CD特效

    在技能图标上面放个半透明的精灵,用来做技能冷却的特效,如下图所示,我就用NGUI中的图标来带代替. NGUI制作转圈的技能CD特效 然后修改一下特效的精灵类型,它是在技能图标上面悬浮半透明可旋转的精灵 ...

  7. PureMVC和Unity3D的UGUI制作一个简单的员工管理系统实例

    前言: 1.关于PureMVC: MVC框架在很多项目当中拥有广泛的应用,很多时候做项目前人开坑开了一半就消失了,后人为了填补各种的坑就遭殃的不得了.嘛,程序猿大家都不喜欢像文案策划一样组织文字写东西 ...

  8. Python来做应用题及思路

    Python来做应用题及思路 最近找工作头疼没事就开始琢磨python解应用题应该可以,顺便还可以整理下思路当然下面的解法只是个人理解,也欢迎大佬们给意见或者指点更好的解决办法等于优化代码了嘛,也欢迎 ...

  9. 利用BMFont和NGUI制作字体集

    Unity中常常需要制作字体,也算是Unity的基本优势吧!其实质就是BMFont和NGUI制作字体.这里把步骤介绍一下: 1.先下载BMFont这个工具 2.Font Settings  设置:(1 ...

随机推荐

  1. SpringMVC框架的工作原理

    学习SpringMVC的工作原理,首先有三个要解决的问题: (1)DispathcherServlet框架如何截获特定的HTTP请求,交由SpringMVC处理? (2)位于Web层的Spring容器 ...

  2. C# 正则分组捕获

    分组语法 捕获 (exp) 匹配exp,并捕获文本到自动命名的组里 (?<name>exp) 匹配exp,并捕获文本到名称为name的组里,也可以写成(?'name'exp) (?:exp ...

  3. VS2015新建asp.net core站点

    摘要 电脑上安装了vs2015,今天就尝尝鲜,新建一个项目试试. BBS 使用vs2015新建一个解决方案,然后新建项目,此时你会发现没有asp.net core项目,这就需要先安装asp.net c ...

  4. 【10-25】OOP基础-飞机游戏知识点

    知识点 鼠标适配器类为抽象类,使用匿名子类实现鼠标事件的重写,创建一个鼠标适配器对象 添加鼠标事件监听器到JPanel对象实现鼠标的响应 创建定时器Timer对象,在定时器的任务列表方法schedul ...

  5. hdu 4960 Another OCD Patient (最短路 解法

    http://acm.hdu.edu.cn/showproblem.php?pid=4960 2014 Multi-University Training Contest 9 Another OCD ...

  6. linxu scp命令

    \ svn 删除所有的 .svn文件 find . -name .svn -type d -exec rm -fr {} \; linux之cp/scp命令+scp命令详解   名称:cp 使用权限: ...

  7. 微信小程序开放公测了 晚上又可以通宵搞代码了

    就在刚刚22:15分,微信公众平台的服务号发来好消息说小程序开放公测了,喜大普奔啊!!!码农们晚上又可以通宵搞测试了.之前还猜测16日微信小论坛小程序专场上会公布,没想到提前了那么多天,效率挺高的,而 ...

  8. hihoCoder挑战赛11.题目4 : 高等理论计算机科学(LCA)

    clj在某场hihoCoder比赛中的一道题,表示clj的数学题实在6,这道图论貌似还算可以... 题目链接:http://hihocoder.com/problemset/problem/1167 ...

  9. 【C语言入门教程】4.6 指针 和 数组

    数组在内存中以顺序的形式存放,数组的第一个存储单元的地址即数组的首地址.对一维数组来说,直接引用数组名就能获得该数组的首地址.指针变量可以存放于其内容相同的数组首地址,也可以指向某一具体的数组元素.通 ...

  10. Codeforces Round #336 Hamming Distance Sum

    题目: http://codeforces.com/contest/608/problem/B 字符串a和字符串b进行比较,以题目中的第一个样例为例,我刚开始的想法是拿01与00.01.11.11从左 ...