OndrejNepozitek / Edgar-Unity

Unity Procedural Level Generator
https://ondrejnepozitek.github.io/Edgar-Unity/docs/introduction
MIT License
817 stars 70 forks source link

Generator does not appear to work for dungeons that require a collider on floor #42

Closed farazk86 closed 4 years ago

farazk86 commented 4 years ago

Hi,

I have a player and some enemies that are required to jump. For this the floor component is required to have a collider.

I managed to simply add this in script by adding the following function to DungeonTilemapLayersHandler:

protected void AddFloorCollider(GameObject gameObject)
        {
            var tilemapCollider2D = gameObject.AddComponent<TilemapCollider2D>();
            tilemapCollider2D.usedByComposite = true;
            var compCollider2D = gameObject.AddComponent<CompositeCollider2D>();
            compCollider2D.geometryType = CompositeCollider2D.GeometryType.Polygons;
            gameObject.GetComponent<Rigidbody2D>().bodyType = RigidbodyType2D.Static;
        }

But from how the dungeon is stitched together I believe this is a problem for me, as the dungeon appears to work visually but the floor colliders prevent the player from leaving the room. As can be seen from the screenshot below:

floor_problem2

As can be seen, rather than a continuous collider across the entire floor we have individual floor colliders on each room template and when stitched together block the movement of the player.

Furthermore, this is a problem with instantiating enemies players in post-process as well, as the player prefab is considered part of the template and the collider is drawn on top of the player preventing its movement.

collider drawn on top of player preventing its movement discussed here The above screenshot shows this, when moved the knight very slowly moves along the polygon collider drawn on top of floor :(

Is there any way I can get around this problem?

Thanks

OndrejNepozitek commented 4 years ago

Hey! Why do you need to have a collider across the whole floor? It seems to me that spawning a player inside a collider which collides with the player should make the player stuck. So why do you need the collider for your jumping setup?

As can be seen, rather than a continuous collider across the entire floor we have individual floor colliders on each room template and when stitched together block the movement of the player.

I think this is not true. If you use the Polygons GeometryType, Unity tries to decompose the whole collider area into simpler polygons (I'm no expert but it seems like what's happening) and therefore it may look like there are separate colliders but it's just the visualization of the individual colliders that form the whole collider. Moreover, there is a "Disable Room Template Colliders" post process task (which is enabled by default) that makes sure that all the colliders from individual room templates are disabled and only the colliders for the whole level are used.

So from the description of your problem, it seems to me like the problem is caused by incorrect setup of the colliders in your game rather than by the generator. But I may be mistaken.

farazk86 commented 4 years ago

Thanks for replying @OndrejNepozitek .

Why do you need to have a collider across the whole floor? It seems to me that spawning a player inside a collider which collides with the player should make the player stuck. So why do you need the collider for your jumping setup?

I'm using a top down framework that required the floor to have a collider on it. And you may be correct with the players/enemies being stuck behind a collider, as can be seen below, when the tilemap collider was added but not composite: 2233

Moreover, there is a "Disable Room Template Colliders" post process task (which is enabled by default) that makes sure that all the colliders from individual room templates are disabled and only the colliders for the whole level are used.

Well that should fix this but I still cant seem to leave the room and am blocked by the corridor collider. Below is a screenshot from my setup. The player knight can move freely in the large room but cannot leave because is blocked by the collider.

23234

??

OndrejNepozitek commented 4 years ago

The root game that holds the whole dungeon has a child called "Room template instances" and there are all the instantiated room templates as children. I'd recommend to find the room template that corresponds to the room template that blocks your path (either the current room or the corridor) and check which of the tilemaps/colliders are causing that (for example by trying to disable/remove individual components and see if it works or not). It should be quite simple to find the room template instance because if you click on it, you should be able to see which room template it is.

I'm using a top down framework that required the floor to have a collider on it. And you may be correct with the players/enemies being stuck behind a collider, as can be seen below, when the tilemap collider was added but not composite:

Can you send me a link to that framework? How do they handle that there is the collider by the player should not collide with it? Isn't it possible that you have to somehow setup which layers collide with one another for this setup to work? Because it still seems to me that if the setup is correct, the player should not be able to collide with the floor.

farazk86 commented 4 years ago

'd recommend to find the room template that corresponds to the room template that blocks your path (either the current room or the corridor) and check which of the tilemaps/colliders are causing that (for example by trying to disable/remove individual components and see if it works or not).

Its interesting that the room instances dont have the colliders on the floor tilemap, although I added the function above in DungeonTilemapLayersHandler. The room instances are at their default state only walls and collidables have colliders added to them, but not on floor.

I'm using the Top Down Engine available on the Unity Asset Store: https://topdown-engine.moremountains.com, youre right the framework does make use of layers and the floor is only used to detect when the player is jumping or falling. When I disable the floor component the player changes state to "falling" although still being able to move within the walls of the room

OndrejNepozitek commented 4 years ago

Its interesting that the room instances dont have the colliders on the floor tilemap, although I added the function above in DungeonTilemapLayersHandler. The room instances are at their default state only walls and collidables have colliders added to them, but not on floor.

Maybe you changed the DungeonTilemapLayersHandler after you have already created the room templates? In that case, their structure would remain the same as it was before. However, as you don't need the collider on individual, it doesn't matter.

I'm using the Top Down Engine available on the Unity Asset Store: https://topdown-engine.moremountains.com, youre right the framework does make use of layers and the floor is only used to detect when the player is jumping or falling. When I disable the floor component the player changes state to "falling" although still being able to move within the walls of the room

Did you set the "Ground" layer to the Floor tilemap of the generated level (based on their documentation)? When working with the generator, you should set it on the shared tilemap (Root game object -> Tilemaps -> Floor) and not on individual room templates (but it probably won't matter if it's on individual room templates, too).

farazk86 commented 4 years ago

Right, So I regenerated my dungeon after making the changes to DungeonTilemapLayersHandler and now individual room instances have the correct colliders on them.

And I figured out that it was not the floor collider preventing me from leaving the room but the collidable layer on which the top wall is built. Once I could click on the individual rooms I could see it, As in screenshot below:

11111

As can be seen its the collidable that is the problem. When I disable the collidable on this room, I can leave and enter the corridor, as can be seen:

121212121212

The floor tilemap still has the collider and it did not prevent me from leaving.

So is this a bug or did I make mistake in setting up dungeon?

Edit: I would like to add that when clicked on the complete dungeon collidable, it appears okay as can be seen from below:

87

Its just failing to remove the collidables from the door connections to individual rooms

Thanks

OndrejNepozitek commented 4 years ago

Have you changed anything regarding the Collideable tilemap layer and its colliders? Because in Example 2, the wall tiles are also placed in the Collideable layer but these individual colliders are properly disabled when you generate a dungeon. And after generation there is only the one big collider. Moreover, it seems to me like the Wall and Collideable colliders are completely same in my example setups, so I'd expect that if the code properly disables Walls, it should work with Collideable, too.

I'm sorry for your troubles. Hopefully we'll fix it soon.

farazk86 commented 4 years ago

Hi @OndrejNepozitek

Thanks for the reply.

I think it may be a bug in the system, I managed to recreate this problem in a completely fresh import of Example 2 and Example 1.

A freshly generated dungeon will have all the correct colliders, and the rooms will not be blocked but when one enters the game the colliders are redrawn and the walls block the player.

Here is how to recreate this problem:

In Example 1:

So this works correctly on a freshly generated dungeon. If you play game to test something and then come back then the dungeon is broken and walls recreated.

No need for sorry my friend, Thank you for writing this asset and making it available for us, an then helping me with the errors.

I hope we can fix this.

Thanks

OndrejNepozitek commented 4 years ago

Thanks for your investigation.

It seems to me that if I disable a collider in Editor mode and then enter Play mode, Unity forgets that the collider was disabled and makes it enabled. So it looks like this bug was affecting only dungeons that were created in Editor mode.

I tried to fix it by completely removing the collider component from individual room templates, instead of disabling it. And it looked like the problem is no longer there.

Please try to download the newly released hotfix and see if it works or not.

farazk86 commented 4 years ago

This fixed the problem. Many thanks :)