Unity3D 射线指定层获取GameObject 注意

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

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

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

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

除了设置标签,还有一点很重要,就是界面要加碰撞器Collider,有的UI默认就有碰撞器,比如NGUI的按钮,你可以看到有一个Box Collider,如果没有的你就要自己加了,Size那里要调成这个UI的尺寸:

这样UI才能接收射线碰撞,然后代码可以这样写:

[csharp]

Rayray1=nguiCamera.camera.ScreenPointToRay(Input.mousePosition);RaycastHithit1;return;}

上面的nguiCamera是获取的NGUI下的Camera,因为是这个Camera发出的射线与UI的碰撞,而不是Main Camera,这点要注意。其他的不解释了,很简单,自己看。

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

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

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

out hitInfo: float =: int = kDefaultRaycastLayers) : bool

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

[csharp]

Rayray1=nguiCamera.camera.ScreenPointToRay(Input.mousePosition);RaycastHithit1;LayerMaskmask=1<<LayerMask.NameToLayer("UI");return;}

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 注意

相关文章:

你感兴趣的文章:

标签云: