代码改变世界

Unity Layout碰撞检测

2014-10-25 11:44  wuzhang  阅读(1801)  评论(1编辑  收藏  举报

第一次看到LayerMask根本不知道是什么东东,后来问问度娘,看了几篇文章,终于看明白一点点,在网上看到各路大神的解释,终于明白了,LayerMask实际上是一个位码操作,在Unity3d中Layers一共有32层,这个是不能增加或者减少的,中文名字叫层蒙版

LayerMask允许你在检视面板中显示LayerMask弹出菜单,类似与camera.cullingmask。LayerMask可以选择性地过滤物体,例如当投射射线时

摘自官网:
Layers are used throughout Unity as a way to create groups of objects that share particular characteristics (see this page for further details). Layers are primarily used to restrict operations such as raycasting or rendering so that they are only applied to the groups of objects that are relevant. In the manager, the first eight layers are defaults used by Unity and are not editable. However, layers from 8 to 31 can be given custom names just by typing in the appropriate text box. Note that unlike tags, the number of layers cannot be increased.
所以那个LayerMask实际上是用Int32的32个位来表示每个层级,当这个位为1时表示使用这个层,为0时表示不用这个层。

回到上面的例子:
1 << LayerMask.NameToLayer("cube")

此处的1表示射线查询只在cube所在这个层级查找。


再来看看NameToLayer是干嘛的。
官网解释:
Given a layer name, returns the layer index as defined by either a Builtin or a User Layer in the Tag Manager.
是返回的该名字所定义的层的层索引,注意是从0开始。

下面咱们做个简单的测试:新建一个Unity 工程

结构如下:

新建layers

Cube的属性设置:

MainCamer属性

Layerout.cs

 1 using UnityEngine;
 2 using System.Collections;
 3 
 4 
 5 public class layout : MonoBehaviour 
 6 {
 7     public LayerMask mask;
 8     // Use this for initialization
 9     void Start ()
10     {
11         mask.value = 1 << 0 | 1 << 8;
12         //mask=1<<0|1<<8;这样写也可以
13         Debug.Log(mask.value);
14 
15         mask.value = ~(1 << 0 | 1 << 8);
16         //mask=~(1<<0|1<<8);这样写也可以
17         Debug.Log(mask.value);
18     }
19     
20     // Update is called once per frame
21     void Update () 
22     {
23         Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);//从摄像机发出到点击坐标的射线
24         RaycastHit hitInfo;
25         int layerNum = LayerMask.NameToLayer("cube");//获取Cube层的层级号
26         LayerMask mask = 1 << layerNum;//取得Cube的层级值
27         if (Input.GetMouseButtonDown(0))
28         {
29             if (Physics.Raycast(transform.position, transform.forward,out hitInfo, 100, mask.value))//只检测Cube层级的碰撞。
30             {
31                 Debug.Log(hitInfo.transform.name);
32                 Debug.DrawLine(transform.position, hitInfo.point, Color.red, 2);
33             }
34         }
35 
36     }
37 
38 }

运行结果:

Start函数结果分析:

Update函数结果分析:

PS:以后我们在做游戏时可以有选择的碰撞检测了。