自分用メモ
半円柱のColliderとか作りたい時用。
これで作ったMeshをMeshColliderに設定してあげると、半円状のColliderを作れます。
境界条件などは厳密にテストしておらずバグが確実にあるので、使用する場合は自己責任で
using UnityEngine;
using System.Collections;
public class SemiCircularColumnMeshFactory{
// 360度の時の、円周の頂点数
const int MaxPerimeterVertexCount = 20;
/// <summary>
/// y軸方向の半円柱のMeshを生成する
/// </summary>
/// <returns>Mesh</returns>
/// <param name="angle">扇の角度</param>
/// <param name="height">半円柱の高さ</param>
public static Mesh CreateMesh(float angle,float height) {
if(angle < 0){
angle = -angle;
}
angle = angle % 360;
var perimeterVertexCount = (int)( (angle - 0.1f) / (360 / MaxPerimeterVertexCount)) + 2;
// 頂点計算
Vector3[] vertices = new Vector3[perimeterVertexCount * 2 + 2];
var halfHeight = height / 2;
var currentRadian = -angle / 2 * Mathf.Deg2Rad;
var deltaRadian = (360 / MaxPerimeterVertexCount)* Mathf.Deg2Rad;
vertices [0] = new Vector3 (0, halfHeight, 0);
vertices [perimeterVertexCount + 1] = new Vector3 (0, -halfHeight, 0);
for(int i = 1;i < perimeterVertexCount;i ++){
vertices[i] = new Vector3(Mathf.Sin(currentRadian) ,halfHeight,Mathf.Cos(currentRadian));
vertices[i + perimeterVertexCount + 1] = new Vector3(Mathf.Sin(currentRadian) ,-halfHeight,Mathf.Cos(currentRadian));
currentRadian += deltaRadian;
}
vertices[perimeterVertexCount] = new Vector3(Mathf.Sin(angle / 2 * Mathf.Deg2Rad) ,halfHeight,Mathf.Cos(angle / 2 * Mathf.Deg2Rad));
vertices[perimeterVertexCount * 2 + 1] = new Vector3(Mathf.Sin(angle / 2 * Mathf.Deg2Rad) ,-halfHeight,Mathf.Cos(angle / 2 * Mathf.Deg2Rad));
var pvc = perimeterVertexCount;
int fanCount = perimeterVertexCount - 1;
int offset;
int[] triangles = new int[ (fanCount * 4 + 4) * 3];
for (int i = 0; i < perimeterVertexCount - 1; i++) {
// 上面
triangles[i * 3] = 0;
triangles[i * 3 + 1] = i + 1;
triangles[i * 3 + 2] = i + 2;
// 底面
offset = fanCount * 3;
triangles[offset + i * 3] = pvc + 1;
triangles[offset + i * 3 + 1] = pvc + 1 + i + 2;
triangles[offset + i * 3 + 2] = pvc + 1 + i + 1;
// 円周面1
offset = fanCount * 3 * 2;
triangles[offset + i * 3] = i + 2;
triangles[offset + i * 3 + 1] = i + 1;
triangles[offset + i * 3 + 2] = pvc + 1 + i + 1;
// 円周面2
offset = fanCount * 3 * 3;
triangles[offset + i * 3] = i + 2;
triangles[offset + i * 3 + 1] = pvc + 1 + i + 1;
triangles[offset + i * 3 + 2] = pvc + 1 + i + 2;
}
// 側面
offset = fanCount * 3 * 4;
triangles [offset] = 1;
triangles [offset + 1] = 0;
triangles [offset + 2] = pvc + 1;
triangles [offset + 3] = 1;
triangles [offset + 4] = pvc + 1;
triangles [offset + 5] = pvc + 2;
triangles [offset + 6] = 0;
triangles [offset + 7] = pvc;
triangles [offset + 8] = pvc + 1;
triangles [offset + 9] = pvc + 1;
triangles [offset + 10] = pvc;
triangles [offset + 11] = pvc * 2 + 1;
Mesh mesh = new Mesh ();
mesh.name = "SemiCircleCylinder(" + angle + ")";
mesh.vertices = vertices;
mesh.triangles = triangles;
return mesh;
}
}