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 = 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;
}
}