- Home /
generated box mesh collision causing convex hull init/computation failed error
I have been following a series of rts tutorials, currently up to 45 out of 81, the error started happening on the 41st video and was not resolved by the end of that series, perhaps an update to unity changed the way this works because the tutorial maker did not seem to have a problem. Here is that 41st vid, incase it helps someone to understand my issue. Unity - All About Trigger Events + Example
It deals with generating a mesh and applying it to the camera, moving the vertices and using the mesh collision to aid in detecting units selected with the mouse.
It works great until the error comes up, If I continue to play past the error it still works, however sometimes the framerate drops from over 1000 to about 4.
ConvexMesh::loadConvexHull: convex hull init failed!
createHull: convex hull computation failed!
those are the two errors that keep popping up, I can't understand why.. it is nowhere near 255 tris.
the errors refer to three lines of code right at the end of the UpdateDragBoxMesh function, each line getting both errors... but all the code does what it is supposed too, the errors are spread out and seem random
these are the lines.
meshc.sharedMesh = mesh;
DragSelectMesh.transform.Translate(0.1f, 0, 0);
DragSelectMesh.transform.Translate(-0.1f, 0, 0);
UpdateDragBoxMesh is being called from LateUpdate when I'm performing a mouse drag.
I'm not sure how much of the script I should put here, since these are pretty big I will just include the updatebox and createbox functions.... Basically I'm just hoping someone will be able to spot why this is giving me such a headache at the moment.
********************************
public void UpdateDragBoxMesh() { MeshCollider meshc = DragSelectMesh.GetComponent(); meshc.sharedMesh = null;
Vector2 p0Ratio = new Vector2(boxFinish.x / (Screen.width * 0.01f) * 0.01f, (boxFinish.y + Mathf.Abs(boxHeight)) / (Screen.height * 0.01f) * 0.01f);
Vector2 p1Ratio = new Vector2(boxStart.x / (Screen.width * 0.01f) * 0.01f, boxStart.y / (Screen.height * 0.01f) * 0.01f);
Vector2 p2Ratio = new Vector2(boxStart.x / (Screen.width * 0.01f) * 0.01f, (boxStart.y - Mathf.Abs (boxHeight)) / (Screen.height * 0.01f) * 0.01f);
Vector2 p3Ratio = new Vector2(boxFinish.x / (Screen.width * 0.01f) * 0.01f, boxFinish.y / (Screen.height * 0.01f) * 0.01f);
ClipPlanePoints nearClipPlanePoints = CameraClipPlanePoints(Camera.main.nearClipPlane + 30f);
ClipPlanePoints farClipPlanePoints = CameraClipPlanePoints(DistanceFromCameraToGround());
float nearPlaneWidth = Vector3.Distance(nearClipPlanePoints.LowerLeft, nearClipPlanePoints.LowerRight);
float nearPlaneHeight = Vector3.Distance(nearClipPlanePoints.UpperRight, nearClipPlanePoints.LowerRight);
float farPlaneWidth = Vector3.Distance(farClipPlanePoints.LowerLeft, farClipPlanePoints.LowerRight);
float farPlaneHeight = Vector3.Distance(farClipPlanePoints.UpperRight, farClipPlanePoints.LowerRight);
Pointer.transform.position = nearClipPlanePoints.LowerLeft;
Pointer.transform.eulerAngles = Camera.main.transform.eulerAngles;
Pointer.transform.Translate(nearPlaneWidth * p0Ratio.x, nearPlaneHeight * p0Ratio.y, 0f);
Vector3 p0 = Pointer.transform.position;
Pointer.transform.position = nearClipPlanePoints.LowerLeft;
Pointer.transform.Translate(nearPlaneWidth * p1Ratio.x, nearPlaneHeight * p1Ratio.y, 0f);
Vector3 p1 = Pointer.transform.position;
Pointer.transform.position = nearClipPlanePoints.LowerLeft;
Pointer.transform.Translate(nearPlaneWidth * p2Ratio.x, nearPlaneHeight * p2Ratio.y, 0f);
Vector3 p2 = Pointer.transform.position;
Pointer.transform.position = nearClipPlanePoints.LowerLeft;
Pointer.transform.Translate(nearPlaneWidth * p3Ratio.x, nearPlaneHeight * p3Ratio.y, 0f);
Vector3 p3 = Pointer.transform.position;
Pointer.transform.position = farClipPlanePoints.LowerLeft;
Pointer.transform.Translate(farPlaneWidth * p0Ratio.x, farPlaneHeight * p0Ratio.y, 0f);
Vector3 p4 = Pointer.transform.position;
Pointer.transform.position = farClipPlanePoints.LowerLeft;
Pointer.transform.Translate(farPlaneWidth * p1Ratio.x, farPlaneHeight * p1Ratio.y, 0f);
Vector3 p5 = Pointer.transform.position;
Pointer.transform.position = farClipPlanePoints.LowerLeft;
Pointer.transform.Translate(farPlaneWidth * p2Ratio.x, farPlaneHeight * p2Ratio.y, 0f);
Vector3 p6 = Pointer.transform.position;
Pointer.transform.position = farClipPlanePoints.LowerLeft;
Pointer.transform.Translate(farPlaneWidth * p3Ratio.x, farPlaneHeight * p3Ratio.y, 0f);
Vector3 p7 = Pointer.transform.position;
Mesh mesh = DragSelectMesh.GetComponent<MeshFilter>().mesh;
Vector3[] vertices = new Vector3[]
{
// Bottom
p0, p1, p2, p3,
// Left
p7, p4, p0, p3,
// Front
p4, p5, p1, p0,
// Back
p6, p7, p3, p2,
// Right
p5, p6, p2, p1,
// Top
p7, p6, p5, p4
};
mesh.vertices = vertices;
meshc.sharedMesh = mesh;
DragSelectMesh.transform.Translate(0.1f, 0, 0);
DragSelectMesh.transform.Translate(-0.1f, 0, 0);
}
And here is the Create method
public void CreateDragBoxMesh()
{
DragSelectMesh = new GameObject();
DragSelectMesh.name = "DragSelectMesh";
DragSelectMesh.transform.position = Vector3.zero;
//MeshRenderer renderer = DragSelectMesh.AddComponent<MeshRenderer>();
//renderer.material = DragSelectMeshMat;
MeshFilter filter = DragSelectMesh.AddComponent<MeshFilter>();
Mesh mesh = filter.mesh;
mesh.Clear();
float length = 20f;
float width = 20f;
float height = 20f;
#region Vertices
Vector3 p0 = new Vector3( -length * .5f, -width * .5f, height * .5f );
Vector3 p1 = new Vector3( length * .5f, -width * .5f, height * .5f );
Vector3 p2 = new Vector3( length * .5f, -width * .5f, -height * .5f );
Vector3 p3 = new Vector3( -length * .5f, -width * .5f, -height * .5f );
Vector3 p4 = new Vector3( -length * .5f, width * .5f, height * .5f );
Vector3 p5 = new Vector3( length * .5f, width * .5f, height * .5f );
Vector3 p6 = new Vector3( length * .5f, width * .5f, -height * .5f );
Vector3 p7 = new Vector3( -length * .5f, width * .5f, -height * .5f );
Vector3[] vertices = new Vector3[]
{
// Bottom
p0, p1, p2, p3,
// Left
p7, p4, p0, p3,
// Front
p4, p5, p1, p0,
// Back
p6, p7, p3, p2,
// Right
p5, p6, p2, p1,
// Top
p7, p6, p5, p4
};
#endregion
#region Normals
Vector3 up = Vector3.up;
Vector3 down = Vector3.down;
Vector3 front = Vector3.forward;
Vector3 back = Vector3.back;
Vector3 left = Vector3.left;
Vector3 right = Vector3.right;
Vector3[] normals = new Vector3[]
{
// Bottom
down, down, down, down,
// Left
left, left, left, left,
// Front
front, front, front, front,
// Back
back, back, back, back,
// Right
right, right, right, right,
// Top
up, up, up, up
};
#endregion
#region UVs
Vector2 _00 = new Vector2( 0f, 0f );
Vector2 _10 = new Vector2( 1f, 0f );
Vector2 _01 = new Vector2( 0f, 1f );
Vector2 _11 = new Vector2( 1f, 1f );
Vector2[] uvs = new Vector2[]
{
// Bottom
_11, _01, _00, _10,
// Left
_11, _01, _00, _10,
// Front
_11, _01, _00, _10,
// Back
_11, _01, _00, _10,
// Right
_11, _01, _00, _10,
// Top
_11, _01, _00, _10,
};
#endregion
#region Triangles
int[] triangles = new int[]
{
// Bottom
3, 1, 0,
3, 2, 1,
// Left
3 + 4 * 1, 1 + 4 * 1, 0 + 4 * 1,
3 + 4 * 1, 2 + 4 * 1, 1 + 4 * 1,
// Front
3 + 4 * 2, 1 + 4 * 2, 0 + 4 * 2,
3 + 4 * 2, 2 + 4 * 2, 1 + 4 * 2,
// Back
3 + 4 * 3, 1 + 4 * 3, 0 + 4 * 3,
3 + 4 * 3, 2 + 4 * 3, 1 + 4 * 3,
// Right
3 + 4 * 4, 1 + 4 * 4, 0 + 4 * 4,
3 + 4 * 4, 2 + 4 * 4, 1 + 4 * 4,
// Top
3 + 4 * 5, 1 + 4 * 5, 0 + 4 * 5,
3 + 4 * 5, 2 + 4 * 5, 1 + 4 * 5,
};
#endregion
mesh.vertices = vertices;
mesh.normals = normals;
mesh.uv = uvs;
mesh.triangles = triangles;
mesh.RecalculateBounds();
mesh.Optimize();
DragSelectMesh.AddComponent<DragMeshTrigger>();
Rigidbody rigidbody = DragSelectMesh.AddComponent<Rigidbody>();
rigidbody.useGravity = false;
MeshCollider meshc = DragSelectMesh.AddComponent<MeshCollider>();
meshc.isTrigger = true;
meshc.convex = true;
meshc.sharedMesh = filter.mesh;
}
After a quick check, according to the video, lines 493-495 inclusive show the values of 50f, whereas you have set the values:
float length = 20f;
float width = 20f;
float height = 20f;
not sure if significant...?
Just tried 50f, 150f, 1f... no change, that just sets the size of the box when it is first created and is called at Start(), all that gets changed the in the UpdateDragBox$$anonymous$$esh() function.
Thank you very much for giving it a go :)
Although this is not exactly a 'fix' it does solve your problem ;) http://www.unitychatchannel.com/
I'm quite tempted to buy this myself for the save time
PS ClipPlanePoints nearClipPlanePoints = CameraClipPlanePoints(Camera.main.nearClipPlane + 30f); The video shows it without 30f - though I doubt this will have any impact
Can't be sure if buying the whole thing pre-made would solve the problem, there has been no activity from that guy on his youtube or website for months either.
as for the nearClipPlanePoints, the + 30f is nothing, the tutorials go back and forth changing code here and there.
the problem has something specifically to do with the convex collider, which is needed for the whole thing to work.
Answer by Bunny83 · Oct 15, 2014 at 01:37 AM
Well, first of all that's a horrible way to get the worldspace frustum of a selected screen rect. You actually just need Camera.ScreenToWorldPoint with each corner of your screen space box. Once with your near distance as z and once with your far distance as z.
Anyways your problem is simply a copy&past error. For each corner you used farClipPlanePoints.LowerLeft, so your mesh has effectively no size at all. The offending lines are 17, 23, 28, 33, 38, 43, 48 and 53.
ps:
Juat as a side note: changing a simple mesh at runtime actually works quite well in Unity, even complex meshes. However changing a meshcollider each Update can give you a huge performance hit since the physics system has to recreate the collider.
For performance it would be better to just use a fix mesh collider with the camera's view frustum so you get all objects within the view and then just iterate through them, convert their position into screen space (with Camera.WorldToScreenPoint) and just do a 2d Rect.Contains check with your selection rect. This of course behaves slightly different to the collider approach, since the colliders will get in touch before the objects pivot is inside the selection. This approach can be modified to use an approximate screen space bounds rect which you could do a simple intersection check (AABB).
Just trying to follow the tutorial for now, cleaning it up will come later :)
I don't think those lines are an issue, it is the same in the tutorial, here is the ClipPlanePoints function.
public ClipPlanePoints CameraClipPlanePoints(float Distance)
{
ClipPlanePoints clipPlanePoints = new ClipPlanePoints();
Transform transform = Camera.main.transform;
Vector3 pos = transform.position;
float halfFOV = (Camera.main.fieldOfView * 0.5f) * $$anonymous$$athf.Deg2Rad;
float aspect = Camera.main.aspect;
float height = $$anonymous$$athf.Tan (halfFOV) * Distance;
float width = height * aspect;
clipPlanePoints.LowerRight = pos + transform.forward * Distance;
clipPlanePoints.LowerRight += transform.right * width;
clipPlanePoints.LowerRight -= transform.up * height;
clipPlanePoints.LowerLeft = pos + transform.forward * Distance;
clipPlanePoints.LowerLeft -= transform.right * width;
clipPlanePoints.LowerLeft -= transform.up * height;
clipPlanePoints.UpperRight = pos + transform.forward * Distance;
clipPlanePoints.UpperRight += transform.right * width;
clipPlanePoints.UpperRight += transform.up * height;
clipPlanePoints.UpperLeft = pos + transform.forward * Distance;
clipPlanePoints.UpperLeft -= transform.right * width;
clipPlanePoints.UpperLeft += transform.up * height;
return clipPlanePoints;
}
I did however manage to figure out something, when opening the console, game window, and scene window all at once I was able to figure out the error is caused when the edges of the box intersect for instance when dragging a straight line down the screen, the box actually vanishes from the scene view and the error gets spammed constantly.... so, a step closer
Yes, you're right. It's hard to follow what actually happens. I'm not sure why he's doing the corner conversion in such a complicated manner since Unity provides all this out of the box.
Back to your problem. Unity can only calculate a convex hull if the mesh describes a volume > 0. So a $$anonymous$$esh that has no depth can't have a convex hull in Unity. Just try to insert a plane, attach a rigidbody to it and select convex, you will get the same error.
You have two options here: Either force a a $$anonymous$$ size of your box by adding / removing 0.1 to the height / width when it's 0, or prevent the mesh updating when the selection rect has a 0-height or 0-width.
Thank you!, I had thought that was done already in the code elsewhere, perhaps I need to go over that again in the tutorial.
for now I came up with a temp solution,
if (UserIsDragging)
{
bool update$$anonymous$$esh = false;
if (boxWidth > 0.1f && boxHeight > 0.1f && update$$anonymous$$esh == false)
{
update$$anonymous$$esh = true;
UpdateDragBox$$anonymous$$esh();
}
if (boxWidth < -0.1f && boxHeight < -0.1f && update$$anonymous$$esh == false)
{
update$$anonymous$$esh = true;
UpdateDragBox$$anonymous$$esh();
}
if (boxWidth > 0.1f && boxHeight < -0.1f && update$$anonymous$$esh == false)
{
update$$anonymous$$esh = true;
UpdateDragBox$$anonymous$$esh();
}
if (boxWidth < -0.1f && boxHeight > 0.1f && update$$anonymous$$esh == false)
{
update$$anonymous$$esh = true;
UpdateDragBox$$anonymous$$esh();
}
}
Thanks again :)
Your answer
![](https://koobas.hobune.stream/wayback/20220613165033im_/https://answers.unity.com/themes/thub/images/avi.jpg)