Unity2D. Не появляются враги
Враги не появляются, но при это в консоли нет ошибок. Помогите пожалуйста
Скрипт появления врагов:
using System.Collections.Generic;
using UnityEngine;
public class EnemySpawner : MonoBehaviour
{
public GameObject enemyPrefab;
private PlayerRoomPlacer playerRoomPlacer;
public int maxEnemiesPerRoom = 3;
public int minEnemiesPerRoom = 1; // Минимально возможное количество врагов
private RoomFirstDungeonGenerator dungeonGenerator;
private void Start()
{
dungeonGenerator = FindObjectOfType<RoomFirstDungeonGenerator>();
playerRoomPlacer = FindObjectOfType<PlayerRoomPlacer>();
dungeonGenerator.OnRoomGenerated += SpawnEnemiesInRoom;
}
private void OnDisable()
{
dungeonGenerator.OnRoomGenerated -= SpawnEnemiesInRoom;
}
private void SpawnEnemiesInRoom(GameObject room)
{
// Проверяем, является ли текущая комната комнатой игрока
if (room == playerRoomPlacer.GetPlayerRoom())
{
return; // Пропускаем спавн врагов в комнате игрока
}
// Выбираем случайное количество врагов в пределах от минимального до максимального
int enemiesCount = Random.Range(minEnemiesPerRoom, maxEnemiesPerRoom + 1);
for (int i = 0; i < enemiesCount; i++)
{
// Генерируем случайную позицию спавна в пределах комнаты
Vector3 spawnPosition = room.transform.position;
spawnPosition.x += Random.Range(-1f, 1f);
spawnPosition.y += Random.Range(-1f, 1f);
GameObject enemy = Instantiate(enemyPrefab, spawnPosition, Quaternion.identity);
enemy.transform.SetParent(room.transform);
dungeonGenerator.enemies.Add(enemy);
}
}
}
Скрипт генерации подземелья:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Random = UnityEngine.Random;
public class RoomFirstDungeonGenerator : SimpleRandomWalkDungeonGenerator
{
[SerializeField]
private int minRoomWidth = 4, minRoomHeight = 4;
[SerializeField]
private int dungeonWidth = 20, dungeonHeight = 20;
[SerializeField]
[Range(0, 10)]
private int offset = 1;
[SerializeField]
private bool randomWalkRooms = false;
public delegate void RoomGeneratedDelegate(GameObject room);
public event RoomGeneratedDelegate OnRoomGenerated;
public List<GameObject> rooms = new List<GameObject>(); // Список сгенерированных комнат
public List<GameObject> enemies { get; private set; } // List to store spawned enemies
public bool HasGeneratedNewRoom { get; private set; } // Свойство, указывающее, была ли сгенерирована новая комната
protected override void RunProceduralGeneration()
{
CreateRooms();
}
private void CreateRooms()
{
enemies = new List<GameObject>(); // Инициализировать список enemies
var roomsList = ProceduralGenerationAlgorithms.BinarySpacePartitioning(new BoundsInt((Vector3Int)startPosition, new Vector3Int(dungeonWidth, dungeonHeight, 0)), minRoomWidth, minRoomHeight);
HashSet<Vector2Int> floor = new HashSet<Vector2Int>();
if (randomWalkRooms)
{
floor = CreateRoomsRandomly(roomsList);
}
else
{
floor = CreateSimpleRooms(roomsList);
}
List<Vector2Int> roomCenters = new List<Vector2Int>();
foreach (var room in roomsList)
{
GameObject roomObject = new GameObject("Room (" + rooms.Count + ")");
roomObject.transform.position = room.center;
rooms.Add(roomObject);
roomCenters.Add((Vector2Int)Vector3Int.RoundToInt(room.center));
OnRoomGenerated?.Invoke(roomObject);
}
HashSet<Vector2Int> corridors = ConnectRooms(roomCenters);
floor.UnionWith(corridors);
tilemapVisualizer.PaintFloorTiles(floor);
WallGenerator.CreateWalls(floor, tilemapVisualizer);
HasGeneratedNewRoom = true; // Устанавливаем флаг HasGeneratedNewRoom в true после генерации комнаты
}
private HashSet<Vector2Int> CreateRoomsRandomly(List<BoundsInt> roomsList)
{
HashSet<Vector2Int> floor = new HashSet<Vector2Int>();
for (int i = 0; i < roomsList.Count; i++)
{
var roomBounds = roomsList[i];
var roomCenter = new Vector2Int(Mathf.RoundToInt(roomBounds.center.x), Mathf.RoundToInt(roomBounds.center.y));
var roomFloor = RunRandomWalk(randomWalkParameters, roomCenter);
foreach (var position in roomFloor)
{
if(position.x >= (roomBounds.xMin + offset) && position.x <= (roomBounds.xMax - offset) && position.y >= (roomBounds.yMin - offset) && position.y <= (roomBounds.yMax - offset))
{
floor.Add(position);
}
}
}
return floor;
}
private HashSet<Vector2Int> ConnectRooms(List<Vector2Int> roomCenters)
{
HashSet<Vector2Int> corridors = new HashSet<Vector2Int>();
var currentRoomCenter = roomCenters[Random.Range(0, roomCenters.Count)];
roomCenters.Remove(currentRoomCenter);
while (roomCenters.Count > 0)
{
Vector2Int closest = FindClosestPointTo(currentRoomCenter, roomCenters);
roomCenters.Remove(closest);
HashSet<Vector2Int> newCorridor = CreateCorridor(currentRoomCenter, closest);
currentRoomCenter = closest;
corridors.UnionWith(newCorridor);
}
return corridors;
}
private HashSet<Vector2Int> CreateCorridor(Vector2Int currentRoomCenter, Vector2Int destination)
{
HashSet<Vector2Int> corridor = new HashSet<Vector2Int>();
var position = currentRoomCenter;
corridor.Add(position);
while (position.y != destination.y)
{
if(destination.y > position.y)
{
position += Vector2Int.up;
}
else if(destination.y < position.y)
{
position += Vector2Int.down;
}
corridor.Add(position);
}
while (position.x != destination.x)
{
if (destination.x > position.x)
{
position += Vector2Int.right;
}else if(destination.x < position.x)
{
position += Vector2Int.left;
}
corridor.Add(position);
}
return corridor;
}
private Vector2Int FindClosestPointTo(Vector2Int currentRoomCenter, List<Vector2Int> roomCenters)
{
Vector2Int closest = Vector2Int.zero;
float distance = float.MaxValue;
foreach (var position in roomCenters)
{
float currentDistance = Vector2.Distance(position, currentRoomCenter);
if(currentDistance < distance)
{
distance = currentDistance;
closest = position;
}
}
return closest;
}
private HashSet<Vector2Int> CreateSimpleRooms(List<BoundsInt> roomsList)
{
HashSet<Vector2Int> floor = new HashSet<Vector2Int>();
foreach (var room in roomsList)
{
for (int col = offset; col < room.size.x - offset; col++)
{
for (int row = offset; row < room.size.y - offset; row++)
{
Vector2Int position = (Vector2Int)room.min + new Vector2Int(col, row);
floor.Add(position);
}
}
}
return floor;
}
}
Скрипт перемещения врага в комнату подземелья:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class PlayerRoomPlacer : MonoBehaviour
{
private RoomFirstDungeonGenerator generator;
private Player player;
private bool hasPlacedPlayer = false;
void Start()
{
generator = FindObjectOfType<RoomFirstDungeonGenerator>();
player = FindObjectOfType<Player>();
}
void Update()
{
// Проверяем, была ли уже сгенерирована новая комната
if (generator.HasGeneratedNewRoom)
{
// Если да, то перемещаем игрока в центр комнаты
if (!hasPlacedPlayer)
{
TeleportPlayerToRoomCenter();
hasPlacedPlayer = true;
}
}
}
void TeleportPlayerToRoomCenter()
{
// Получаем первую комнату
GameObject room = generator.rooms[0];
// Помещаем игрока в центр комнаты
player.transform.position = room.transform.position;
}
public GameObject GetPlayerRoom()
{
if (generator != null)
{
return generator.rooms[0];
}
else
{
// Возвращаем null или какой-либо другой объект по умолчанию, если список пуст
return null;
}
}
}
Ответы (1 шт):
Могу предположить что ваш генератор уровня создает уровни до того как вы подписываетесь на событие генерации. Из примеров кода вообще не ясно где вы запускаете генерацию, может она у вас в конструкторе стартует. Поскольку все делается в одном потоке, а вы ищете объект в сцене, то возможно уже генерация к этому моменту будет завершена до того как вы его получаете в скрипте.
Вынесите запуск генерации в отдельный метод и запускайте только после того как сделаете подписку в своем скрипте EnemySpawner
.
Ну либо вариант, вы саму генерацию вообще забыли запустить)