简体   繁体   English

为什么我的光线投射在 Unity 中没有检测到任何网格对撞机?

[英]Why is my raycast not detecting any mesh colliders in Unity?

I have a code where im creating a convex hull but instantiating a gameobject (has mesh renderer, mesh filter, and mesh collider components) for each different face/triangle in my convex because I need each to be a different color, I then want to move raycast based on keyboard click (the raycast goes through a list of points that i want to hit, the center of the raycast is the centroid of my convex hull and the direction is based on each point I go through in that list).我有一个代码,我在其中创建一个凸包,但为我的凸包中的每个不同的面/三角形实例化一个游戏对象(具有网格渲染器、网格过滤器和网格碰撞组件),因为我需要每个都是不同的颜色,然后我想根据键盘点击移动光线投射(光线投射经过我想要击中的点列表,光线投射的中心是我的凸包的质心,方向基于我 go 在该列表中的每个点)。

My raycast never detects mesh colliders, it detects spheres but never meshes, tried many solutions such as drawing the raycast on FixedUpdate rather that on Update.我的光线投射从不检测网格碰撞器,它检测到球体但从不网格,尝试了许多解决方案,例如在 FixedUpdate 上而不是在 Update 上绘制光线投射。 also tried putting both codes in the same script as well as making all triangles in the same object (thought it might be a problem with detecting non-convex) but nothing worked.还尝试将两个代码放在同一个脚本中,并将所有三角形放在同一个 object 中(认为检测非凸可能是个问题),但没有任何效果。 I even tried making a new layer that is not ignored by raycast and still nothing.我什至尝试制作一个不会被光线投射忽略的新图层,但仍然没有。

My convex creating code:我的凸创建代码:

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();
        }

My raycast code:我的光线投射代码:

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);
        }
    }

My mesh object that I instantiate:我实例化的网格 object: 网格对象

I haven't worked with Unity meshes for a while but maybe add the sharedMesh of your MeshCollider after you added the verticies and triangles to your Mesh.我已经有一段时间没有使用 Unity 网格了,但是在将顶点和三角形添加到网格之后,可能会添加 MeshCollider 的 sharedMesh。 Maybe the MeshCollider uses the verticies and triangles of the Mesh at the time of assignment and not the updated values if it changes overtime.也许 MeshCollider 在分配时使用 Mesh 的顶点和三角形,而不是在超时时使用更新的值。

As far as I am aware in order for the raycast to catch the mesh collider it needs to be marked as "Convex" in the inspector.据我所知,为了让光线投射捕捉到网格对撞机,它需要在检查器中标记为“凸”。

Otherwise you could enable the convex configuration in runtime through a script however the inspector option is always a bit better because you can then see if the collider matches your shape!否则,您可以通过脚本在运行时启用凸配置,但是检查器选项总是更好一些,因为您可以查看对撞机是否与您的形状匹配!

This could be another reason why your raycast cannot catch it!这可能是您的光线投射无法捕捉到它的另一个原因! your collider needs to match the shape of your object!您的对撞机需要与您的对象的形状相匹配! This explains why you can catch sphere and box colliders but not mesh colliders (assuming that they are marked as convex to begin with) since the sphere and box have specific shapes that the raycast collides and triggers.这解释了为什么您可以捕捉球体和盒子碰撞器,但不能捕捉网格碰撞器(假设它们一开始就被标记为凸面),因为球体和盒子具有光线投射碰撞和触发的特定形状。 Of course make sure that the layers and tags are appropriate as well!当然要确保图层和标签也合适!

Make sure your colliders are big enough.确保你的对撞机足够大。 You can check how they look if you enable from gizmos.如果从 Gizmo 启用,您可以检查它们的外观。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM