126 lines
4.3 KiB
C#
126 lines
4.3 KiB
C#
using System.Collections.Generic;
|
||
using UnityEngine;
|
||
|
||
public class SpawnRandomObjectsScript : MonoBehaviour
|
||
{
|
||
[SerializeField] private List<GameObject> _Prefabs = new List<GameObject>();
|
||
[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<Point> points = new List<Point>();
|
||
|
||
|
||
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<GameObject>(_Prefabs);
|
||
|
||
|
||
// Случайный поворот только по оси Y
|
||
Quaternion randomRotation = Quaternion.Euler(
|
||
0f, // угол по оси X
|
||
Random.Range(0f, 360f), // случайный угол по оси Y
|
||
0f // угол по оси Z
|
||
);
|
||
|
||
// Инстанцируем объект с случайным поворотом
|
||
Instantiate(prefab, point.Position, randomRotation);
|
||
}
|
||
|
||
}
|
||
|
||
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<T>(List<T> list)
|
||
{
|
||
// проверка на пустоту списка
|
||
if (list == null || list.Count == 0)
|
||
{
|
||
return default;
|
||
}
|
||
|
||
// Генерация случайного индекса
|
||
int randomIndex = UnityEngine.Random.Range(0, list.Count);
|
||
return list[randomIndex];
|
||
}
|
||
}
|