Home > Mobile >  Why is my raycast not detecting any mesh colliders in Unity?
Why is my raycast not detecting any mesh colliders in Unity?

Time:06-08

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).

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, 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. 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: MeshObject

CodePudding user response:

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. 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.

CodePudding user response:

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!

  • Related