Каков наилучший способ равномерного распределения объектов для заполнения искривленного пространства в Unity 3D?
Я хотел бы заполнить это место для сидения в аудитории стульями (в редакторе) и сделать так, чтобы все они стояли перед одним и тем же центром (сценой). Затем я буду случайным образом заполнять стулья разными людьми (во время выполнения). После каждого запуска стулья должны оставаться такими же, но люди должны быть очищены, чтобы во время следующего запуска толпа выглядела иначе.
В настоящее время к зоне отдыха не прикреплен коллайдер, а также стулья и люди.
Я нашел этот код, который позаботился о вращении стульев, чтобы они были нацелены на одну и ту же точку фокусировки. Но мне все еще любопытно, есть ли лучшие способы сделать это.
//C# Example (LookAtPoint.cs)
using UnityEngine;
[ExecuteInEditMode]
public class LookAtPoint : MonoBehaviour
{
public Vector3 lookAtPoint = Vector3.zero;
void Update()
{
transform.LookAt(lookAtPoint);
}
}
Дополнительные скриншоты
1 ответ
Вы можете написать скрипт редактора, чтобы автоматически размещать их равномерно. В этом сценарии
Я не обрабатываю мировое и локальное / модельное пространство в следующем коде. Не забудьте сделать это, когда вам нужно.
Генерируйте параллельные лучи, которые идут от +y до -y в сетке. Размер патча этой сетки зависит от того, насколько большой ваш стул и сетка (искривленное пространство). Чтобы получить правильный размер патча. Возьмите ограничивающую рамку стула (A) и изогнутую пространственную сетку (B), а затем разделите их (B/A) и используйте результат в качестве размера патча.
Mesh chairMR;//Mesh of the chair Mesh audiMR;//Mesh of the auditorium var patchSizeX = audiMR.bounds.size.X; var patchSizeZ = audiMR.bounds.size.Z; var countX = audiMR.bounds.size.x / chairMR.bounds.size.x; var countZ = audiMR.bounds.size.z / chairMR.bounds.size.z;
Таким образом, количество лучей, которое вам нужно генерировать, составляет около
countX*countZ
, Размер патча(patchSizeX, patchSizeZ)
,Затем можно определить исходные точки лучей:
//Generate parallel rays that come form +y to -y. List<Ray> rays = new List<Ray>(countX*countZ); for(var i=0; i<countX; ++i) { var x = audiMR.bounds.min.x + i * sizeX + tolerance /*add some tolerance so the placed chairs not intersect each other when rotate them towards the stage*/; for(var i=0; i<countZ; ++i) { var z = audiMR.bounds.min.z + i * sizeZ + tolerance; var ray = new Ray(new Vector3(x, 10000, z), Vector3.down); //You can also call `Physics.Raycast` here too. } }
Получите зелья, чтобы разместить стулья
- временно прикрепите MeshCollider к вашей сетке
- передний луч,
Physics.Raycast
это (вы можете разместить некоторые препятствия в местах, где не будет стула. Установите специальный слой для этих препятствий.) - получить точку попадания и создать стул в точке попадания и повернуть его к сцене
Повторно используйте эти хитпоинты, чтобы размещать своих людей во время выполнения.
Преобразуйте каждый из них в модель / локальную точку пространства. И сохраните их в json или актив через сериализацию для последующего использования во время выполнения: размещайте людей случайным образом.