Моей целью было создать большой невидимый куб и внутри него создавать маленькие случайные кубики.
Эти маленькие кубики будут иметь:
- Случайная позиция в большом кубе.
- Случайный цвет.
- Случайный размер.
- Случайная жизнь.
- Более высокий шанс появления со смещением 0 по оси Y, чем с любым другим смещением.
- Возможность вращаться синхронно с большим кубом.
- Способность исчезать с возрастом.
- Заменяется новыми случайными кубиками по мере их истечения.
Вот код, который я написал для этого:
SpawnCube.cs
public GameObject smallCubePrefab;
public float rateOfSpawn = 1;
private float nextSpawn = 0;
// Update is called once per frame
void Update()
{
// Spawn new cubes at specified spawn rate
if (Time.time > nextSpawn)
{
nextSpawn = Time.time + rateOfSpawn;
StartCoroutine(FadeOutCube());
}
}
public List<GameObject> SpawnSmallCubes()
{
// Create an empty list of cubes
List<GameObject> cubesList = new List<GameObject>();
// Spawn cube at random position within the big cube's transform position
Vector3 randPosition = new Vector3(Random.Range(-1f, 1f), 0, Random.Range(-1f, 1f));
// Generate higher chance (2 chances in 3) of spawning small cubes with offset = 0 on Y-axis
List<float> randomY = new List<float>() {0, 0, Random.Range(-1f, 1f)};
randPosition.y = randomY[Random.Range(0, 3)];
randPosition = transform.TransformPoint(randPosition * .5f);
// Spawn small cube
GameObject smallCube = Instantiate(smallCubePrefab, randPosition, transform.rotation);
// Give random color
smallCube.GetComponent<Renderer>().material.color = Random.ColorHSV(0f, 1f, 1f, 1f, 0.5f, 1f);
// Give random size
int randSize = Random.Range(1, 10);
smallCube.transform.localScale = new Vector3(randSize, randSize, randSize);
// Add spawned cube to the list of cubes
cubesList.Add(smallCube);
return cubesList;
}
public IEnumerator FadeOutCube()
{
// Give random lifetime
float fadeSpeed = Random.Range(0.01f, 0.05f);
List<GameObject> smallCubes = SpawnSmallCubes();
foreach (GameObject cube in smallCubes.ToArray())
{
while (cube.GetComponent<Renderer>().material.color.a > 0)
{
Color cubeColor = cube.GetComponent<Renderer>().material.color;
float fadeAmount = cubeColor.a - (fadeSpeed * Time.deltaTime);
cubeColor = new Color(cubeColor.r, cubeColor.g, cubeColor.b, fadeAmount);
cube.GetComponent<Renderer>().material.color = cubeColor;
yield return null;
}
if(cube.GetComponent<Renderer>().material.color.a <= 0)
{
Destroy(cube);
smallCubes.Remove(cube);
}
}
}
Rotate.cs
public Vector3 rotationSpeed;
// Update is called once per frame
void Update()
{
transform.Rotate(rotationSpeed * Time.deltaTime);
}
Есть предложения по улучшению или изменениям, чтобы сделать его лучше?
благодаря
2 ответа
- Почему
SpawnSmallCubes()
создать только один куб? if(cube.GetComponent<Renderer>().material.color.a <= 0)
эта строка не нужнаGetComponent()
количество вызовов можно уменьшить, удерживая экземпляр Renderer, если вы не меняете его местамиsmallCubes.ToArray()
преобразование не требуетсяFadeOutCube()
также порождает кубики. Это не очевидно из наименования
Вам следует разбить свои генераторы случайных чисел на их собственные объекты и использовать Next()
метод.
// Spawn cube at random position within the big cube's transform position Vector3 randPosition = new Vector3(Random.Range(-1f, 1f), 0, Random.Range(-1f, 1f));
Тогда становится что-то вроде этого
var randomVectorValue = new Random.Range(-1f, 1f);
var randPosition = new Vector3(randomVectorValue.Next(), 0, randomVectorValue.Next())
имейте в виду, что я не использую среду IDE для написания этого кода, поэтому синтаксис может немного отличаться
Выполнение этого подобного действия делает значения генератора случайных чисел более удобными в обслуживании. Что, если бы вы вычисляли случайные числа для нескольких вещей с одним и тем же диапазоном, вы бы не захотели проходить весь код и изменять его каждый раз, когда это будет проще поменять в одном месте, в этом случае было бы randomVectorValue
(маловероятно, из-за того, как работают векторы, но если бы это было для чего-то другого, у которого был диапазон 1-10, и вы хотели бы изменить его на 5-25 …)
SpawnSmallCubes()
генерирует один куб, поскольку в настоящее время я создаю кубы с указанной скоростью появления вUpdate
как видите. Однако, если бы я убрал частоту появления, кубики просто появлялись бы с большой скоростью. Я думал, что могу изменить это так, чтобы, например, одновременно появлялось 5 случайных кубов, а затем, когда эти 5 кубиков исчезли, я создал еще 5, и это продолжало бы повторяться … Не знаю, как это сделать хотя.— AaySquare
Я делаю
smallCubes.ToArray()
преобразование, потому что, если я этого не сделаю, Unity выдает ошибку «Коллекция была изменена; операция перечисления может не выполняться». вforeach (GameObject cube in smallCubes)
вFadeOutCube()
функция.— AaySquare
smallCubes.Remove(cube);
не требуется, так как вы все равно перебираете список только один раз— Тед Браунлоу
Я понимаю. Итак о
SpawnSmallCubes()
, как бы вы порекомендовали мне сделать такое изменение, чтобы в начале появлялось 5 случайных кубиков, а не только один. И когда все они истекают, должен появиться еще один набор из 5 случайных кубиков.— AaySquare
Вы уже используете список, поэтому поместите 5 элементов в список с
for
петля должна работать— Тед Браунлоу