Last active
November 26, 2018 14:40
-
-
Save rngtm/0b6369ff2e7f8592729b2bd1cecc71a3 to your computer and use it in GitHub Desktop.
大量の球体をワンメッシュで作成し、ランダムな位置に並べるスクリプト。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
#if UNITY_EDITOR | |
using UnityEditor; | |
[CustomEditor(typeof(GenerateManySphere))] | |
public class GenerateManySphereInspector : Editor | |
{ | |
public override void OnInspectorGUI() | |
{ | |
base.OnInspectorGUI(); | |
var gs = target as GenerateManySphere; | |
EditorGUILayout.LabelField("VertexCount", (gs.SphereCount * gs.CountXZ * gs.CountY).ToString()); | |
} | |
} | |
#endif | |
[RequireComponent(typeof(MeshFilter))] | |
[RequireComponent(typeof(MeshRenderer))] | |
public class GenerateManySphere : MonoBehaviour | |
{ | |
[SerializeField] bool generateMeshOnUpdate = false; | |
[SerializeField] int sphereCount = 50; // 球体の個数 | |
[SerializeField] int yCount = 12; // Y軸を直径とする円の角度の分割数 | |
[SerializeField] int xzCount = 12; // XZ平面上での円の角度の分割数 | |
[SerializeField] float positionRandom = 8f; | |
[SerializeField] int randomSeed = 100; | |
[SerializeField] float sphereSize = 1f; | |
private Mesh mesh; | |
public int SphereCount => sphereCount; | |
public int CountY => yCount; | |
public int CountXZ => xzCount; | |
void Start() | |
{ | |
mesh = new Mesh(); | |
GetComponent<MeshFilter>().mesh = mesh; | |
Create(); | |
} | |
void Update() | |
{ | |
if (generateMeshOnUpdate) | |
{ | |
Create(); | |
} | |
} | |
void Create() | |
{ | |
if (yCount < 3) { yCount = 3; } | |
if (xzCount < 3) { xzCount = 3; } | |
Random.InitState(randomSeed); | |
int vertexCountXZ = xzCount + 1; | |
// 法線・頂点座標の作成 | |
Vector3[] vertices = new Vector3[sphereCount * vertexCountXZ * yCount]; //頂点座標 | |
Vector3[] normals = new Vector3[vertices.Length]; // 法線 | |
Vector2[] uv = new Vector2[vertices.Length]; | |
int vi = 0; | |
for (int si = 0; si < sphereCount; si++) | |
{ | |
Vector3 position = ( | |
new Vector3(Random.value, Random.value, Random.value) - Vector3.one / 2f | |
) * positionRandom; | |
for (int yi = 0; yi < yCount; yi++) | |
{ | |
float radian1 = yi * Mathf.PI / (yCount - 1) - Mathf.PI / 2f; | |
float y = Mathf.Sin(radian1); | |
for (int xi = 0; xi < vertexCountXZ; xi++) | |
{ | |
float radian2 = xi * 2f * Mathf.PI / xzCount; | |
float x = Mathf.Cos(radian1) * Mathf.Cos(radian2); | |
float z = Mathf.Cos(radian1) * Mathf.Sin(radian2); | |
uv[vi] = new Vector2((float)si / sphereCount, 0f); | |
normals[vi] = new Vector3(x, y, z); | |
vertices[vi++] = new Vector3(x, y, z) * sphereSize + position; | |
} | |
} | |
} | |
// 頂点インデックスの作成 | |
int[] triangles = new int[sphereCount * xzCount * (yCount - 1) * 6]; | |
int ti = 0; | |
int triangleOffset = 0; | |
for (int si = 0; si < sphereCount; si++) | |
{ | |
for (int i = 0; i < yCount - 1; i++) | |
{ | |
for (int j = 0; j < xzCount; j++) | |
{ | |
triangles[ti++] = triangleOffset + vertexCountXZ; // 2 | |
triangles[ti++] = triangleOffset + 1; // 1 | |
triangles[ti++] = triangleOffset + 0; // 0 | |
triangles[ti++] = triangleOffset + 1 + vertexCountXZ; // 3 | |
triangles[ti++] = triangleOffset + 1; // 1 | |
triangles[ti++] = triangleOffset + vertexCountXZ; // 2 | |
triangleOffset += 1; | |
} | |
triangleOffset += 1; | |
} | |
} | |
// メッシュ作成 | |
mesh.vertices = vertices; | |
mesh.triangles = triangles; | |
mesh.normals = normals; | |
mesh.uv = uv; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
大量の球体をワンメッシュで生成します。 頂点数が65536を超えると表示がおかしくなるので注意
