生成立方体球

时间:2019-05-13 19:09:31

标签: c# visual-studio unity3d 3d

我是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 个答案:

答案 0 :(得分:2)

定义一个点(Vector3)为中心。我们叫 c

将距离(浮点数)定义为半径的长度。称为 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 个立方体。您可以轻松评估每个多维数据集的位置:

假设半径为 r 的周长1为2πr/ L = 3,所以我们有3个立方体:

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

很显然,您定义的 L 越小,多维数据集就会越多,并且外观越好。

答案 1 :(得分:1)

从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

让我知道是否有帮助。

答案 2 :(得分:1)

使用其他答案中提供的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);
}