Physics.Raycast failing

Hey All:

First off, I am not sure if this should be a Physics or Graphics question. It looks like a Graphics problem, so I posted here. Apologies if I got it wrong.

I am trying to perform a Physics.Raycast on the center hex of a hex map, in order to select said hex (GameObject). The call is returning false.

   public GameObject GetLookedAtGameObject()
   {
      // in an editor run, the game window is really a "window", and not full screen. So I am
      // not sure if ScreenPointToRay still works, since the window is not centered on the
      // screen. It seems to me that ViewportPointToRay should work regardless?
      Ray ray = Camera.main.ViewportPointToRay(new Vector3(0.5F, 0.5F, 0));

      RaycastHit hit;
      if (Physics.Raycast(ray, out hit)) {
         // Get the GameObject that was hit
         GameObject lookedAtObject = hit.collider.gameObject;

         // Do something with the lookedAtObject, like logging its name
         Debug.Log("Looking at: " + lookedAtObject.name);

         return lookedAtObject;
      }

      return null;
   }

GetLookedAtGameObject() always returns null. I clearly see the hex drawn in the window with the correct material. Here is a picture of the center hex (green) with a white dot over the center of the viewport.


I’ve looked at the pertinent hex info, the Ray (data) numbers, etc, many times: it all looks spot on! I know that this doesn’t mean it is correct. it seems that the Raycast is on the green (center) hex. Not only does GetLookedAtGameObject fail to find the center hex, it fails to find any hex on the larger map. i must be making a mistake somewhere.

For each Hex, the associated collider and mesh are created in OnEnable():

   private void OnEnable()
   {
      // each hex has one collider
      m_collider = gameObject.AddComponent<MeshCollider>();
      // ... and one mesh
      m_collider.sharedMesh = new Mesh();
      m_collider.sharedMesh.name = "Hex";

      // assign the same mesh to the mesh filter?
      m_meshFilter.mesh = m_collider.sharedMesh;

      shouldUpdateMesh = true;
   }

… drawing is done in Update():

   private void Update()
   {
      if (shouldUpdateMesh) {
         DrawMesh();
         shouldUpdateMesh = false;
      }
   }

After all the faces (triangles, verticies and uv’s) are otherwise formed, they are combined and given to the collider in CombineColliderData(), which is made during DrawMesh(). I did not post the code for forming the faces, because the faces draw correctly, so it seems redundant. I can provide if needed.

   public void CombineColliderData()
   {
      List<Vector3> vertices = new List<Vector3>();
      List<int> triangles = new List<int>();
      List<Vector2> uvs = new List<Vector2>();

      for (int i = 0; i < m_faces.Count; i++) {
         // add the vertices and uv's to the master list's for the collider.
         vertices.AddRange(m_faces[i].vertices);
         uvs.AddRange(m_faces[i].uvs);
         // offset and add the triangles to the master list for the collider.
         int offset = (4 * i);
         foreach (int triangle in m_faces[i].triangles) {
            triangles.Add(triangle + offset);
         }
      }

      Mesh mesh = m_collider.sharedMesh;
      mesh.vertices = vertices.ToArray();
      mesh.triangles = triangles.ToArray();
      mesh.uv = uvs.ToArray();
      mesh.RecalculateNormals();
   }

Hopefully it is clear that I do not have one mesh for drawing and a another mesh for collision. I use the same mesh for both: not sure if this bad or not?

Question 1: Am I misunderstanding, and therefore misusing/misforming the mesh/collider code? I am guessing that the basic data is correct since everything draws correctly?, … although I may be mistaken.

Question 2: Am I making an incorrect Physics.Raycast call?

thoughts/feedback appreciated.

Cheers!

When updating the mesh first remove the MeshCollider component and then after updating the mesh and assigning it to the MeshFilter you can add the MeshCollider component again and it’ll automatically use the mesh that’s currently assigned to the MeshFilter.

That did the trick zulo3d. so the take away is don’t set the collider until all the pieces/parts are in place?

1 Like