Создать сферу кубов - PullRequest
0 голосов
/ 13 мая 2019

Я новичок в Unity и пытаюсь создать сферу, создавая объекты из готового куба. Это может показаться легкой задачей для новичка - я, конечно, иронизирую - но я нашел пример на: https://docs.unity3d.com/Manual/InstantiatingPrefabs.html - за исключением того, что это всего лишь круг:

Circle of Cubes

В идеале, я бы хотел, чтобы генератор / код также преобразовывал кубы так, чтобы они располагались бок о бок (без пробелов или настраиваемых интервалов) и с несколькими строками, чтобы они образовывали сплошную сферу. Поэтому я считаю, что код должен преобразовывать как внешнюю, так и внутреннюю грани куба.

Как это можно сделать? Вот код для круга:

using UnityEngine;
public class CubeSphere : MonoBehaviour {
    // Instantiates prefabs in a circle formation
    public GameObject prefab;
    public int numberOfObjects = 4;
    public float radius = 5f;
    void Start() {
        for (int i = 0; i < numberOfObjects; i++) {
            float angle = i * Mathf.PI * 2 / numberOfObjects;
            float x = Mathf.Cos(angle) * radius;
            float z = Mathf.Sin(angle) * radius;
            Vector3 pos = transform.position + new Vector3(x, 0, z);
            float angleDegrees = -angle * Mathf.Rad2Deg;
            Quaternion rot = Quaternion.Euler(0, angleDegrees, 0);
            Instantiate(prefab, pos, rot);
        }
    }
}

Бонусный вопрос : Можно ли изогнуть префабы (например, изогнутый экран), в результате чего получается действительно гладкая сфера префабов?

Ответы [ 3 ]

2 голосов
/ 14 мая 2019

Определите точку (Vector3), которая будет центром.Давайте назовем c .

. Определите расстояние (float) как длину радиуса.Назовите это R .

Представьте себе вертикальную линию через c длиной 2R :

| \
|  )R
| /
c
| \
|  )R
| /

Сфераничего, кроме множества окружностей, расположенных один под другим:

      --|--        circunference 1
   -----|-----     circunference 2
 -------|-------   circunference 3
--------c--------  circunference 4
 -------|-------   circunference 5
   -----|-----     circunference 6
      --|--        circunference 7

Теперь вам нужно определить, сколько окружностей вы хотите иметь в своей сфере, чем больше у вас будет, тем лучше оно будет выглядеть (и тем тяжелеетоже).В этом примере мы используем 7 окружностей.У нас должна быть позиция (по оси Y) для каждого из них, ее легко оценить.

Как оценить радиус любой из этих окружностей?Давайте рассмотрим пример оценки радиуса окружности 1:

     .--|--                     .--|     by definition, we have this
   ---\-|-----                  |\ | h   height h (it is not c.y + R, 
 ------\|-------                | \|     is something below that)
--------c--------  =>           '--c    
 -------|-------                 x
   -----|-----     
      --|--        

Мы знаем, что cos(angle) = h / R, поэтому мы оцениваем угол как angle = arccos(h / R).

Радиус x должно быть R * sin(angle).


Последний шаг - это решить, сколько кубов вы должны создать в каждой окружности.Вы можете решить, основываясь на длине окружности (2πr).Вы можете просто предположить, что для некоторой длины L будет один куб, поэтому для любой длины 2πr должно быть 2πr / L кубов.Позиции каждого куба вы можете легко оценить:

Предположим, для окружности 1 радиуса r , 2πr / L = 3, поэтому у нас будет 3 куба:

 ^         _.----[2]                 ^
 |       .'         '.               |          [][][]    circunference 1
 |      /             \              |        [][][][][]
z|    [1]      c       |            y|      [][][][][][][]     ...
 |      \             /              |        [][][][][]
 |       '.         .'               |          [][][]    curcunference 7
 |         ''----[3]                 |
 |---------------------------->      |---------------------------->
               x                                  x

Очевидно, что чем меньше вы определяете L , тем больше будет кубиков и лучше будет выглядеть.

1 голос
/ 14 мая 2019

Используя VoxelTools.cs, предоставленный в другом ответе:

public void CreateSphere(int r, Vector3 center) {
    int r2 = r*r;
    for (int x = -r; x <= r; ++x)
        for (int y = -r; y <= r; ++y)
            for (int z = -r; z <= r; ++z)
                if (new Vector3(x,y,z).sqrMagnitude <= r2)
                    VoxelTools.MakeCube(center.x + x, center.y + y, center.z +z);
}
1 голос
/ 13 мая 2019

Нашел скрипт из одного из туториалов на youtube.

Скрипт: VoxelTools.cs

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class VoxelTools : MonoBehaviour
{

    private static GameObject cubePrefab;
    private static GameObject cubeContainer;
    private static int cubeCount = 0;
    private static List<GameObject> cubes;

    public static Color GetRandomColor()
    {
        float r = Random.Range(0f, 1f);
        float g = Random.Range(0f, 1f);
        float b = Random.Range(0f, 1f);

        //make grey/sludge colors less likely
        for (int i = 0; i < Random.Range(1, 3); i++)
            {
            if (Random.Range(0, 10) > 1)
            {
                int a = Random.Range(0, 3);
                if (a == 0)
                    r = 0;
                if (a == 1)
                    g = 0;
                if (a == 2)
                    b = 0;
            }
        }

        return new Color(r, g, b);
    }

    public static GameObject MakeCube(float x, float y, float z)
    {
        return MakeCube(x, y, z, Color.red, 1);
    }

    public static GameObject MakeCube(float x, float y, float z, Color color)
    {
        return MakeCube(x, y, z, color, 1);
    }

    public static GameObject MakeCube(float x, float y, float z, Color color, float size)
    {
        return MakeCube(new Vector3(x, y, z), color, size);
    }

    private static GameObject GetCubePrefab()
    {    
        if (cubePrefab == null)
            cubePrefab = Resources.Load("Cube") as GameObject;
        return cubePrefab;
    }

public static GameObject MakeCube(Vector3 position, Color color, float size)
{
    cubeCount++;
    if (cubeContainer == null)
    {
        cubeContainer = new GameObject("cube container");
        cubes = new List<GameObject>();
    }

    GameObject cube = Instantiate(GetCubePrefab()) as GameObject;
    cubes.Add(cube);
    cube.transform.position = position;
    cube.transform.parent = cubeContainer.transform;
    cube.name = "cube " + cubeCount;

    cube.GetComponent<Renderer>().material.color = color;
    cube.transform.localScale = new Vector3(size, size, size);

    return cube;
}

    public static void MakeAllCubesFall()
    {
        foreach (GameObject cube in cubes)
            if (cube.GetComponent<Rigidbody>() == null)
                cube.AddComponent<Rigidbody>();
    }
}

Результат:

enter image description here

Дайте мне знать, если это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...