#はじめに
Unityでスクリプトからmeshを作って 対称性のあるオブジェクトを描画しようとしてみた備忘録
環境:Unity 2020.3.12f1
対称なものをつくる
Quaternionであらかじめ
軸に対して対称となる回転系を用意しておく。
これに、中心から少し離れた位置にある座標を掛けることで、球面上のどこかの点をとるようになる。
うまく内側の球と外側の球の大きさや角度を調整すると
多面体や星形多面体などの対称性のある形が現れるはず。
流れ
まず一つ
三角ポリゴンを描画し、
前後にミラーし、
上下にミラーし、
あと、X軸、Y軸に90度づつねじれた形に回転しつつ複製しています。
スクリプト
MakePolyhedron.cs
using System.Collections.Generic;
using UnityEngine;
public class MakePolyhedron : MonoBehaviour
{
// 3軸対象
readonly Quaternion[] _qs3S = {Quaternion.Euler(0, 0, 0), Quaternion.Euler(0, 90, 90), Quaternion.Euler(90, 0, 90)};
// 前後対象
readonly Quaternion[] _qfbs = {Quaternion.Euler(0, 0, 0), Quaternion.Euler(0, 180, 0)};
// 上下対象
readonly Quaternion[] _qtbts = {Quaternion.Euler(0, 0, 0), Quaternion.Euler(0, 0, 180)};
private readonly List<Vector3> _vertices = new List<Vector3>();
private Mesh _mesh;
private void Start()
{
GetComponent<Renderer>().material.SetColor("_Color",
new Color(Random.Range(0.25f, 0.85f), Random.Range(0.25f, 0.85f), Random.Range(0.25f, 0.85f)));
_mesh = new Mesh();
TriangleSetUp();
var meshFilter = GetComponent<MeshFilter>();
meshFilter.mesh = _mesh;
}
private void TriangleSetUp()
{
foreach (var qs3 in _qs3S)
{
foreach (var qfb in _qfbs)
{
foreach (var qtbt in _qtbts)
{
for (int i = 0; i < 3; i++)
{
// 頂点を用意
_vertices.Add(Quaternion.Euler(Random.Range(0, 45), Random.Range(0, 45), Random.Range(0, 45)) *
new Vector3(0, 1, 0));
}
}
}
}
// 頂点登録
_mesh.SetVertices(_vertices);
var triangles = new List<int>();
for (int i = 0; i < _vertices.Count; i++)
{
triangles.Add(i);
}
_mesh.SetTriangles(triangles, 0);
}
private void Update()
{
TriangleSeed(1 + Mathf.Sin(Time.timeSinceLevelLoad), 1, 45 + Mathf.Sin(Time.timeSinceLevelLoad) * 45);
_mesh.SetVertices(_vertices);
_mesh.RecalculateBounds();
_mesh.RecalculateNormals();
}
private void TriangleSeed(float l1, float l2, float fa)
{
var id = 0;
foreach (var qs3 in _qs3S)
{
foreach (var qfb in _qfbs)
{
foreach (var qtbt in _qtbts)
{
// 頂点を用意
_vertices[id++] = qtbt * qfb * qs3 * Quaternion.Euler(0, 0, 0) * new Vector3(0, l1, 0);
_vertices[id++] = qtbt * qfb * qs3 * Quaternion.Euler(90, fa, 0) * new Vector3(0, l2, 0);
_vertices[id++] = qtbt * qfb * qs3 * Quaternion.Euler(90, -fa, 0) * new Vector3(0, l2, 0);
}
}
}
}
}
Mesh描画のためのコンポーネント
MeshFilterとMeshRenererが必要なようです。
ちょっと複製の仕方を変えてみる
.cs
// 前後対象 -> 4回回転対称
readonly Quaternion[] _qfbs = {Quaternion.Euler(0, 0, 0), Quaternion.Euler(0, 90, 0), Quaternion.Euler(0, 180, 0), Quaternion.Euler(0, 270, 0)};