This repository has been archived on 2024-11-16. You can view files and clone it, but cannot push or open issues or pull requests.

110 lines
3.1 KiB
C#
Raw Normal View History

2021-01-31 15:48:04 +08:00
using UnityEngine;
public class Fractal : MonoBehaviour
{
2021-01-31 16:25:50 +08:00
private struct FractalPart
{
public Vector3 direction;
public Quaternion rotation;
public Transform transform;
}
FractalPart[][] parts;
2021-01-31 15:48:04 +08:00
[SerializeField, Range(1, 8)]
int depth = 4;
2021-01-31 16:25:50 +08:00
[SerializeField]
Mesh mesh = default;
[SerializeField]
Material material = default;
static Vector3[] directions =
{
Vector3.up,
Vector3.right,
Vector3.left,
Vector3.forward,
Vector3.back
};
static Quaternion[] rotations =
2021-01-31 15:48:04 +08:00
{
2021-01-31 16:25:50 +08:00
Quaternion.identity,
Quaternion.Euler(0f, 0f, -90f),
Quaternion.Euler(0f, 0f, 90f),
Quaternion.Euler(90f, 0f, 0f),
Quaternion.Euler(-90f, 0f, 0f)
};
private FractalPart CreatePart(int levelIndex, int childIndex, float scale)
{
var go = new GameObject("Fractal Part L" + levelIndex + " C" + childIndex);
go.transform.localScale = scale * Vector3.one;
go.transform.SetParent(transform, false);
go.AddComponent<MeshFilter>().mesh = mesh;
go.AddComponent<MeshRenderer>().material = material;
return new FractalPart()
{
direction = directions[childIndex],
rotation = rotations[childIndex],
transform = go.transform
};
}
2021-01-31 15:48:04 +08:00
2021-01-31 16:25:50 +08:00
private void Awake()
{
parts = new FractalPart[depth][];
for (int i = 0, length = 1; i < parts.Length; i++, length *= 5)
2021-01-31 15:48:04 +08:00
{
2021-01-31 16:25:50 +08:00
parts[i] = new FractalPart[length];
2021-01-31 15:48:04 +08:00
}
2021-01-31 16:25:50 +08:00
var scale = 1f;
parts[0][0] = CreatePart(0, 0, scale);
for (int li = 1; li < parts.Length; li++)
{
scale *= 0.5f;
FractalPart[] levelParts = parts[li];
for (int fpi = 0; fpi < levelParts.Length; fpi += 5)
{
for (int ci = 0; ci < 5; ci++)
{
levelParts[fpi + ci] = CreatePart(li, ci, scale);
}
}
}
2021-01-31 15:48:04 +08:00
}
private void Update()
{
2021-01-31 16:25:50 +08:00
Quaternion deltaRotation = Quaternion.Euler(0f, 22.5f * Time.deltaTime, 0f);
2021-01-31 15:48:04 +08:00
2021-01-31 16:25:50 +08:00
FractalPart rootPart = parts[0][0];
rootPart.rotation *= deltaRotation;
rootPart.transform.localRotation = rootPart.rotation;
parts[0][0] = rootPart;
for (int li = 1; li < parts.Length; li++)
{
FractalPart[] parentParts = parts[li - 1];
FractalPart[] levelParts = parts[li];
for (int fpi = 0; fpi < levelParts.Length; fpi++)
{
var parentTransform = parentParts[fpi / 5].transform;
var part = levelParts[fpi];
part.rotation *= deltaRotation;
part.transform.rotation =
parentTransform.localRotation * part.rotation;
part.transform.localPosition =
parentTransform.localPosition +
parentTransform.localRotation *
(1.5f * part.transform.localScale.x * part.direction);
levelParts[fpi] = part;
}
}
2021-01-31 15:48:04 +08:00
}
}