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 шт):

Автор решения: KingPeas

Могу предположить что ваш генератор уровня создает уровни до того как вы подписываетесь на событие генерации. Из примеров кода вообще не ясно где вы запускаете генерацию, может она у вас в конструкторе стартует. Поскольку все делается в одном потоке, а вы ищете объект в сцене, то возможно уже генерация к этому моменту будет завершена до того как вы его получаете в скрипте.

Вынесите запуск генерации в отдельный метод и запускайте только после того как сделаете подписку в своем скрипте EnemySpawner.

Ну либо вариант, вы саму генерацию вообще забыли запустить)

→ Ссылка