这一篇是纯技术讨论,看过我前面文章的童鞋应该清楚,我的奔跑是靠鼠标响应的,鼠标点到哪就跑到哪,后来又有了界面,麻烦就来了,我的界面居然能点 穿。我不希望点界面的时候还能点到界面后面的地面上,角色傻不拉几的往那跑,那肿么办呢,总不能每次点击都要推断点击的物体名称吧。那界面多了会累死的, 好在我们有标签和层这两个神器,所以我这里介绍两种方案,都能达到效果。

方案一:利用标签(Tag)拦截射线消息。

每一个GameObject的Inspector面板最上方都有个Tag选项,也就是说我们能够给全部的物体加个标签,Unity3d已经默认有了几 个标签,这里我们能够自己定义个UI的标签。然后把全部UI都用这个标签。点击Tag右方的选项。选Add Tag。Size调成2。Element 0的值改成UI。

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbHpocTE5ODI=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

然后你全部不想被点穿的UI都选成这个标签。

除了设置标签,另一点非常重要,就是界面要加碰撞器Collider,有的UI默认就有碰撞器,比方NGUI的button,你能够看到有一个Box Collider。假设没有的你就要自己加了,Size那里要调成这个UI的尺寸:

这样UI才干接收射线碰撞。然后代码能够这样写:

[csharp] view plaincopy
  1. Ray ray1 = nguiCamera.camera.ScreenPointToRay(Input.mousePosition);
  2. RaycastHit hit1;
  3. if (Physics.Raycast(ray1, out hit1)) {
  4. if (hit1.collider.gameObject.tag == "UI")
  5. return;
  6. }

上面的nguiCamera是获取的NGUI下的Camera。由于是这个Camera发出的射线与UI的碰撞,而不是Main Camera,这点要注意。其它的不解释了。非常easy,自己看。

方案二、利用层(Layer)拦截射线消息

每一个GameObject的Inspector面板最上方都也有个Layer选项,就在Tag旁边,unity3d已经有了几个层。我们新建个层。 也叫UI,点击Add Layer,能够看到从Layer0到Layer7都灰掉了,那是不能用的,从第八个起能够用。所以在第八个建个UI的层。

然后我们看一下Physics的Raycast的參数:

static function Raycast (ray : Rayout
hitInfo
 : RaycastHitdistance :
float = Mathf.InfinitylayerMask :
int = kDefaultRaycastLayers) : bool

普通情况下我们仅仅用前两个參数,distance表示射线距离,默认是无限远,重点是最后一个參数layerMask,专门处理layer过滤的,是个整型,怎么用呢。是靠layer的二进制位来操作的。看以下代码就清楚了:

[csharp] view plaincopy
  1. Ray ray1 = nguiCamera.camera.ScreenPointToRay(Input.mousePosition);
  2. RaycastHit hit1;
  3. LayerMask mask = 1 << LayerMask.NameToLayer("UI");
  4. if (Physics.Raycast(ray1, out hit1, 600, mask.value)) {
  5. return;
  6. }

LayerMask的NameToLayer是通过层的名称返回该层的索引,这里是8,然后1<<8换算成LayerMask值,再用LayerMask的value就能够了。

注意也必须设置collider才干接收碰撞,这里才干推断到。

我这里提供了两个方案,假设有其它方案的欢迎留言,谢谢。



笔者补充内容

 假设是在代码中自己创建GameObject指定Layer的方法和获取Layer进行射线的注意地方。

例如以下创建一个GameObject:



          GameObject _newObj = new GameObject();

            _newObj.layer = LayerMask.NameToLayer("CommObj"); //指定Layer

            _newObj.name = "Terrain0_Grass";



            print(LayerMask.NameToLayer("CommObj"));



            BoxCollider _collider = _newObj.GetComponent();

            _collider = _collider == null ?

_newObj.AddComponent() : _collider;

            _collider.center = Vector3.zero;

            _collider.size = new Vector3(10f, CommonDef.Layer0_Terrain_Grass, 10f);



            MeshFilter _meshFilter = _newObj.GetComponent();

            _meshFilter = _meshFilter == null ?

_newObj.AddComponent() : _meshFilter;



            Mesh _mesh = ModelResManager.AddTerrainGrassMesh(10, 10);

            _meshFilter.mesh = _mesh;



            MeshRenderer _meshRender = _newObj.GetComponent();

            _meshRender = _meshRender == null ? _newObj.AddComponent() : _meshRender;



            //指向父子节点关系,仅仅需指定其位置组件父子关系;

            GameObject _subObj = GameObject.CreatePrimitive(PrimitiveType.Cube);

            _subObj.transform.parent = _newObj.transform;



以上是创建一个GameObject。赋上Collider组件用于射线碰撞检測。下面是获取指定Layer射线的方法:

 

          LayerMask mask = 1 << LayerMask.NameToLayer("CommObj");



          Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

          RaycastHit _hitInfo;

          if (Physics.Raycast(ray, out _hitInfo, 1000f, mask.value))

          {

             m_currSelectObj = _hitInfo.collider.gameObject;

             m_mouseMovePos = _hitInfo.point;

         }



黑体字为获取指定Layer的mask值。用于射线检測。

Unity3D 射线指定层获取GameObject 注意 LayerMask的更多相关文章

  1. sql 根据指定条件获取一个字段批量获取数据插入另外一张表字段中+MD5加密

    /****** Object: StoredProcedure [dbo].[getSplitValue] Script Date: 03/13/2014 13:58:12 ******/ SET A ...

  2. [ionic开源项目教程] - 第4讲 通Service层获取数据列表

    第4讲:通Service层获取数据列表 上一讲中页面的基本架构已完成,这一讲介绍如何通过service层从服务器请求数据,在通过controller层为载体,显示到视图层. 1.在services.j ...

  3. caffe fine tune 复制预训练model的参数和freeze指定层参数

    复制预训练model的参数,只需要重新copy一个train_val.prototxt.然后把不需要复制的层的名字改一下,如(fc7 -> fc7_new),然后fine tune即可. fre ...

  4. 计算 byte[] 转 int modebus 指定位数 获取值 使用

    计算 byte[] 转 int modebus 指定位数 获取值 使用 if (bytetores.Length > 6) { int total = 0; for (int i = 0; i ...

  5. 在spring的业务层获取request,response

    1.直接通过controller层获取到传输到业务层2.SpringMVC提供的RequestContextHolder可以直接获取代码: RequestAttributes requestAttri ...

  6. 【Unity笔记】鼠标射线由指定层接收

    LayerMask mask = << LayerMask.NameToLayer("UI"); Ray ray = Camera.main.ScreenPointTo ...

  7. 【unity3d游戏开发之基础篇】unity3d射线的原理用法以及一个利用射线实现简单拾取的小例子

    原地址:http://www.cnblogs.com/xuling/archive/2013/03/04/2943154.html 最近开始研究U3D,它的强大就不多说了, 今天研究了研究射线相关东西 ...

  8. unity3d 射线的原理,基础用法

    射线:射线是3D世界中一个点向一个方向发射的一条无终点的线,在发射轨迹中与其他物体发生碰撞时,它将停止发射 . Ray射线类和RaycastHit射线投射信息类是射线中常用的两个工具类. 用途:射线多 ...

  9. Unity3D之随心所欲的获取对象

    ps 1 建立一个cube 建立一个scripts 2  scripts 赋给cube 3  在script里面直接  gameObject.SetActive (false); 就是操作当前脚本绑定 ...

随机推荐

  1. jdbc数据库中的增删改

    HttpSession session=request.getSession(); session.setAttribute("currentUser",u.username);/ ...

  2. 2019手机号码JS正则表达式

    前端的正则表达式验证往往是最繁多最复杂的,所以整理了一些最近自己常用的正则表达式,希望能对大家有所帮助! /* 合法uri */ export function validateURL(textval ...

  3. python请求服务器图片并下载到本地磁盘

    >>> import os >>> os.getcwd() 'C:\\Python33' >>> os.chdir('E:\\python\\mm ...

  4. MVC简单的解释

    MVC (Model-View-Controller,模型视图控制器)是一种软件的设计模式,它最早是由 20 世纪 70 年代的 Smalltalk 语言提出的,即把一个复杂的软件工程分解为三个层 ...

  5. Oracle 当输入参数允许为空时

    场景: 有一个存储过程p_test 带有多个输入参数code.name.number p_test(code IN VARCHAR2,nameIN VARCHAR2,number IN VARCHAR ...

  6. sql--Truncate Table

    Truncate Table(截断表) 有时候需要清除一个表中的所有资料.要达到者个目的,一种方式是DROP TABLE 指令.不过这样整个表格就消失,而无法再被用了. 另一种方式是Delete不带w ...

  7. Java接口中的成员变量为什么必须声明为public static final?

    我想对于每个Java程序员来说,接口都不陌生,接口中的方法也经常使用.而接口中的成员变量,就显得用得少一点,而对于成员变量为什么必须声明为public static final,可能就更不清楚了,而且 ...

  8. jQuery学习笔记之插件开发(4)

    jQuery学习笔记之插件开发(4) github源码地址 插件:了让原有功能的增强. 1.插件的种类(3种):局部.全局.选择器插件 1.1封装对象方法的插件 这种类型的插件是把一些常用或者重复使用 ...

  9. 网页前端状态管理库Redux学习笔记(一)

    最近在博客园上看到关于redux的博文,于是去了解了一下. 这个Js库的思路还是很好的,禁止随意修改状态,只能通过触发事件来修改.中文文档在这里. 前面都很顺利,但是看到异步章节,感觉关于异步说得很乱 ...

  10. dubbo之上下文信息

    上下文信息 上下文中存放的是当前调用过程中所需的环境信息.所有配置信息都将转换为 URL 的参数,参见 schema 配置参考手册 中的对应URL参数一列. RpcContext 是一个 Thread ...