一、先看下效果

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的位置

using System;
using UnityEngine;
using System.Collections;
using System.Collections.Generic; public class NewbieGuide : MonoBehaviour
{ public Transform Hollow; bool IsVisible(Vector3 worldPoint, GameObject go)
{
UIPanel panel = NGUITools.FindInParents<UIPanel>(go); while (panel != null)
{
if (!panel.IsVisible(worldPoint)) return false;
panel = panel.parentPanel;
}
return true;
} struct DepthEntry
{
public int depth;
public RaycastHit hit;
public Vector3 point;
public GameObject go;
} #if UNITY_FLASH
static bool IsVisible (DepthEntry de)
#else
static bool IsVisible(ref DepthEntry de)
#endif
{
UIPanel panel = NGUITools.FindInParents<UIPanel>(de.go); while (panel != null)
{
if (!panel.IsVisible(de.point)) return false;
panel = panel.parentPanel;
}
return true;
} void Notify(GameObject go, string funcName, object obj)
{
if (NGUITools.GetActive(go))
{
go.SendMessage(funcName, obj, SendMessageOptions.DontRequireReceiver);
}
} public void ClickCenter()
{
DepthEntry mHit = new DepthEntry();
BetterList<DepthEntry> mHits = new BetterList<DepthEntry>(); UICamera cam = UICamera.current; UIEventTrigger.current = null; // Convert to view space
var currentCamera = cam.cachedCamera; // Cast a ray into the screen
var p = Hollow.transform.position;
p.z = currentCamera.nearClipPlane;
Ray ray = new Ray(p, Vector3.forward); // Raycast into the screen
int mask = currentCamera.cullingMask & (int)cam.eventReceiverMask;
float dist = (cam.rangeDistance > 0f) ? cam.rangeDistance : currentCamera.farClipPlane - currentCamera.nearClipPlane; RaycastHit[] hits = Physics.RaycastAll(ray, dist, mask); if (hits.Length > )
{
for (int b = ; b < hits.Length; ++b)
{
GameObject go = hits[b].collider.gameObject; if (go == Hollow.gameObject)
continue; UIWidget w = go.GetComponent<UIWidget>(); if (w != null)
{
if (!w.isVisible) continue;
if (w.hitCheck != null && !w.hitCheck(hits[b].point)) continue;
}
else
{
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].point;
mHit.go = hits[b].collider.gameObject;
mHits.Add(mHit);
}
} mHits.Sort(delegate(DepthEntry r1, DepthEntry r2) { return r2.depth.CompareTo(r1.depth); }); for (int b = ; b < mHits.size; ++b)
{
#if UNITY_FLASH
if (IsVisible(mHits.buffer[b]))
#else
if (IsVisible(ref mHits.buffer[b]))
#endif
{
Notify(mHits.buffer[b].go, "OnClick", null);
return;
}
}
mHits.Clear();
}
else if (hits.Length == )
{
GameObject go = hits[].collider.gameObject; if (go == Hollow.gameObject)
return; UIWidget w = go.GetComponent<UIWidget>(); if (w != null)
{
if (!w.isVisible) return;
if (w.hitCheck != null && !w.hitCheck(hits[].point)) return;
}
else
{
UIRect rect = NGUITools.FindInParents<UIRect>(go);
if (rect != null && rect.finalAlpha < 0.001f) return;
} if (IsVisible(hits[].point, hits[].collider.gameObject))
{
Notify(hits[].collider.gameObject, "OnClick", null);
return;
}
} } }

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. 跟着ttlsa一起学zabbix监控呗

    本章转载至:http://www.ttlsa.com/zabbix/follow-ttlsa-to-study-zabbix/ 虽然接触zabbix时间很长,但是中间相当一段时间没去配置,这次算是重新 ...

  2. Mysql InnoDB行锁实现方式(转)

    Mysql InnoDB行锁实现方式 InnoDB行锁是通过给索引上的索引项加锁来实现的,这一点MySQL与Oracle不同,后者是通过在数据块中对相应数据行加锁来实现的.InnoDB这种行锁实现特点 ...

  3. Google地图实现

    API地址:https://developers.google.com/maps/documentation/javascript/tutorial <div id="map" ...

  4. oracle 特殊符号

    http://hi.baidu.com/wind_stay/blog/item/85113a6f6553a5d680cb4a0e.html oracle通配符,运算符的使用 用于where比较条件的有 ...

  5. Spring之FactoryBean

    首先要分辨BeanFactory 与 FactoryBean的区别, 两个名字很像,所以容易搞混 BeanFactory: 以Factory结尾,表示它是一个工厂类,是用于管理Bean的一个工厂 Fa ...

  6. jquery自定义函数的多种方法

    在jquery中自定义函数你会吗?今天抽时间写了几个,个人感觉还不错,喜欢的朋友可以了解下   复制代码 代码如下: //方法定义 $.windowbox = { //定义一个方法aa aa: fun ...

  7. mongodb 基本用法大全

    1>给数据库添加用户名密码    db.addUser("xxx","yyy") 2>

  8. word中那些重要但是被人忽略的快捷键和长word文档的跳转

    重复上一次操作: F4, 这个太重要了,比如你在做一次很复杂的操作, 下一次又要这样操作时就很有用! 如设置 文字的 段落背景/ 底纹颜色!时要多次设置这个时就 非常有用! 段落缩进:ctrl+M : ...

  9. zoj3811 Untrusted Patrol (dfs)

    2014牡丹江网络赛C题 (第三水的题 The 2014 ACM-ICPC Asia Mudanjiang Regional First Round http://acm.zju.edu.cn/onl ...

  10. IEnumerable 和 IEnumerator

    IEnumerable 接口只包含一个抽象的方法 GetEnumerator(),它返回一个可用于循环访问集合的 IEnumerator 对象,IEnumerator 对象是一个集合访问器. 需要给自 ...