我有一个代码,我创建一个凸包,但为凸包中的每个不同的面/三角形实例化一个游戏对象(具有网格渲染器、网格过滤器和网格碰撞器组件),因为我需要每个都具有不同的颜色,然后我想要基于键盘单击移动光线投射(光线投射经过我想要击中的点列表,光线投射的中心是我的凸包的质心,方向基于我在该列表中经过的每个点)。
我的光线投射从未检测到网格碰撞器!它检测球体但从不检测网格,尝试了许多解决方案,例如在FixedUpdate而不是在Update上绘制光线投射,还尝试将这两个代码放在同一个脚本中以及将所有三角形放在同一个对象中(认为这可能是检测的问题)非凸)但没有任何效果。我什至尝试制作一个不会被光线投射忽略的新图层,但仍然没有任何结果。
我的凸创建代码:
void CreateMyMesh()
{
for (int i = 0; i < faces.Count; i++)
{
if (faces[i].points.Count == 3)
{
Vector3 DirectionnnOFTRI = Vector3.Cross(faces[i].points[1] - faces[i].points[0], faces[i].points[2] - faces[i].points[0]).normalized;
Vector3 CentroidTRI = new Vector3((faces[i].points[0].x + faces[i].points[1].x + faces[i].points[2].x) / 3
, (faces[i].points[0].y + faces[i].points[1].y + faces[i].points[2].y) / 3
, (faces[i].points[0].z + faces[i].points[1].z + faces[i].points[2].z) / 3);
float Sign = Vector3.Dot(DirectionnnOFTRI, centroid - CentroidTRI);
if (Sign > 0)
{
for (int j = 2; j >= 0; j--)
{
Vector3 v = new Vector3(faces[i].points[j].x, faces[i].points[j].y, faces[i].points[j].z);
int iWhich = isExist(v, tmpVec);
if (iWhich == -1)
{
tmpVec.Add(v);
tmpTriangles.Add(tmpVec.Count - 1);
}
else
{
tmpTriangles.Add(iWhich);
}
}
}
else
{
for (int j = 0; j < 3; j++)
{
Vector3 v = new Vector3(faces[i].points[j].x, faces[i].points[j].y, faces[i].points[j].z);
int iWhich = isExist(v, tmpVec);
if (iWhich == -1)
{
tmpVec.Add(v);
tmpTriangles.Add(tmpVec.Count - 1);
}
else
{
tmpTriangles.Add(iWhich);
}
}
}
}
else
{
print("Error : #of points in Face != 3");
}
GameObject newMeshObject = Instantiate(MeshObject, MeshObject.transform.position, Quaternion.identity);
newMeshObject.name = "triangle number " + i;
Mesh mesh = new Mesh();
newMeshObject.GetComponent<MeshRenderer>().material.color = new Color(tmpVec[0].x, tmpVec[0].y, tmpVec[0].z, 1f);
newMeshObject.GetComponent<MeshFilter>().mesh = mesh;
newMeshObject.GetComponent<MeshCollider>().sharedMesh = mesh;
mesh.Clear();
mesh.vertices = tmpVec.ToArray();
mesh.triangles = tmpTriangles.ToArray();
mesh.RecalculateNormals();
mesh.name = "triangle mesh number " + i;
tmpVec.Clear();
tmpTriangles.Clear();
}
我的光线投射代码:
int ct = 0;
public void Raycasttt()
{
if(Input.GetKeyDown(KeyCode.UpArrow))
{
if(ct<rayyy.Count-1)
{
ct++;
}
else
{
ct=0;
}
}
Debug.DrawRay(transform.position, (rayyy[ct]) * 10, Color.yellow);
RaycastHit hit;
Vector3 Direc = ((rayyy[ct] * 10) - transform.position ).normalized;
if(Physics.Raycast(transform.position, Direc, out hit, Mathf.Infinity, 6))
{
Debug.Log("in raycast");
if (hit.collider != null)
{
Debug.DrawRay(transform.position, (rayyy[ct]) * 10 * hit.distance, Color.yellow);
Debug.Log("Did Hit");
Debug.Log("HitPosition = " + hit.collider.gameObject.transform.position);
}
Debug.Log(hit.collider.gameObject.name);
}
}
我有一段时间没有使用 Unity 网格体了,但在将顶点和三角形添加到网格体后,可能会添加 MeshCollider 的共享网格体。也许 MeshCollider 在分配时使用网格的顶点和三角形,而不是随着时间的推移而变化的更新值。
据我所知,为了让光线投射捕获网格碰撞器,需要在检查器中将其标记为“凸面”。
否则,您可以通过脚本在运行时启用凸配置,但是检查器选项总是更好一点,因为您可以查看碰撞器是否与您的形状匹配!
这可能是您的光线投射无法捕捉到它的另一个原因!你的对撞机需要匹配你的物体的形状!这解释了为什么您可以捕获球体和盒子碰撞器,但不能捕获网格碰撞器(假设它们一开始就被标记为凸面),因为球体和盒子具有光线投射碰撞和触发的特定形状。当然也要确保图层和标签合适!
确保你的碰撞器足够大。如果您从小发明中启用,您可以检查它们的外观。
图中,MeshCollider 组件的 Mesh 字段为空。这意味着没有可以碰撞的网格体,因此 Raycast 不会报告任何内容。在这里放置一个网格物体,光线投射就会击中它。您还可以将相同的网格放入 MeshFilter 组件中,这样它也将变得可见。