- Home /
[SOLVED] Why is this procedurally generated mesh not colliding?
Solved, a mesh with working collision just needs to exist on the object before it is cleared and constructed.
The below script generates a quadrilateralized spherical cube with Perlin noise deformation. Currently, everything works except collision (and yes, I am actually applying the collider). Any idea why this isn't working?
using UnityEngine;
using System.Collections;
using LibNoise.Unity;
using LibNoise.Unity.Generator;
using LibNoise.Unity.Operator;
public class QuadSpherePlanetGeneration : MonoBehaviour {
private Vector3 dir;
public Vector3 pivot;
public int subdivisions = 1;
public float radius = 1f;
public Perlin noise = new Perlin();
void Start()
{
StartCoroutine(BuildPlanet());
}
// Use this for initialization
IEnumerator BuildPlanet () {
pivot = new Vector3(0,0,0);
//gameObject.AddComponent<MeshRenderer>();
MeshFilter filter = gameObject.AddComponent< MeshFilter >();
Mesh mesh = filter.mesh;
mesh.MarkDynamic();
MeshCollider collider = gameObject.AddComponent<MeshCollider>();
mesh.Clear();
int verts = 6 * (subdivisions+2)*(subdivisions+2);
#region Vertices
Vector3[] vertices = new Vector3[verts];
Vector3[] normales = new Vector3[verts];
Vector2[] uvs = new Vector2[verts];
Color32[] vColors = new Color32[verts];
int curVert = 0;
float offset;
Quaternion angle = new Quaternion();
//Color color = new Color();
Vector3[] points = new Vector3[verts];
offset = (float)1.0f/(subdivisions+1);
for(int c = 0; c < subdivisions+2; c++)
{
for(int v = 0; v < subdivisions+2; v++)
{
points[curVert] = new Vector3((float)offset*v*2.0f, 1.0f, (float)-offset*c*2.0f) - new Vector3((float)offset*(subdivisions+1), 0.0f, (float)-offset*(subdivisions+1));
curVert++;
}
}
int side = curVert;
int row = (int)Mathf.Sqrt((float)side);
curVert = 0;
int uv1 = 0;
int uv2 = 0;
for(int s = 0; s < 6; s++)
{
switch(s)
{
case 0:
//color = Color.white;
angle = Quaternion.Euler(0,0,0);
dir = Vector3.up;
uv1 = 0;
uv2 = 2;
break;
case 1:
//color = Color.red;
angle = Quaternion.Euler(180,-90,0);
dir = Vector3.down;
uv1 = 2;
uv2 = 0;
break;
case 2:
//color = Color.green;
angle = Quaternion.Euler(0,0,90);
dir = Vector3.left;
uv1 = 2;
uv2 = 1;
break;
case 3:
//color = Color.yellow;
angle = Quaternion.Euler(-90,0,0);
dir = Vector3.back;
uv1 = 0;
uv2 = 1;
break;
case 4:
//color = Color.blue;
angle = Quaternion.Euler(-90,0,-90);
dir = Vector3.right;
uv1 = 1;
uv2 = 2;
break;
case 5:
//color = Color.black;
angle = Quaternion.Euler(0,90,90);
dir = Vector3.forward;
uv1 = 1;
uv2 = 0;
break;
}
for(int g = 0; g < row; g++)
{
for(int q = row*g; q < row*(g+1); q++)
{
vertices[curVert] = angle*(points[q] - pivot)+pivot;
normales[curVert] = dir;
uvs[curVert] = new Vector2(vertices[curVert][uv1]*0.5f, vertices[curVert][uv2]*0.5f);
//Debug.DrawLine(vertices[curVert], vertices[curVert]+new Vector3(0.025f*dir.x, 0.025f*dir.y, 0.025f*dir.z), color, 60.0f);//RotatePointAroundPivot(point, new Vector3(0, 0, 0), dir);
//print(vertices[curVert]);
curVert++;
}
}
//print (curVert+1);
}
#endregion
#region Triangles
int[] triangles = new int[(subdivisions+1)*(subdivisions+1)*6*6];
int tr = 0;
int pat = 0;
//Side
for(int r = 0; r < 6; r++)
{
//Row
for(int n = 0; n < (subdivisions+1); n++)
{
//Collumn
for(int t = 0; t < (subdivisions+1); t++)
{
triangles[tr] = pat;
triangles[tr+1] = pat+subdivisions+3;
triangles[tr+2] = pat+subdivisions+2;
triangles[tr+3] = pat;
triangles[tr+4] = pat+1;
triangles[tr+5] = pat+subdivisions+3;
pat ++;
tr += 6;
}
pat++;
}
pat += subdivisions+2;
}
#endregion
for(int d = 0; d < verts; d++)
{
Vector3 pos = vertices[d].normalized;
vertices[d] = vertices[d].normalized*(float)(radius+noise.GetValue(pos.x, pos.y, pos.z)*10);
vColors[d] = new Color32((byte)Mathf.Clamp(128/radius/vertices[d].magnitude, 0f, 255f), (byte)Mathf.Clamp(128/radius/vertices[d].magnitude, 0f, 255f), (byte)Mathf.Clamp(128/radius/vertices[d].magnitude, 0f, 255f), (byte)1F);
}
mesh.vertices = vertices;
mesh.normals = normales;
mesh.uv = uvs;
mesh.triangles = triangles;
mesh.colors32 = vColors;
mesh.RecalculateNormals();
mesh.RecalculateBounds();
mesh.Optimize();
filter.mesh = mesh;
collider.sharedMesh = mesh;
//print (endTime-startTime);
yield return null;
}
}
Are you sure the mesh collider is recalculated after the construction of your mesh ?
I'm pretty sure it is - after all, I'm just setting it to be the mesh that is generated (and I have recalculated the bounds, as you can see. Unless this is not what you mean? Is there some recalculation step I'm missing?
I am not used to procedural mesh generation, but I suspect the following
$$anonymous$$eshCollider collider = gameObject.AddComponent();
to add a collider to your mesh while it is not constructed yet.
$$anonymous$$oreover, the $$anonymous$$esh.RecalculateBounds
only recalculate the bouding box of your mesh (see doc : http://docs.unity3d.com/ScriptReference/$$anonymous$$esh.RecalculateBounds.html) and not the collider.
Try to add your collider after you constructed your mesh.
Ooops, I didn't see the collider.shared$$anonymous$$esh = mesh;
to update the mesh collider.
Sorry, I can't do anything for you ... :\
EDIT : Are you sure your object or the objects which could collide with yours have a Rigidbody ??
Yes, they have been tested on other geometry and work just fine.
Does collision calculation change for an object depending on whether or not Static is checked?
Static game objects are not supposed to move, but in your case, I suppose you want to create a rock or something like that ?
I think that collisions detections don't $$anonymous$$d if your object is static or not (I can't certify)
Answer by Maxszkutron · Jun 18, 2015 at 07:33 AM
Try setting collider to be convex
collider.convex = true;
I cannot do this - the object is static and needs to have accurate collision with the player and other rigidbodies.
Answer by BluetoothBoy · Jun 18, 2015 at 03:20 PM
Solved! All I needed to do was have the mesh filter to first contain a mesh (I am just using the default sphere). It then clears that mesh and builds from there.
Your answer
Follow this Question
Related Questions
Correct position of overlapping meshes 0 Answers
Generated mesh collider on a generated mesh becomes a big box instead of taking mesh's shape 1 Answer
Scale collider independent of gameObject. 1 Answer
MeshCollider Failure at high velocities 0 Answers
How can I get the mesh that is represented by a convex collider? 0 Answers