Hi everyone, I’m new to Unity and I’m trying to develop an application to manage a sort of a procedural 2D map that is interactable by clicking on it to create more rooms or add contents to them but i have encountered a problem:
I have a Sprite
for a Door that i have converted into a Prefab and gave it a BoxCollider2D
with IsTrigger = true
that is used as an interactable point to generate a new room and to set the connection point for the new room that is being created.
Then I have a set of Sprites that are Rooms that i have converted to Prefabs and added the Doors as childs of these Rooms prefabs, the Rooms have a PolygonCollider2D
set as IsTrigger = true
and a RigidBody2D
set as Kinematic
.
On the project settings, in the Physics Matrix i have set that the Rooms must collide only with Rooms and Doors must collide only with doors. The problem is that when I want to create a Room I would like to check if the Room, that I’m trying to create, fits in the place it should be placed and for doing so I looked out for a solution that is by using something like Physics2D.OverlapAreaAll()
or Room.GetComponent<Collider2D>().Cast()
to check if there are collisions with the newly created Room and if there are no collisions then there is enough space for the room and it can be safely created, instead i just destroy it. The problem is that when I try that, there are no collisions detected but adding a void OnTriggerEnter2D(Collider2D other)
to the Room makes the Room to trigger collisions with other rooms, I can’t wrap my head around it to figure out a solution, I’m attaching screenshots of the code, I hope someone can help. Thanks in advance to you all.
Method inside GameManager that instantiate a new Room and then checks if it fits by checking if the collider collides with others:
public Room InstantiateRoom(string roomId = null)
{
roomId ??= Room.GenerateRoomId();
var roomPrefab = MapPrefabs.RoomsPrefabs.First(room => room.GetComponent<Room>().Id == roomId);
var clickedDoor = LastClickable.Transform.GetComponent<Door>();
var createdRoom = Instantiate(roomPrefab, Vector3.zero, Quaternion.identity, MapContainer.transform);
PositionRoom(createdRoom, clickedDoor);
if (!IsRoomColliding(createdRoom))
{
return createdRoom.GetComponent<Room>();
}
Debug.LogError("Created room is colliding with other");
//Before destroying the gameobject, to give the engine the time to destroy it, i move it out of the camera
createdRoom.transform.Translate(new Vector3(0, 0, 999));
Destroy(createdRoom);
return null;
}
Checks if the Room fits by checking if the collider collides with others:
private static bool IsRoomColliding(GameObject room)
{
var roomCollider = room.GetComponent<Collider2D>();
// Get the bounds of the polygon collider
Bounds bounds = room.GetComponent<Collider2D>().bounds;
// Perform overlap check using the entire bounds
Collider2D[] overlapColliders = Physics2D.OverlapAreaAll(bounds.center, bounds.extents);
// Check if the overlap collider is not null (indicating a collision)
var isOverlapping = overlapColliders.Any(collider => collider != null && collider != roomCollider);
Debug.LogWarning(isOverlapping);
return isOverlapping;
}
UnityMessage inside Room class:
void OnTriggerEnter2D(Collider2D other)
{
IsTouchingOtherRoom = true;
Debug.Log("Is Triggering");
}
For now the game says that the Rooms always collide even if there is space.
Update:
I checked the values of the Room Collider2D.bounds
by debugging them and I noticed that the center
property has not the same value as when I check it from the inspector after the creation of the room, is like when after the instantiation and position of the Room prefab, the Collider2D
position is not updated inside the method but it is updated after the method is ended and that could explain why the casting of the box using the Physics2D.OverlapAreaAll()
method overlaps a Room that is positioned at 0,0,0
when it should not do it. But the question now may be: “Why does this happen? Is this the reason why it is not working?”