Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Join us on Dec 8, 2022, between 7 am & 7 pm EST, in the DOTS Dev Blitz Day 2022 - Q&A forum, Discord, and Unity3D Subreddit to learn more about DOTS directly from the Unity Developers.
    Dismiss Notice
  3. Have a look at our Games Focus blog post series which will show what Unity is doing for all game developers – now, next year, and in the future.
    Dismiss Notice

DunGen - Procedural Dungeon Generation

Discussion in 'Assets and Asset Store' started by Aegon-Games, Mar 7, 2014.

  1. thiskidcalledtom

    thiskidcalledtom

    Joined:
    Nov 9, 2017
    Posts:
    35
    I have just found the cause.... Unity by default sets the `World Extents` to 250 in the physics settings... jesus christ. 6 months of pain.
     
    Aegon-Games and hopeful like this.
  2. thiskidcalledtom

    thiskidcalledtom

    Joined:
    Nov 9, 2017
    Posts:
    35
    is there a way to detect if a room is a dead end? i want to put a chest in deadend rooms
     
  3. Aegon-Games

    Aegon-Games

    Joined:
    Mar 7, 2014
    Posts:
    590
    Since a dead end tile will have exactly one doorway in use, you can do this to determine if a tile is a dead end:

    Code (CSharp):
    1. tile.UsedDoorways.Count == 1
     
    thiskidcalledtom and hopeful like this.
  4. thiskidcalledtom

    thiskidcalledtom

    Joined:
    Nov 9, 2017
    Posts:
    35
    Me again haha.
    is there a setting somewhere to make a certain room not be a dead end? i have a small corridor that likes to be a deadend and i'd like that not to happen
     
  5. Aegon-Games

    Aegon-Games

    Joined:
    Mar 7, 2014
    Posts:
    590
    You could use the branch pruning feature:

    1. Create a tag for tiles that you don't want to appear as dead ends and apply it to your tiles
    2. In the dungeon flow settings, add the tag you just created to the "Branch Prune Tags" list
    3. Set the branch prune mode to "Any Tag Present"
    Now after the dungeon has finished generating, it will look at the end of every branch and remove any tiles that have the tag you've made.

    Another option would be to use the "Branch Cap Tiles" list in the archetype settings and just put every tile in there other than the ones you don't want to appear as dead ends. The problem with this method is that it's not guaranteed to work if a branch has to end early to avoid collision.
     
    thiskidcalledtom likes this.
  6. bradbecker

    bradbecker

    Joined:
    Dec 26, 2014
    Posts:
    130
    I have objects that are under various RandomProps that register themselves OnEnable. Unfortunately, they seem to become enabled BEFORE they're actually attached to the Tile (room). Is there a different event that individual props/monsters/etc can listen for instead of Enable to register themselves?
     
  7. Aegon-Games

    Aegon-Games

    Joined:
    Mar 7, 2014
    Posts:
    590
    You should be able to implement the IDungeonCompleteReceiver interface on your component to receive a notification from DunGen once the generation is done:

    Code (CSharp):
    1. using DunGen;
    2. using UnityEngine;
    3.  
    4. public class Monster : MonoBehaviour, IDungeonCompleteReceiver
    5. {
    6.    public void OnDungeonComplete(Dungeon dungeon)
    7.    {
    8.        // Spawn logic goes here
    9.    }
    10. }
     
  8. bradbecker

    bradbecker

    Joined:
    Dec 26, 2014
    Posts:
    130
    FYI for posterity, IDungeonCompleteReceiver only works for objects that are under the dungeon hierarchy.
     
    Aegon-Games likes this.
  9. Meteorwater

    Meteorwater

    Joined:
    May 23, 2019
    Posts:
    2
  10. Aegon-Games

    Aegon-Games

    Joined:
    Mar 7, 2014
    Posts:
    590
    I can see some Z-fighting in your video so it looks like the blocker prefabs have been spawned inside your walls instead of in the doorway.

    Prefab blockers are attached to the doorway object and have their local position, rotation, and scaling reset - so you want your prefab to block the open doorway when it is placed at the doorway's position. Your prefab is most likely offset somehow.

    I've found the best way to position blocker prefabs is like this:

    1. Create an empty GameObject that will be your new prefab. Avoid using an existing prefab as a blocker if you'll be using the same prefab in a different way (as a wall for example) because we'll probably need to offset its position. If you already have a prefab, skip this step.
    2. Put one of your rooms down in the scene
    3. Parent your blocker prefab to one of the doorways of your room and reset the prefab's position, rotation, and scaling
    4. Place any mesh(es) you want to use inside the prefab
    5. Adjust the position of the meshes (not the prefab itself) so that they fit the doorway properly
     
  11. bradbecker

    bradbecker

    Joined:
    Dec 26, 2014
    Posts:
    130
    I got a stack overflow error in a runtime build from dungen generation. In the log, it starts with the DoorwayPairFinder.cs line 138 and then in InnerGeneration there are line after line of Wait. Then the stack overflow from all the IEnumerator calls. It's a huge log dump that I don't want to fill this forum with, so hopefully that's enough for you to be able to give me a clue of where to look for the problem.
     
  12. bradbecker

    bradbecker

    Joined:
    Dec 26, 2014
    Posts:
    130
    FYI, the immediate issue is that the dungeon is failing to build. I'm guessing that is because the dungeon starting object is near the edge of the bounds and for whatever reason, it keeps trying to build the dungeon in the wrong direction from there.
     
  13. bradbecker

    bradbecker

    Joined:
    Dec 26, 2014
    Posts:
    130
    @Aegon-Games So, is there a way to get the dungeon to build in a direction? I think I've seen on other comments that there is not. So, how can you set up the bounds if you don't know which way it will build out at first? How can you have the procedural dungeon extend from and connect to an existing area? (I know you could wrap the entire existing in a parent gameobject with Tile component and a single doorway but that seems ill-advised and probably non-performant)
     
  14. Aegon-Games

    Aegon-Games

    Joined:
    Mar 7, 2014
    Posts:
    590
    In a packaged build, there's no limit to the number of retries when generating a dungeon so you have to be careful when adding very restrictive constraints otherwise it could get stuck in an endless loop. I'll have to look into it further, but I think that's what's happening here.

    The best way to have a dungeon build in a direction is to use a starting tile with only one doorway. Since the starting tile is never rotated, the doorway should always point in the same direction. To try to make the dungeon continue in that direction, you could use the 'Straighten' slider in the archetype settings, or mark opposite doorways in your tile as the 'Entrance' and 'Exit' in the tile component. These can all be used alongside the dungeon bounds constraint, but you may need to widen your bounds to make it less restrictive and give the generator more options for placing tiles.
     
  15. bradbecker

    bradbecker

    Joined:
    Dec 26, 2014
    Posts:
    130
    Thanks! FWIW, the constraints I set were really large but it wasn't laying out a single room even. I think it was probably just because it wanted to point it in the other direction out of the constraints. Will try building a custom starting tile for this.
     
  16. Shing-Ming

    Shing-Ming

    Joined:
    Apr 6, 2018
    Posts:
    1
    Hi, I use Dungeon Generate in Editor (Window/Dungen/Generate Dungeon). Although the Dungeon is generated correctly in editor mode, but the Dungeon component's variables will initialized after i enter playmode. This means that allTiles, mainPathTiles, branchPathTiles etc will be lost. It doesn't seem to happen only in the Dungeon class. How can I make the Dungeon generated in the Editor have all the data like the one generated in runtime?
     
    Last edited: Aug 31, 2022
  17. snowcult

    snowcult

    Joined:
    Feb 6, 2014
    Posts:
    292
    what now?
     
  18. Aegon-Games

    Aegon-Games

    Joined:
    Mar 7, 2014
    Posts:
    590
    I think I've managed to fix this issue. I've uploaded a new build to the asset store (should be live once approved by Unity within a few days) and in the new build, any information in the Dungeon component is now saved so you should be able to access it after generating the dungeon in-editor. The bounds for each tile are also now saved, so they should no longer be reset.
     
  19. codebread

    codebread

    Joined:
    Apr 18, 2013
    Posts:
    5
    Hello!

    Is there a good way to force the ordering of tiles for a dungeon? I want to set up a tutorial zone where the dungeon always generates a set of rooms in the same order (Ex. you have Rooms A, B, C, and D and you always want them spawned in that order). I can reuse the seed once it's generated once, but I'm having trouble getting that far.

    At the moment I've created 10 rooms, all with their own Tileset and Archetype, which I'm throwing into the Dungeon Flow editor as 10 separate segments. It's problematic because getting the segment lengths equal is tedious.

    I could create it as a single tile in a one tile dungeon I suppose, but I added some custom logic for "loading" between tiles that I'd like to keep. I can hack a tile into multiple smaller loaded zones if I need to, but I figured I'd ask this first.
     
  20. Aegon-Games

    Aegon-Games

    Joined:
    Mar 7, 2014
    Posts:
    590
    There isn't really a good option that I can think of I'm afraid. You could maybe use the tile injection system (around page 31 in the Readme PDF) but if you want the dungeon to consist of only those rooms, I think your solution of having 1 archetype per room laid out in the dungeon flow would produce better results.

    Though if the tutorial zone layout needed to be exactly the same each time, I wouldn't necessarily even use DunGen to generate it and would instead make it by hand. I don't know how you custom logic for loading between tiles works but it may be possible to just build the layout by hand in such a way that it still works as if it were a procedural dungeon.
     
  21. codebread

    codebread

    Joined:
    Apr 18, 2013
    Posts:
    5
    Yeah that's what I ended up doing, no worries. It wasn't hard, I just wanted to cut as many corners as possible. Thanks for making an awesome tool!
     
  22. Misscelan

    Misscelan

    Joined:
    Mar 8, 2013
    Posts:
    166
    Hi,

    I have this starting room that has 4 doors, I would like to generate a different dungeon starting on each door and then connect the beginning of each dungeon with a door of the initial room.

    Each door of the initial room leads to a different floor and the dungeon generated would be flat, so there shouldn't be any overlaps.

    I could generate 4 differents dungeons, and then do the math to make the starting point match with the initial, but I was wondering if there is any Dungen feature I might be missing that could help me out with the process.

    Thanks!
     
  23. chuwilliamson

    chuwilliamson

    Joined:
    Jan 18, 2013
    Posts:
    6
    does this support unity terrain?
     
  24. Aegon-Games

    Aegon-Games

    Joined:
    Mar 7, 2014
    Posts:
    590
    There isn't a built-in DunGen feature to handle this, but at least you shouldn't have to do the maths manually. You can use DunGen's UnityUtil.PositionObjectBySocket helper function to move & rotate each dungeon into place.

    You can use Unity terrains inside DunGen tiles, but the tile must be set to not allow rotation because Unity terrains can't be rotated.
     
    chuwilliamson and Misscelan like this.
  25. GreaserMonkey

    GreaserMonkey

    Joined:
    Feb 10, 2019
    Posts:
    48
    Hi

    From time to time Dungen fails to generate dungeon. Most of the times it fails because doorways or not correctly placed to the edge of the tile and sometimes I have to open a lot of tile prefabs to check the doorways and it takes time.

    Log says:
    -----------------------------------------------
    Here are a list of all reasons a tile placement had to be retried:
    UnityEngine.Debug:LogError(Object)
    DunGen.<InnerGenerate>d__91:MoveNext() (at Assets/DunGen/Code/DungeonGenerator.cs:251)
    DunGen.DungeonGenerator:Wait(IEnumerator) (at Assets/DunGen/Code/DungeonGenerator.cs:223)
    DunGen.<GenerateMainPath>d__96:MoveNext()
    .
    .
    .

    Could you improve the log somehow so that it could give a little bit more information to help solving the issue? Maybe the path depth it was at when it failed. And maybe log the archetype and the current tile it was trying to place when it failed to do so?
     
  26. alexjet1000

    alexjet1000

    Joined:
    Jul 29, 2020
    Posts:
    19
    Hi! I wonder how can you make it through code so tile injection can take into consideration already injected tiles. Like a post processing injection.

    Example: I have a SecretRoom TileSet with ChallengeRoom and TreasureRoom, then i have a Shop tileSet with WeaponShop, and GeneralShop tiles.

    How can i make so if a TreasureRoom is injected, it wont spawn a GeneralShop? So it discards considering tiles.


    Same question for TileSets, how can i decide if a TileSet is spawned or not if another one was already spawned? Like if a TreasureRoom was spawned, not spawn a GeneralShop room.
    This considering that not all tileSets need to spawned (!isRequired).

    Priorities would be good to add.

    Thanks!
     
    Last edited: Oct 21, 2022
  27. hopeful

    hopeful

    Joined:
    Nov 20, 2013
    Posts:
    5,521
    It sounds like you could make dungen prefabs for specific purposes, like one type that is keyed to include treasure rooms, and one prefab that is keyed to produce general shops. Then you just instantiate and generate the specific type you need for your purpose.
     
  28. alexjet1000

    alexjet1000

    Joined:
    Jul 29, 2020
    Posts:
    19
    I think it could do what you say as well without even using tile injection, but then whats the point of tile injection itself if done like that?
     
  29. hopeful

    hopeful

    Joined:
    Nov 20, 2013
    Posts:
    5,521
  30. alexjet1000

    alexjet1000

    Joined:
    Jul 29, 2020
    Posts:
    19
    Last edited: Oct 22, 2022
  31. alexjet1000

    alexjet1000

    Joined:
    Jul 29, 2020
    Posts:
    19
    I have an additional question,

    For adding custom tile injection rules using a range for the depth of paths, wouldnt be good to have a constructor for InjectedTile that accepts ranges?
    The two of them existent dont seem to have this. (Im on v.2.15 btw)
     
  32. Aegon-Games

    Aegon-Games

    Joined:
    Mar 7, 2014
    Posts:
    590
    Sorry for the very late reply. Usually I'd have a new beta build ready to go to address issues like these, but deadlines on another project are keeping me from working on DunGen at the moment. I'm hoping to find some time to put out a beta version soon.


    For finding common tile misconfiguration issues, you might be able to use the "Validate Dungeon" button at the top of the inspector when selecting your dungeon flow asset. It doesn't currently check if doorways are on the edge of tiles, but it's on my todo list.

    I'll see if I can add more information to the errors so they're more useful.


    The way tile injection works at the moment doesn't allow for ranges unfortunately. Even the injection rules defined in the editor just take a random value in the range before the rule gets put into the injection queue.

    It probably would be better if the tile injection accepted ranges instead, but I'll have to take a look under the hood and see if it's a change I can make without re-working the whole system.
     
    GreaserMonkey likes this.
  33. Storm_Fireblade

    Storm_Fireblade

    Joined:
    Dec 17, 2020
    Posts:
    1
  34. Aegon-Games

    Aegon-Games

    Joined:
    Mar 7, 2014
    Posts:
    590
  35. desukarhu

    desukarhu

    Joined:
    Jun 14, 2017
    Posts:
    24
    Hey,

    What does
    Code (CSharp):
    1. Doorway 'Doorway 1' in tile 'Cave Inner 2' has an invalid rotation. the forward vector is not axis-aligned
    actually mean? I keep getting that when validating my dungeons. The dungeons seem to generate just fine but I'd like the validation to pass still.

    Attached a picture of one of my doors that causes that error.
     

    Attached Files:

  36. Aegon-Games

    Aegon-Games

    Joined:
    Mar 7, 2014
    Posts:
    590
    Doorways need to be aligned so the blue line faces down one of the world axes. Basically, your doorway rotations should be snapped to 90 degree increments.
     
  37. desukarhu

    desukarhu

    Joined:
    Jun 14, 2017
    Posts:
    24
    Thank you, that fixes that error. But if I rotate my doorways to 90 degree increments I get this error instead:
    "Doorway 'Doorway 1' in tile 'Cave Inner 2' is facing the wrong way. Doorways should face outwards from the tile (local z-axis, blue line)"
    Even though the doors absolutely do face away from the tile. At least according to the blue lines.
     

    Attached Files:

    • cave.png
      cave.png
      File size:
      280.6 KB
      Views:
      13
  38. Aegon-Games

    Aegon-Games

    Joined:
    Mar 7, 2014
    Posts:
    590
    I'm not sure why you're getting that error, it looks right to me. Unfortunately I haven't been able to reproduce the issue myself so far.
     
  39. desukarhu

    desukarhu

    Joined:
    Jun 14, 2017
    Posts:
    24
    Alright, I can probably ignore it then? The dungeons seem to generate just fine.
     
  40. Aegon-Games

    Aegon-Games

    Joined:
    Mar 7, 2014
    Posts:
    590
    Yeah, if everything seems to be working (and the tile is actually being used) then it's probably just a bug in the validation code.
     
  41. Misscelan

    Misscelan

    Joined:
    Mar 8, 2013
    Posts:
    166
    Hi,

    I have noticed this issue in one of my generated dungeons. Rooms a2 and b1 are logically connected but not physically.




    -b2 and b1 are the same prefab room.
    -a1 and a2 are the same prefab room.
    -There is a door in a2 indicated by the blue arrow that should connect with b1. The door prefab is physically present in a2 but not in b1. So all good there.
    -Both room prefabs are correctly connected through those doors in other instances, as seen in b2 and a1


    Any idea what I'm doing wrong?

    Thanks!
     
  42. Aegon-Games

    Aegon-Games

    Joined:
    Mar 7, 2014
    Posts:
    590
    I don't think I've seen that before. Could you let me know the answers to these questions? Hopefully we'll be able to narrow the cause down a bit.

    1. Are your tiles made of standard mesh components or are they generated by something like ProBuilder?
    2. If you select b1 in the scene view after the dungeon is generated, is the doorway GameObject in the correct place? I just want to be sure it's the whole tile in the wrong place, not just the content. I've only ever seen this happen with Unity terrains (because they can't be rotated), but it's worth checking.
    3. Are your doorways directly under the root GameObject of the tile in the hierarchy or are they nested inside other objects? It should work either way but I tend not to nest them so it hasn't been extensively tested.