我是Unity的新手,我正在尝试通过实例化预制立方体中的对象来生成球体。对于初学者来说,这听起来像是一件容易的事-当然,我很讽刺-但我在https://docs.unity3d.com/Manual/InstantiatingPrefabs.html上找到了一个例子,除了它只是一个圆圈:
理想情况下,我希望生成器/代码也将多维数据集转换为它们并排放置(没有间距;或可配置的间距),并具有多行,以便它们形成一个实心球体。因此,我认为代码需要同时转换多维数据集的外表面和内表面。
这怎么办?这是圈子的代码:
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);
}
}
}
奖励问题:是否还可以弯曲预制件(如弯曲的屏幕),从而使预制件的表面真正光滑?
答案 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上的其中一个教程中找到了一个脚本。
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>();
}
}
让我知道是否有帮助。
答案 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);
}