Не удается проверить пересечение объекта по коллайдеру с другим объектом

Написал скрипт для генерации комнат и коридоров между ними, но бывает так, что ни пересекаются друг с другом, решил добавить проверку на пересечение с другой комнатой, и если она есть, то просто отмечать возможный выход комнаты как недоступный, что позволит не строить от него комнаты в дальнейшем, по итогу, попробовал разные варианты, но не один не дал того, что мне нужно.

Я решил повесить на префаб комнаты коллайдер, указать isTrigger = true, потом просто проверять через OverlapBox, он берет все коллайдеры, которые есть, поэтому по маске отсеиваю, чтобы взял только верхний коллайдер, который isTrigger = true (у меня на каждый тайл в комнате свой коллайдер, поэтому так).

Я попробовал убрать маску, по итогу у меня всегда одна комната, потому что он пересекается сам с собой, как я понял, я решил поменять проверку, чтобы не учитывать пересечения с дочерними коллайдерами префаба с помощью hits.Any(hit => hit.transform.root != newRoom.transform && hit.isTrigger);, но все равно проблему не решил

Текущий код скрипта:

using Assets.Scipts;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

public class LevelGenerator : MonoBehaviour
{
    public GameObject CrossRoomPrefab;
    public GameManager gameManager;
    public GameObject AltarRoomPrefab;
    public GameObject CorridorPrefab;
    public GameObject EmptyRoomPrefab;
    public GameObject WallExitPrefab;
    public GameObject Player;
    public int NumberOfRooms = 5;
    public int NumberOfAltarRooms = 2;
    private int AlreadyPickupedRunes = 0;
    public double RadiusToCheckExistingOfAltars = 15;
    public Vector3 StartPosition = Vector3.zero;
    public event Action AllRunesCollectedEvent;
    public event Action OneRuneCollectedEvent;

    private List<GameObject> placedRooms = new List<GameObject>();
    private List<RoomInfo> roomInfos = new List<RoomInfo>();
    public List<Vector3> AltarRoomPositions = new List<Vector3>();

    public void GenerateLevel()
    {
        GameObject startRoom = Instantiate(EmptyRoomPrefab, StartPosition, Quaternion.identity);
        placedRooms.Add(startRoom);
        roomInfos.Add(startRoom.GetComponent<RoomInfo>());
        PlaceEmptyRooms();
        PlaceAltarRooms();
        CloseFreeExists();
    }

    RoomInfo FindFirstRoomWithFreeExit()
    {
        for (int i = 0; i < roomInfos.Count; i++)
        {
            if (roomInfos[i].FreeExits.Count > 0)
            {
                return roomInfos[i];
            }
        }

        return null;
    }

    void OccupieExit(RoomInfo roomInfo, GameObject objectToOccupie)
    {
        roomInfo.OccupiedExits.Add(objectToOccupie);
        roomInfo.FreeExits.Remove(objectToOccupie);
    }

    Transform FindFarthestFreeExitFromPoint(Vector3 pos)
    {
        Transform farthestExit = null;
        float maxDistance = float.MinValue;

        for (int i = 0; i < roomInfos.Count; i++)
        {
            for (int j = 0; j < roomInfos[i].FreeExits.Count; j++)
            {
                Transform freeExitTransform = roomInfos[i].FreeExits[j].transform;
                float distance = Vector3.Distance(pos, freeExitTransform.position);
                if (distance > maxDistance && !IsPositionTooCloseToAltarRooms(freeExitTransform.position))
                {
                    maxDistance = distance;
                    farthestExit = roomInfos[i].FreeExits[j].transform;
                }
            }
        }

        return farthestExit;
    }

    bool IsPositionTooCloseToAltarRooms(Vector3 position)
    {
        foreach (Vector3 altarPosition in AltarRoomPositions)
        {
            if (Vector3.Distance(position, altarPosition) < RadiusToCheckExistingOfAltars)
            {
                return true;
            }
        }
        return false;
    }

    void PlaceEmptyRooms()
    {
        for (int i = 0; i < NumberOfRooms; i++)
        {

            Transform oldExit = FindFirstRandomRoomWithFreeExit();

            if (oldExit == null)
            {
                break;
            }

            Transform corridorExit;

            PlaceCorridor(oldExit, out corridorExit);

            GameObject newRoom = Instantiate(EmptyRoomPrefab);
            Transform newRoomEntrance = newRoom.GetComponent<RoomInfo>().FreeExits.First().transform;
            Quaternion roomRotation = Quaternion.FromToRotation(-newRoomEntrance.forward, corridorExit.forward);
            newRoom.transform.rotation = roomRotation;
            newRoom.transform.position = corridorExit.position - (newRoom.transform.rotation * newRoomEntrance.localPosition);

            BoxCollider roomCollider = newRoom.GetComponent<BoxCollider>();
            if (roomCollider != null)
            {
                Bounds bounds = roomCollider.bounds;
                Vector3 center = bounds.center;
                Vector3 halfExtents = bounds.extents;

                LayerMask collisionMask = LayerMask.GetMask("Room");
                Collider[] hits = Physics.OverlapBox(center, halfExtents, newRoom.transform.rotation, collisionMask);
                bool overlaps = hits.Any(hit => hit.transform.root != newRoom.transform && hit.isTrigger);

                if (overlaps)
                {
                    Destroy(newRoom);
                    OccupieExit(corridorExit.GetComponentInParent<RoomInfo>(), corridorExit.gameObject);
                    continue;
                }
            }

            RoomInfo newRoomInfo = newRoom.GetComponent<RoomInfo>();
            placedRooms.Add(newRoom);
            roomInfos.Add(newRoomInfo);
            OccupieExit(newRoomInfo, newRoomEntrance.gameObject);
            OccupieExit(corridorExit.GetComponentInParent<RoomInfo>(), corridorExit.gameObject);
        }
    }
    void PlaceAltarRooms()
    {
        for (int i = 0; i < NumberOfAltarRooms; i++)
        {
            Transform farthestExit = FindFarthestFreeExitFromPoint(Vector3.zero);

            if (farthestExit == null)
            {
                Debug.LogWarning("Нет доступных выходов для размещения комнаты с алтарём.");
                break;
            }

            Transform corridorExit;

            PlaceCorridor(farthestExit, out corridorExit);

            Transform newRoomEntrance = AltarRoomPrefab.GetComponent<RoomInfo>().FreeExits.First().transform;
            Quaternion rotationDifference = Quaternion.FromToRotation(-newRoomEntrance.forward, corridorExit.forward);
            Vector3 newPosition = corridorExit.position - (rotationDifference * newRoomEntrance.localPosition);

            GameObject newRoom = Instantiate(AltarRoomPrefab, newPosition, rotationDifference * AltarRoomPrefab.transform.rotation);
            RoomInfo newRoomInfo = newRoom.GetComponent<RoomInfo>();

            placedRooms.Add(newRoom);
            roomInfos.Add(newRoomInfo);
            AltarRoomPositions.Add(newPosition);
            //OccupieExit(newRoomInfo, newRoomEntrance.gameObject);
            OccupieExit(newRoomInfo, newRoom.GetComponent<RoomInfo>().FreeExits.First().transform.gameObject);
            OccupieExit(corridorExit.GetComponentInParent<RoomInfo>(), corridorExit.gameObject);
        }
    }

    void PlaceCorridor(Transform startPosition, out Transform otherExitFromCorridor)
    {
        GameObject corridor = Instantiate(CorridorPrefab);
        Transform corridorEntrance = corridor.GetComponent<RoomInfo>().FreeExits.First().transform;
        Quaternion corridorRotation = Quaternion.FromToRotation(-corridorEntrance.forward, startPosition.forward);
        corridor.transform.rotation = corridorRotation;
        corridor.transform.position = startPosition.position - (corridor.transform.rotation * corridorEntrance.localPosition);

        RoomInfo corridorInfo = corridor.GetComponent<RoomInfo>();
        placedRooms.Add(corridor);
        roomInfos.Add(corridorInfo);
        OccupieExit(corridorInfo, corridorEntrance.gameObject);
        OccupieExit(startPosition.GetComponentInParent<RoomInfo>(), startPosition.gameObject);

        Transform corridorExit = corridorInfo.FreeExits.First().transform;

        otherExitFromCorridor = corridorExit;
    }

    Transform FindFirstRandomRoomWithFreeExit()
    {
        List<GameObject> exits = new List<GameObject>();
        exits = roomInfos.Where(x => x.FreeExits.Count > 0).SelectMany(x => x.FreeExits).ToList();
        if (exits.Count != 0)
        {
            System.Random rnd = new System.Random();
            return exits.ElementAt(rnd.Next(exits.Count)).transform;
        }

        return null;
    }

    void CloseFreeExists()
    {
        List<GameObject> exits = new List<GameObject>();
        exits = roomInfos.Where(x => x.FreeExits.Count > 0).SelectMany(x => x.FreeExits).ToList();
        for (int i = 0; i < exits.Count; i++)
        {
            GameObject wall = Instantiate(WallExitPrefab);
            Quaternion wallRotation; //= Quaternion.FromToRotation(-wall.transform.forward, exits[i].transform.forward);
            wallRotation = Quaternion.LookRotation(-exits[i].transform.forward, Vector3.up);
            wall.transform.rotation = wallRotation;
            wall.transform.position = exits[i].transform.position;
            OccupieExit(exits[i].GetComponentInParent<RoomInfo>(), wall);
        }
    }
    void RuneWasPickuped()
    {
        AlreadyPickupedRunes++;
        OneRuneCollectedEvent?.Invoke();
        if (AlreadyPickupedRunes >= NumberOfAltarRooms)
        {
            AllRunesCollectedEvent?.Invoke();
        }
    }
    public void SubscribeOnPlayer(Movement movement)
    {
        movement.RunePickuped += RuneWasPickuped;
    }
}

Пример неудачной генерации 1

Префаб комнаты 2


Ответы (0 шт):