using System.Collections.Generic; using UnityEngine; public class SpawnRandomObjectsScript : MonoBehaviour { [SerializeField] private List _Prefabs = new List(); [SerializeField] private Vector3 _SpawnArea; [SerializeField] private float fixedDistance = 1f; // фиксированное расстояние между точками private float MinX; // минимальная координата X private float MaxX; // максимальная координата X private float MinZ; // минимальная координата Z private float MaxZ; // максимальная координата Z private float Y; // кол-во повторных проходов [SerializeField] private int NumOfRep = 1; // Структура Point теперь на плоскости X-Z // Структура Point теперь на плоскости X-Z public struct Point { public Vector3 Position; // позиция точки public Point(float x, float y, float z) { Position = new Vector3(x, y, z); // плоскость 2D, Y-координата всегда 0 } public float DistanceTo(Point other) { return Vector3.Distance(Position, other.Position); // возвращаем расстояние между точками } } private List points = new List(); void Start() { MinX = -_SpawnArea.x / 2 + transform.position.x; MaxX = _SpawnArea.x / 2 + transform.position.x; MinZ = -_SpawnArea.z / 2 + transform.position.z; MaxZ = _SpawnArea.z / 2 + transform.position.z; Y = -_SpawnArea.y / 2 + transform.position.y; GeneratePoints(); foreach (var point in points) { GameObject prefab = GetRandomObject(_Prefabs); // Случайный поворот только по оси Y Quaternion randomRotation = Quaternion.Euler( 0f, // угол по оси X Random.Range(0f, 360f), // случайный угол по оси Y 0f // угол по оси Z ); // Инстанцируем объект с случайным поворотом Transform child = Instantiate(prefab, point.Position, randomRotation).transform; child.SetParent(transform); } } public void GeneratePoints() { // Размещение первой точки случайным образом в указанном диапазоне points.Add(new Point(Random.Range(MinX, MaxX), Y, Random.Range(MinZ, MaxZ))); for (int i = 0; i < NumOfRep; i++) { bool canAddPoint = true; while (canAddPoint) { canAddPoint = false; // Пробуем случайно разместить следующую точку в пределах нового диапазона float newX = Random.Range(MinX, MaxX); float newZ = Random.Range(MinZ, MaxZ); Point newPoint = new Point(newX, Y, newZ); bool valid = true; foreach (var point in points) { if (newPoint.DistanceTo(point) < fixedDistance) // фиксированное расстояние { valid = false; break; } } // Если точка валидна (удовлетворяет условиям), добавляем её if (valid) { points.Add(newPoint); canAddPoint = true; } } } } void OnDrawGizmos() { // Устанавливаем цвет Gizmos Gizmos.color = Color.red; // Рисуем сферу Gizmos.DrawWireCube(transform.position, _SpawnArea); } T GetRandomObject(List list) { // проверка на пустоту списка if (list == null || list.Count == 0) { return default; } // Генерация случайного индекса int randomIndex = UnityEngine.Random.Range(0, list.Count); return list[randomIndex]; } }