一、先看下效果

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. MongoDB学习笔记(索引)(转)

    一.索引基础:    MongoDB的索引几乎与传统的关系型数据库一模一样,这其中也包括一些基本的优化技巧.下面是创建索引的命令:    > db.test.ensureIndex({" ...

  2. verilog阻塞与非阻塞的初步理解(三)

    下面这段源码是因为习惯不好,出现不正确波形的例子. module pwm_division(reset,clkin,clkout); input reset,clkin; output clkout; ...

  3. Fortify

    sourceanalyzer -b my_buildid -scan -f xxx.fpr -b  取一个build的ID号,通常以这个项目名称加扫描时间为buildID-Xmx 指定JVM使用的最大 ...

  4. ImageView.ScaleType8种用法

    1·ImageView.ScaleType.center:图片位于视图中间,但不执行缩放. 2·ImageView.ScaleType.CENTER_CROP 按统一比例缩放图片(保持图片的尺寸比例) ...

  5. POJ 2452 Sticks Problem

    RMQ+二分....枚举 i  ,找比 i 小的第一个元素,再找之间的第一个最大元素.....                   Sticks Problem Time Limit: 6000MS ...

  6. 数论只会GCD。。。

    一些关于GCD的代码.... #include <iostream> #include <cstdio> #include <cstring> using name ...

  7. eclipse tomcat debug启动慢

    myeclipse或eclipse下debug模式启动很慢,默认模式也是debug,网上找了终于解决, 原因是有eclipse或myeclipse启动debug时自动添加断点,所以必须删除一些东西. ...

  8. Android4.4 往短信收件箱中插入自定义短信(伪造短信)

    这段时间稍微有点空闲,把前一段学习Android做过的一些小项目整理整理.虽然没有什么工程量很大的项目,但是对于一个新手,解决这些问题还是花了一段时间.感觉还是非常有记录的意义呢~~~么么哒*—* 今 ...

  9. ajax访问 aspx.cs后台

    --前台$.ajax({ type: "POST", contentType: "application/json", url: "WebForm2. ...

  10. laravel中间件-----------middleware

    middleware中间件 是访问到达服务器后在被对应的路由处理之前所经过的一层过滤层,故称中间件. 中间件是存放在app\http\middleware中,需要定一个 handle 处理方法,在ha ...