LoginSignup
4
5

More than 5 years have passed since last update.

Unityで半円柱のMeshを生成するコード

Last updated at Posted at 2015-12-04

自分用メモ

半円柱の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;

	}



}

4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5