0

I basically want to be able to select many things in my game by projecting a UI selection box (hold right click) into a corresponding meshcollider in world space that would detect anything in it. So I have my main script that takes care of turning screen coords of all four corners of the box into world coords using raycastAll (this part works fine AFAIK but here it is anyway):

`                                      //////////// SELECTION BOX ////////////////
//set vertex p0 to the position where the player first clicked
        if (Input.GetMouseButtonDown(0))
        {
            clickPos = Input.mousePosition;

            RaycastHit[] hits0 = Physics.RaycastAll(Camera.main.ScreenPointToRay(clickPos));
            foreach (RaycastHit hit in hits0)
            {
                if (hit.collider.tag == "chunk")
                {
                    p0 = new Vector3(hit.point.x, -2f, hit.point.z);
                }
             }
        }

//everything disappear if player let go the mouse button
        if (Input.GetMouseButtonUp(0))
        {
            selectionBox.gameObject.SetActive(false);
            GetComponent<MeshCollider>().sharedMesh?.Clear();
            GetComponent<MeshCollider>().enabled = false;
        }
//if mouse button is held down, the UI box appear and the other vertices(p1, p2, p3) are determined accordingly
        if (Input.GetMouseButton(0))
        {
            mousePos = Input.mousePosition;
            if ((clickPos - mousePos).magnitude > 20f)
            {
                // selection box UI
                selectionBox.gameObject.SetActive(true);
                selectionBox.rectTransform.sizeDelta = new Vector2(Mathf.Abs(clickPos.x - mousePos.x), Mathf.Abs(clickPos.y - mousePos.y));
                selectionBox.rectTransform.anchoredPosition = clickPos + new Vector3((mousePos.x - clickPos.x) / 2, (mousePos.y - clickPos.y) / 2, 0f);

                //selection box meshcollider
                RaycastHit[] hits1 = Physics.RaycastAll(Camera.main.ScreenPointToRay(mousePos));
                foreach (RaycastHit hit in hits1)
                {
                    if (hit.collider.tag == "chunk")
                    {
                        p1 = new Vector3(hit.point.x, -2f, hit.point.z);
                    }
                }
                RaycastHit[] hits2 = Physics.RaycastAll(Camera.main.ScreenPointToRay(new Vector2(clickPos.x, mousePos.y)));
                foreach (RaycastHit hit in hits2)
                {
                    if (hit.collider.tag == "chunk")
                    {
                        p2 = new Vector3(hit.point.x, -2f, hit.point.z);
                    }
                }
                RaycastHit[] hits3 = Physics.RaycastAll(Camera.main.ScreenPointToRay(new Vector2(mousePos.x, clickPos.y)));
                foreach (RaycastHit hit in hits3)
                {
                    if (hit.collider.tag == "chunk")
                    {
                        p3 = new Vector3(hit.point.x, -2f, hit.point.z);
                    }
                }

//meshGen is a custom class that takes in four Vector3 and output the corresponding mesh, then the mesh is added to the meshcollider.
                mesh = meshGen.GenerateMeshFromWorldPoint(p0, p1, p2, p3);                
                GetComponent<MeshCollider>().sharedMesh = mesh;
                GetComponent<MeshCollider>().convex = true;
                GetComponent<MeshCollider>().enabled = true;
            }
        }`

Here is the class meshGen that generates the mesh:

`public class MeshGen
{
    Vector3[] _vertices;
    int[] _triangles;

    public Mesh GenerateMeshFromWorldPoint(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3)
    {        
        _vertices = new Vector3[]
        {
            p0, p1, p2, p3
        };
        _triangles = new int[]
        {
            0, 1, 2, 0, 3, 1
        };
        Mesh mesh = new Mesh();
        mesh.name = "Custom Mesh Collider";
        mesh.vertices = _vertices;
        mesh.triangles = _triangles;
        return mesh;
    }
}`

Now here's the problem:

As you can see in the middle panel, the selection box is there but the mesh of the meshcollider appears as a 3D box, not a plane with 4 vertices as intended. We can even see in the left panel that the meshcollider actually contains my custom mesh As you can see in the middle panel, the selection box is there but the mesh of the meshcollider appears as a 3D box, not a plane with 4 vertices as intended. We can even see in the left panel that the meshcollider actually contains my custom mesh.

Even more confusing is when I double click on the "custom mesh collider" in the inspector:

We can actually see (in the bottom left corner) the intended mesh, created by my custom class meshGen! We can actually see (in the bottom left corner) the intended mesh, created by my custom class meshGen!

So both my script seems to be functional but I'm clearly missing something here, if you guys have any insight please help me out! Also, I'm pretty new to the stackoverflow thingy and I have no idea if I'm doing it right so let me know if some basic info is missing from my post. Thanks!

What I tried: I tried to generate a plane mesh from four Vector3 derived from a box on the screen so the plane overlap perfectly the UI box, in world space.

What I expected: a meshCollider made of a custom mesh plane with four vertices and 2 triangles.

What actually resulted: although the mesh generation is a success and is properly put into the meshCollider, the meshCollider shows as a box with 8 vertices and whatever amount of triangles (not two though).

MathMith
  • 39
  • 7

2 Answers2

0

Ok I found the issue. If anyone comes across this problem in the future, make sure the Vector3 are all global coordinate and NOT local to the gameObject hosting the script... In my case, all Vector3 p0, p1, p2 and p3 were converted with transform.TransformPoint(Vector3).

MathMith
  • 39
  • 7
  • If your object is at `0,0,0`, unscaled and not rotated than you could save a lot of work as he local and world space would be aligned ;) – derHugo Nov 08 '22 at 07:38
  • It was indeed, a lot of trouble. Even when I fixed the problem mentioned in the post, an army of errors popped up saying my mesh was invalid and complaining about other stuff as well. So a scrap the whole approach. Since my game use an orthographic cam, I went for a box overlap instead, it worked first try with no errors, I can also share the code if anyone is interrested in the future. – MathMith Nov 09 '22 at 12:17
  • is also way cheaper to compute ;) – derHugo Nov 09 '22 at 12:43
0

I had a similar problem with custom mesh collider when it was turning in something like box collider. The problem was solved by disabling convex in Mesh Collider and enable "Is Kinematic" in Rigidbody component. So collisions began to read correctly.