C#Tutorial 1.2-cons tructing a Fractial ②를 터치해 보십시오.

9279 단어 Unity
계속

6.Better Code For More Children


여기서 지금까지의 코드를 잠시 재평가한다.
객체의 Position 및 Rotation 섹션을 좀 더 알기 쉽게 설명합니다.
//子オブジェクトの方向を定義
private static Vector3[] childDirections = {
    Vector3.up,
    Vector3.right,
    Vector3.left
};

//子オブジェクトの向きを定義
private static Quaternion[] childOrientations = {
    Quaternion.identity,
    Quaternion.Euler(0f, 0f, -90f),
    Quaternion.Euler(0f, 0f, 90f)
};

//子オブジェクトの作成コルーチン
// 0.5sec毎にオブジェクトを作成
private IEnumerator CreateChildren () {
    for (int i = 0; i < childDirections.Length; i++) {
        yield return new WaitForSeconds(0.5f);
        new GameObject("Fractal Child").AddComponent<Fractal>().
            Initialize(this, i);
    }
}

// 子オブジェクトの初期化
private void Initialize (Fractal parent, int childIndex) {
    …
    transform.localPosition =
        childDirections[childIndex] * (0.5f + 0.5f * childScale);
    transform.localRotation = childOrientations[childIndex];
}
Vector 및 Quaternion을 순서대로 저장하여 사용하도록 변경합니다.이렇게 하면 그룹을 추가해서 대상을 추가할 수 있다.
그럼 다른 방향도 추가해 주세요.
private static Vector3[] childDirections = {
    Vector3.up,
    Vector3.right,
    Vector3.left,
    Vector3.forward,
    Vector3.back
};

private static Quaternion[] childOrientations = {
    Quaternion.identity,
    Quaternion.Euler(0f, 0f, -90f),
    Quaternion.Euler(0f, 0f, 90f),
    Quaternion.Euler(90f, 0f, 0f),
    Quaternion.Euler(-90f, 0f, 0f)
};
저번

7.Explosice Growth


그렇다면 지금 몇 명의 아이들이 있느냐
max depth=0 시근의 입방체는 1, 즉 f(0)=1
max depth=1 시 뿌리 외에 다섯 개의 자가 있고 f(1)=6
max depth=n을 공식 f(n)=5xf(n-1)+1으로 설정합니다
.
제작된 대상의 수는 16,311568139061953197656 증가했다.
유니티라면 4~5 정도가 좋다.더 많은 숫자를 추가하면 대상의 수가 너무 많아 처리가 매우 무거워진다.
현재 아이의 제작에 0.5초의 무게를 넣었기 때문에 규칙은 정확하게 분형되어 성장하고 있다.
랜덤이면 분형이 불규칙하게 자라 동작이 더 재미있다.
private IEnumerator CreateChildren () {
    for (int i = 0; i < childDirections.Length; i++) {
        yield return new WaitForSeconds(Random.Range(0.1f, 0.5f));
        new GameObject("Fractal Child").AddComponent<Fractal>().
            Initialize(this, i);
    }
}
Random.하위 객체를 작성하는 시간은 Range(0.1f, 0.5f)로서 0.1~0.5초 사이에 변경됩니다.

8.Adding Color


이 분형은 좀 수수하니 색칠을 해 보세요.
먼저 아이에게 색칠을 해서 노랗게 만들어야 한다.
이번에는 유닛 컬러.Lerp처럼 편리한 방법이 있기 때문에 이걸 사용하세요.
private void Start () {
    gameObject.AddComponent<MeshFilter>().mesh = mesh;
    gameObject.AddComponent<MeshRenderer>().material = material;
    GetComponent<MeshRenderer>().material.color =
        Color.Lerp(Color.white, Color.yellow, (float)depth / maxDepth);
    if (depth < maxDepth) {
        StartCoroutine(CreateChildren());
    }
}

Lerp(a, b, t)는 [0-1]의 범위 내에서 t를 취하고 1에 가까울수록 b의 값을 되돌려주고 0에 가까울수록 a의 값을 되돌려준다.
예를 들어 0.5팩을 붙이면 화이트와 옐로가 각각 절반을 차지한다.
이로써 depth의 값이 maxDepth에 가까울수록 색이 노랗게 변한다.
이러한 처리는 문제가 있어 여러 항목과 같은 재료를 대량으로 처리하여 부하를 줄였지만 반드시 완전히 같은 재료여야 하며 등가성 확인을 하지 않았다(매우 비싼 처리라고 쓰여 있다).
이번에는 같은 색을 사용해도 동적으로 제작된 재료의 등가성을 확인할 수 없어 대량 처리가 불가능하다는 것이다.
따라서 같은 등급의 cube에 적용되는 재료는 같은 재료를 사용하십시오.
Start에서는 Initialize Materials라고 하며 배열로 재료를 만듭니다.
private Material[] materials;

//階層の数だけマテリアルを定義
private void InitializeMaterials () {
    materials = new Material[maxDepth + 1];
    for (int i = 0; i <= maxDepth; i++) {
        materials[i] = new Material(material);
        materials[i].color =
            Color.Lerp(Color.white, Color.yellow, (float)i / maxDepth);
    }
}

private void Start () {
    if (materials == null) {
        InitializeMaterials();
    }
    gameObject.AddComponent<MeshFilter>().mesh = mesh;
    gameObject.AddComponent<MeshRenderer>().material = materials[depth];
    if (depth < maxDepth) {
        StartCoroutine(CreateChildren());
    }
}
상위 재료의 참조를 작성된 배열로 수정합니다.
private void Initialize (Fractal parent, int childIndex) {
    mesh = parent.mesh;
    materials = parent.materials;
    …
}
다음은 막내 아이의 색깔을 자홍색으로 만든다.
또 노란색의 변화를 이해하기 쉽게 하기 위해 수치를 2로 곱했다.
private void InitializeMaterials () {
    materials = new Material[maxDepth + 1];
    for (int i = 0; i <= maxDepth; i++) {
        float t = i / (maxDepth - 1f);
        t *= t;
        materials[i] = new Material(material);
        materials[i].color = Color.Lerp(Color.white, Color.yellow, t);
    }
    materials[maxDepth].color = Color.magenta;
}

다음 단계는 역시 흰색에서 파란색으로, 가장 어린 아이를 빨간색으로 바꾸는 배열을 아까 만든 배열과 함께 2차원 배열로 만든다.
만약 이 두 배열이 무작위로 선택된다면, 색을 선택하면, 시작할 때마다 색이 바뀐다.

(채도가 상당히 낮아 머티리얼 샤이니스를 높였다)

9.Randomizeing Meshes


그 전에 제작된 망상물은 형식(cube와 sphere)이니 무작위로 선택해 보세요.
자료에 등록된 mesh를 수조 형식으로 저장하고 mesh를 대입할 때 수조에서 무작위로 선택합니다.
public Mesh[] meshes;

private void Start () {
    if (materials == null) {
        InitializeMaterials();
    }
    gameObject.AddComponent<MeshFilter>().mesh =
        meshes[Random.Range(0, meshes.Length)];
    …
}

private void Initialize (Fractal parent, int childIndex) {
    meshes = parent.meshes;
    …
}
그런 다음 확장기에 Size를 추가하여 mesh를 할당합니다.

크기를 1로 설정하고 Element에서 Cube를 선택하면 이전과 같은 결과를 얻을 수 있습니다.
그림에서 보듯이 크기를 2로 설정하고 Element 1에서 Sphere를 선택할 때 50% 확률로 큐브와 Sphere를 제작한다.

10.Making the Fractal Irregular


9에서 랜덤으로 제작된 메시를 선택했지만, 이번에는 제작 여부를 랜덤으로 선정한다.
이렇게 하면 매번 실행할 때마다 완전히 다른 형태의 대상이 생길 수 있다.
[Range(0, 1)]public float spawnProbability;

private IEnumerator CreateChildren () {
    for (int i = 0; i < childDirections.Length; i++) {
        if (Random.value < spawnProbability) {
            yield return new WaitForSeconds(Random.Range(0.1f, 0.5f));
            new GameObject("Fractal Child").AddComponent<Fractal>().
                Initialize(this, i);
        }
    }
}

private void Initialize (Fractal parent, int childIndex) {
    …
    spawnProbability = parent.spawnProbability;
    …
}
Random.value는 0-1 범위 내에서 수치를 되돌려줍니다.
spawnProbablity 범위는 0-1이기 때문에 Range(0,1)를 사용하여 이 범위 내에서 수치를 조작할 수 있습니다.
spawn Probability는 자가 생성될 확률로 0의 경우 루트의 cube만 만들고, 1의 경우 이전과 마찬가지로 모두 자가 생성된다.
이번에는 spawn Probability를 0.7로 실행해 보려고 합니다.


11.Rotating the Fractal


그런 다음 객체를 회전합니다.
Update에 다음 코드만 추가하면 됩니다.
private void Update () {
    transform.Rotate(0f, 30f * Time.deltaTime, 0f);
}
delta Time과 이전 프레임의 시간차입니다.
따라서 프레임 단위가 아닌 시간 단위로 회전합니다.

지금 일정 속도로 회전하고 있습니다.나는 네가 이미 알고 있다고 생각한다. 다음에 무작위로 이것을 하자.
또한 최대 회전 속도는 Inspector를 통해 수행할 수 있습니다.
public float maxRotationSpeed;

private float rotationSpeed;

private void Start () {
    rotationSpeed = Random.Range(-maxRotationSpeed, maxRotationSpeed);
    …
}

private void Initialize (Fractal parent, int childIndex) {
    …
    maxRotationSpeed = parent.maxRotationSpeed;
    …
}

private void Update () {
    transform.Rotate(0f, rotationSpeed * Time.deltaTime, 0f);
}
여기에 루트의 대상도 회전시키기 위해 Start 내에서 초기화합니다.
이로써 각각 자신의 회전 속도를 가진 대상을 생성한다.

12.Addubg Nire Chaos


마지막으로 분형에 다른 방향의 회전을 가해 배열이 어지러운 회전을 시도해 본다.
public float maxTwist;

private void Start () {
    rotationSpeed = Random.Range(-maxRotationSpeed, maxRotationSpeed);
    transform.Rotate(Random.Range(-maxTwist, maxTwist), 0f, 0f);
    …
}

private void Initialize (Fractal parent, int childIndex) {
    …
    maxTwist = parent.maxTwist;
    …
}
내용은 기본적으로 11과 같고 이번에는 X축을 회전시켰다.
따라서 모든 대상은 무작위로 조작할 수 있다.
https://docs.unity3d.com/jp/540/ScriptReference/Time-deltaTime.html
왠지 흥미진진한 상대가 완성되었다.

좋은 웹페이지 즐겨찾기