按位与的这种,层计算方式,很多人博客都写了,估计你查了很多篇资料才翻到我这,所以按位与计算不在本篇重点。
这是官方中文文档 https://connect.unity.com/doc/Manual/Layers 可以看一下。
那么为什么按照官方文档,按位与,计算好层,传给Physics.Raycast中的layerMask后,
依然没什么卵用!
写好的逻辑,毫无效果!
为什么!
首先,感谢下面链接作者文章的最后一句话
https://blog.csdn.net/qq_37254346/article/details/88642883
传入LayerMask参数没有效果,是因为Physics.Raycast参数中,没有传入maxDistance
传入LayerMask参数没有效果,是因为Physics.Raycast参数中,没有传入maxDistance
传入LayerMask参数没有效果,是因为Physics.Raycast参数中,没有传入maxDistance
即使你不需要maxDistance这个参数,也要传进去(这里我使用的unity版本是2019.2.11)
像这样,随便传入个1000,作为参数
Physics.Raycast(ray,out hit,1000, mask)
而反观官方文档,他们在maxDistance处,确实都传了Mathf.infinity
然鹅,他们并没有说明。
基本,看到这,标题的问题就解决了。如果想看其它基础知识,请往下
其次,贴一下按位与的基本知识
1 << 9 打开第9层。
~(1 << 9) 打开除了第9之外的层。
~(1 << 0) 打开所有的层。
(1 << 10) | (1 << 8) 打开第10和第8的层。
关于LayerMask这里要传什么样的参数
1.传入int型
直接按照上面,按位与基本知识,传入想要打开射线碰撞检测的层即可。
例如我只想射线与第8层交互,其它全部穿过忽略
Physics.Raycast(ray,out hit,1000, (1 << 8))
若不使用按位与,直接输入一个Int到LayerMask,那么unity会忽略你输入的这个层,这个层的index与Tag & Layer中的关系是+1的。
比如,我想忽略Floor层,我们要传入9,而不是8!
Physics.Raycast(ray,out hit,1000, 9)
2.传入LayerMask类型
这种非常直观,而且容易编辑,共有参数可以在Inspector中编辑想要交互的层
其次,如果想要代码为其赋值,可以
public LayerMask mask;
void Start()
{
mask = (1 << 8) | (1 << 11);
}
这是,指定Floor层和C层,参与交互
这是我的一个例子
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LLL : MonoBehaviour
{
LineRenderer lineRender;
Ray ray;
RaycastHit hit;
Transform point;
public string TeleableTag = "";
public int mlayer = 0;
public LayerMask mask;
void Start()
{
point = transform;
lineRender = GetComponent<LineRenderer>();
lineRender.startWidth = 0.05f;
lineRender.endWidth = 0.05f;
lineRender.useWorldSpace = false;
lineRender.material = new Material(Shader.Find("Standard"));
mask = (1 << 8) | (1 << 11);
}
void Update()
{
ray = new Ray(point.position, point.transform.forward);
//;
//
if (Physics.Raycast(ray,out hit,1000, mask)) {
if (hit.transform.tag == TeleableTag) {//
//可传送
LinernederTeleable();
}
else {
//Tag验证未通过,不可传送
LinerenderUnTeleable();
}
}
else {
//不可传送
LinerenderUnTeleable();
}
}
private void LinernederTeleable() {
//linerender 结束点=hit 颜色=green
lineRender.SetPosition(1, new Vector3(0, 0, Vector3.Distance(point.position, hit.point)));
Debug.Log("point=" + hit.point + " distance=" + Vector3.Distance(point.position, hit.point));
lineRender.materials[0].color = Color.green;
Debug.Log(hit.transform.name);
}
private void LinerenderUnTeleable() {
//linerender 结束点=很大 颜色=red
if (hit.transform.gameObject == null)
lineRender.SetPosition(1, new Vector3(0, 0, 1000));
else
lineRender.SetPosition(1, new Vector3(0, 0, Vector3.Distance(point.position, hit.point)));
lineRender.materials[0].color = Color.red;
}
}
运行结果