一、先看下效果

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. MV*模式的个人理解

    MV*模式主要解决的问题就是 View代码难以维护的问题. MV*模式将View中的逻辑分离出去,形成一个弱逻辑的易于维护的视图. MV*中的*是Model和View的桥梁,负责保持Model和Vie ...

  2. JSTL I18N 格式标签库

    <%@ page language="java" pageEncoding="gbk"%> <%@ taglib prefix="c ...

  3. C# 表达式树demo

    class Program { static void Main(string[] args) { //创建Expression参数 var left = System.Linq.Expression ...

  4. Linq 操作基础

    参考资料: LINQ系列:LINQ to DataSet的DataTable操作 List<T>转换为DataTable C# DataTable 和List之间相互转换的方法 Linq中 ...

  5. 关于 jquery 选择器的 深入理解 -1

    多级选择器: 前面一个selector1, 后面通过 //空格, >, + ~, 各种筛选 选择器 + selector2 // 再次进行选择的,就叫做多级选择器 jquery的一个基本常识: ...

  6. thinkphp的url地址区分大小写?

    在默认情况下: 在访问url地址的时候, 其中的 Action类名 即: 模块名称 是区分大小写的. (只有模块名, 即控制器名称) 可以根据设置 'URL_CASE_INSENSITIVE' =&g ...

  7. Win7与XP共享互相访问及共享注意事项!

    win7共享方法和XP类似,主要需要检查以下操作: 1,首先将Guest账户打开 2,右击文件夹-属性-共享选项-高级共享 3,将共享文件√打上,应用-确定即可! 4,查看自己IP(开始-运行-cmd ...

  8. 如何催促Apple进行App审核

    为什么提交给 App Store 的应用进入"审核(In Review)"状态后, 仍然可能会等待好多天的时间 ? 不过你也可以通过催促Apple进行App审核来缩短这个时间.以下 ...

  9. 基于iSCSI的SQL Server 2012群集测试(四)--模拟群集故障转移

    6.模拟群集故障转移 6.1 模拟手动故障转移(1+1) 模拟手动故障转移的目的有以下几点: 测试群集是否能正常故障转移 测试修改端口是否能同步到备节点 测试禁用full-text和Browser服务 ...

  10. 利用百度语音API进行语音识别。

    由于项目需要,这几天都在试图利用百度语音API进行语音识别.但是识别到的都是“啊,哦”什么的,我就哭了. 这里我只是分享一下这个过程,错误感觉出现在Post语音数据那一块,可能是转换问题吧. API请 ...