Search Unity

  1. Looking for a job or to hire someone for a project? Check out the re-opened job forums.
    Dismiss Notice
  2. Unity 2020 LTS & Unity 2021.1 have been released.
    Dismiss Notice
  3. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

DunGen - Procedural Dungeon Generation

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

  1. Aegon-Games

    Aegon-Games

    Joined:
    Mar 7, 2014
    Posts:
    495
    I'm going to make it optional (but probably enabled by default). I do try to make any system changes like this optional whenever I can.


    Runtime generation is the standard way of using DunGen and is achieved by adding a 'Runtime Dungeon' component to an object in your scene (page 10 of the readme).
     
    neoshaman likes this.
  2. OmegaGoodJob

    OmegaGoodJob

    Joined:
    Dec 26, 2017
    Posts:
    2
    Does the A* Pathfinder Pro integration work with 2d tiles? I'm using the 2d example project and I've followed the instructions for integration but no grid / navmeshes are being generated. When I add a target for my AI to follow it gets a "Can't find node near start node. Scanned nodes: 0" error. It also states there are 0 nodes in the inspector.
     
    Last edited: Oct 6, 2020
  3. lhadlum

    lhadlum

    Joined:
    Jun 26, 2012
    Posts:
    9
    Awesome asset, it's really helping with my game progress, but I have a question regarding the post-process step - I'm struggling to understand how it works.

    Basically, I need to call a method in a script, let's say 'Start timer' for argument's sake, as soon as the dungeon is generated.

    Can you provide an example of how I would call 'Start Timer' once the dungeon generation is complete?

    Thanks
     
  4. Aegon-Games

    Aegon-Games

    Joined:
    Mar 7, 2014
    Posts:
    495
    Sorry for the late reply. DunGen's integration for that asset only uses recast graphs and it looks like they don't support 2D primitives. I'd like to make the integration work with any type of graph, but unfortunately I can't find the time to work on DunGen right now.


    If you just need to know when the dungeon generation is complete, you can use the OnGenerationStatusChanged callback like this example. The post-processing steps are just there for if you need more control over exactly when your code runs relative to other post-processing steps.
     
    lhadlum likes this.
  5. katasteel

    katasteel

    Joined:
    Nov 21, 2014
    Posts:
    263
    Repeat Mode question.
    I thought if I Set Repeat Mode to "Disallow" that a tile would only be able to occur once in the dungeon.
    upload_2020-10-11_13-17-29.png
     
  6. Aegon-Games

    Aegon-Games

    Joined:
    Mar 7, 2014
    Posts:
    495
    You're right, that is how the 'Disallow' repeat mode should work. Do you have the global override enabled?

    GlobalRepeatMode.png

    If that's enabled, it'll ignore the repeat mode setting on the individual tiles.
     
  7. katasteel

    katasteel

    Joined:
    Nov 21, 2014
    Posts:
    263
    Yep it was checked. Thanks!
     
  8. lejean

    lejean

    Joined:
    Jul 4, 2013
    Posts:
    349
    Hey what would be a good way to avoid having 2 rooms next to each other that are not connected?

    I also don't want them to connect I just want a gap between rooms if they aren't connected

    thx
     
  9. Aegon-Games

    Aegon-Games

    Joined:
    Mar 7, 2014
    Posts:
    495

    Unfortunately I don't think there is a good way to do that. I thought maybe you could manually set the tile bounds to force some buffer room around tiles, but it doesn't work very well.
     
  10. DGordon

    DGordon

    Joined:
    Dec 8, 2013
    Posts:
    556
    Hello,

    I have a staircase room, and I would like it to only appear in a branch if it has another room after it. Meaning, I wouldn't want a staircase to lead to a blank wall at the bottom. It works fine in the main path since its guaranteed not to be the last room ... any way to guarantee this with something built in for branches?
     
  11. Aegon-Games

    Aegon-Games

    Joined:
    Mar 7, 2014
    Posts:
    495

    In your archetype settings, you can use a specific set of branch cap tiles. When the mode is set to 'Instead Of', DunGen will try to always use on of the specified tiles as a cap. Unfortunately DunGen can't guarantee that a cap tile will be used. There will be some cases where a branch is blocked and can't reach its desired length and will therefore be left with whatever tile was placed last as the branch cap.

    BranchCapTiles.png


    The only other thing I can think of is to make sure any staircase tiles aren't just a staircase and that they have something at the bottom/top so it doesn't look out of place if used at the end of a branch. As an example, you could have a staircase lead down into a small room with another doorway in it, then in the tile component, you can mark the top doorway as an entrance so DunGen doesn't use the room the wrong way around.
     
  12. Felinsky

    Felinsky

    Joined:
    Jan 22, 2018
    Posts:
    22
    Hey im generating dungeon on start of scene, but I need to make it happen on Awake method instead Start. Is it safe to change the code in RuntimeDungeon.cs from Start to Awake ? or it will harm some generation processes in DunGen ?
     
  13. DGordon

    DGordon

    Joined:
    Dec 8, 2013
    Posts:
    556
    Will it check if every single cap does not fit, or just pull one by weight, test that, and if it fails leave it as the stairs? If it will keep trying each cap until every single one failed, an easily solution is to just make sure I have a more appropriate cap that fits the exact tile size of the staircase.

    Would this work?
     
  14. lejean

    lejean

    Joined:
    Jul 4, 2013
    Posts:
    349
    Is it possible the start tile is not taken into account for branching?

    It seems to always have 1 door even though multiple doors are available.
     
  15. katasteel

    katasteel

    Joined:
    Nov 21, 2014
    Posts:
    263
    The Start tile does not seem to get rotated even though I have "Allow Rotation" set on it.
    Am I missing a setting that may be stopping it from rotating?
     
  16. Aegon-Games

    Aegon-Games

    Joined:
    Mar 7, 2014
    Posts:
    495
    That should be okay. If you just need it to run before the start method of another component, you could also adjust the execution order. If instead you need to do something when the dungeon generation is complete, you can do this.


    Unfortunately, it's the latter. Unlike the main path, DunGen doesn't consider branches to be gameplay-relevant so it doesn't bother re-trying when it fails to place a tile on a branch path. I did it this way so it would be rare for the generator to run into situations where it has to just discard the whole dungeon layout and start over.


    That's correct - only line segments in the dungeon flow graph can have branches. Branching settings are in the archetype, so they don't apply to nodes on the graph.


    The start tile is always placed at the origin of the dungeon root object and has its transform (including rotation) reset. With it being the first tile, I didn't think it mattered that it won't rotate since a random doorway from the start tile will be picked anyway and all subsequent tiles are able to rotate. I could allow the start tile to rotate if there's a need for it though.
     
  17. katasteel

    katasteel

    Joined:
    Nov 21, 2014
    Posts:
    263
    Personally I feel that it should be able to rotate if it is not a problem.
    Otherwise I would need to create four versions of the start tile if I want a more random feel.
     
    ok8596 likes this.
  18. camta005

    camta005

    Joined:
    Dec 16, 2016
    Posts:
    320
    I agree it would be helpful in my project too.
     
  19. hopeful

    hopeful

    Joined:
    Nov 20, 2013
    Posts:
    5,294
    Can you describe how you are using it? Is it in a top down game? Just curious. Having trouble visualizing the issue if it is a 3rd or 1st person camera game.
     
  20. katasteel

    katasteel

    Joined:
    Nov 21, 2014
    Posts:
    263
    Topdown ARPG
     
    hopeful likes this.
  21. katasteel

    katasteel

    Joined:
    Nov 21, 2014
    Posts:
    263
    Here is an example of one of the dungeons. Right now the exit to this starting room is always north.
    upload_2020-11-16_14-34-57.png
     
  22. hopeful

    hopeful

    Joined:
    Nov 20, 2013
    Posts:
    5,294
    What happens if you rotate the parent object?
     
  23. gliealonso

    gliealonso

    Joined:
    Oct 21, 2018
    Posts:
    76
    Hi,

    How can I set the the Line Segments from the Dungeon Flow as random through code? Or if there is already a random way to set this with your tool, is also ok

    Many thanks,
    Gabriel.
     
  24. Aegon-Games

    Aegon-Games

    Joined:
    Mar 7, 2014
    Posts:
    495

    If you just want it to pick a random archetype for a line segment, you can simply add more archetypes to the list. Select the line segment in the dungeon flow editor, then in the inspector use the 'Add New' button to add more archetypes:

    LineSegmentArchetypes.png

    DunGen will pick a random archetype from that list.

    If you need more complex logic, you can copy and modify the dungeon flow asset directly before passing it to the generator like this.
     
    gliealonso likes this.
  25. Felinsky

    Felinsky

    Joined:
    Jan 22, 2018
    Posts:
    22
    Hey, regarding random prefabs and local props, do they work recursively ? I mean can I put random prefab into random prefab list and then that list will be one of local props ? To make maximum generation diversity. Im using 2.13.2
     
  26. Aegon-Games

    Aegon-Games

    Joined:
    Mar 7, 2014
    Posts:
    495
    As of 2.13.0, the random prop components should be properly handled recursively. The exception is global props which don't allow other props inside them, but they can be nested in other props themselves.
     
  27. paifu

    paifu

    Joined:
    Jul 15, 2012
    Posts:
    21
    I bought Dungen today and it work great.

    But on URP the mini map on the Dungeon Crawler exemple doesnt draw the rooms, just showing chest,
    even with the materials updated to URP.
    Can you release an URP version of those mini map shaders?

    Thanks.
     
  28. katasteel

    katasteel

    Joined:
    Nov 21, 2014
    Posts:
    263
    Is there a way to know when the dungeon is 100% completed?
    Because it looks like GenerationStatus is being set to complete before all the tiles have finished processing.
    I subscribe to OnGenerationStatusChanged and some doors and tiles have not been set still at that time.
    This can cause many problems as you can imagine because I don't bind my pathing grid till it is completed.
    I also use a custom room culling solution and if I disable the game object(if out of camera view) after DunGen has reported "Completed" I end up with two doors(one from each room).

    My guess it you may be calling some coroutine to do the processing or something. And you might be marking it completed before everything is really completed(still running in the coroutine).
     
    Last edited: Nov 28, 2020
  29. Aegon-Games

    Aegon-Games

    Joined:
    Mar 7, 2014
    Posts:
    495
    It looks like the shader itself works fine with URP, but the script that draws the minimap needed some changes to support scriptable render pipelines.

    If you find the file at "DunGen/Samples/Dungeon Crawler Sample/Minimap/RenderMinimap.cs" and replace all the code with this it should work properly with SRP.


    That's strange, the status is changed to 'Complete' after the post-processing step where I build the NavMesh with the built-in adapters so everything should be in place by then.

    Just to be sure, you are definitely checking that the status is 'Complete' inside the OnGenerationStatusChanged delegate?

    Code (CSharp):
    1. private void OnDungeonGenerationStatusChanged(DungeonGenerator generator, GenerationStatus status)
    2. {
    3.     if (status == GenerationStatus.Complete)
    4.     {
    5.         // Do Stuff
    6.     }
    7. }
     
  30. katasteel

    katasteel

    Joined:
    Nov 21, 2014
    Posts:
    263
    Yeah. Here is the code.
    Code (CSharp):
    1.         private void OnGenerationStatusChanged(DungeonGenerator generator, GenerationStatus status)
    2.         {
    3.             if (status != GenerationStatus.Complete)
    4.                 return;
    5.  
    6.             RuntimeDungeon.instance.Generator.OnGenerationStatusChanged -= OnGenerationStatusChanged;
    7.  
    8.             Process();
    9.         }
     
  31. septN

    septN

    Joined:
    Oct 29, 2015
    Posts:
    26
    So I tried the sample scene, grabbed the key, but the door wont open. Is there something or button press that I need to do to open the gate?



    Edit: this bug happened after importing DunGen on a TopDownEngine project
     
    Last edited: Dec 18, 2020
  32. taotao-cw

    taotao-cw

    Joined:
    Dec 21, 2020
    Posts:
    2
    Hi, can the dungeon generate 2 main paths at the same time? Or generate 1 unique branch path. I want to make 2 boss rooms with different directions. I'm sorry for my poor English, I may not express myself clearly~
     
  33. hopeful

    hopeful

    Joined:
    Nov 20, 2013
    Posts:
    5,294
    I believe it's one path to the goal. However, you could potentially insert additional bosses on the main path.

    It may also be possible to design to have more than one dungeon generate, and the player could do one dungeon then the other.
     
    Aegon-Games likes this.
  34. taotao-cw

    taotao-cw

    Joined:
    Dec 21, 2020
    Posts:
    2
    Thanks, it occurred to me that I could add a room in the middle of the main path as the room where the player starts, so that the start of the main path and the target could be the boss room in 2 different directions!
     
    Aegon-Games and hopeful like this.
  35. lejean

    lejean

    Joined:
    Jul 4, 2013
    Posts:
    349
    What's the best way to have special tile injections per archetype instead of per dungeon.

    For example I want each archetype to have their own required healing room but it seems I can only have a required tile on dungeon basis which gives me scenarios like a cave healing room in the middle of a forest.

    I don't see a required tileset option in the archetypes themselves.

    I could solve this by adding multiple dungeon generators but that seems counter intuitive as I rather just use 1 flow.

    Should I do it like in the picture maybe?
    I'm not entirely sure how the nodes in the flow operate though.

    What do the positions on the segments signify?
    Do they get placed on that relative distance or something?

    dungen.png
     
  36. Aegon-Games

    Aegon-Games

    Joined:
    Mar 7, 2014
    Posts:
    495
    Sorry for the very late replies on some of these posts. I'm going to try to check the forum thread regularly from now on in case I miss the email alert again.

    I'm still unable to reproduce the issue unfortunately. I'd expect it to cause problems for the built-in NavMesh integration as well, but everything seems to work as expected. I even tried a script that printed the number of objects in the scene to the console when the dungeon generation was completed, then again a few seconds later just to make sure the numbers matched. I've also tried it with 'Generate Asynchronously' on and off.

    Is there any chance you could send me a small project demonstrating the issue?


    The gate should open when the player enters a box collider trigger as long as the player has the key. From your screenshot, it absolutely should have opened.

    It doesn't look like it from your screenshot, but were there any errors at all? I don't have TopDownEngine to test, but if there were any conflicts they should have appeared as errors in the console.


    As long as your archetypes are fixed (e.g. caves is always the first half, forest is always the second), there are two ways you could go about doing this:

    1. Place them as nodes like in your picture. As you assumed, the tiles are placed relative to their distance along the segment. If it's in the middle of the line, the tile will be placed ~50% of the way through that segment.

    2. Use two separate special tiles and restrict the path depth appropriately. In your example, you'd use a path depth of 0.0-0.5 for the first segment so it only shows up in the first half of the dungeon (and 0.5-1.0 for the other half).
     
    lejean likes this.
  37. septN

    septN

    Joined:
    Oct 29, 2015
    Posts:
    26
    @Aegon-Games found the issue, it was nothing to do with DunGen but the collision matrix setup by TDE.

    Anyway, what's the common pitfall/mistakes when designing rooms?
    Everything works fine and nice when my tileset contains room with simple square shape (with 2 doors on each side). But things start falling apart when I add weird shaped room (all has same door socket) they seems to refuse to be placed together, so I ended up with all squares [ ] rooms, or all | | shaped rooms, but never a combination of those even with special dungeon flow rules.
     
  38. Aegon-Games

    Aegon-Games

    Joined:
    Mar 7, 2014
    Posts:
    495
    I'm not sure what's causing your specific issue. If you hadn't said that the rooms are all using the same door socket I would have guessed that each of your rooms were using a different socket and can't connect to each other. That's the only reason I've encountered dungeons being generated with only one room.


    The most common mistake I see with rooms is the doorway positioning. Mostly things that are easy to miss like doorways facing the wrong way, or having doorways that are inside the room's Axis-Aligned Bounding Box.

    There's a tool to check for some of the more common configuration errors. It can be accessed by selecting your dungeon flow asset, then click the 'Validate Dungeon' button at the top of the inspector. If it finds any errors, they'll appear in the console.
     
    hopeful likes this.
  39. hopeful

    hopeful

    Joined:
    Nov 20, 2013
    Posts:
    5,294
    Just wanted to mention that if for some reason you do wind up making squares, keep in mind that your room mesh only has to use part of the square. You could make a weird shaped room inside that square so long as corridor type shapes extend to the edge to facilitate door joining.
     
    septN likes this.
  40. NotTrollax

    NotTrollax

    Joined:
    Oct 31, 2018
    Posts:
    1
    Is there a way to have a corridor in the archetype and ensure that both openings will be connected to a room? Cause right now I sometimes end up with a corridor that leads to nothing.
     
  41. Aegon-Games

    Aegon-Games

    Joined:
    Mar 7, 2014
    Posts:
    495
    Unfortunately, there's no way to guarantee that right now. It's a commonly requested feature though and I'm working on finding a good solution.

    In the meantime - as long as your corridors only have 2 doorways - the only place they can appear and not have all of the doorways connected is at the end of a branch. You can minimize how often this happens by using branch-cap tile sets.

    In your archetype asset(s), you can assign a tile set to the 'Branch-Cap Tile Sets' field, and as long as the mode is set to 'Instead Of', only tiles in that set will be used at the end of a branch. This still isn't guaranteed - if the branch needs to be cut short (because there's not enough room for the full branch for example), you can still be left with a corridor at the end, but it should happen less often.
     
    Vincent13122 likes this.
  42. Vincent13122

    Vincent13122

    Joined:
    Oct 26, 2014
    Posts:
    82
    Couldn't you in theory ask the corridor if its connected on more than one doorway and if not, just delete it and close the doorway on the other tile again.
     
  43. lejean

    lejean

    Joined:
    Jul 4, 2013
    Posts:
    349
    Hey is Dungen compatible with the addressable package?
     
  44. gliealonso

    gliealonso

    Joined:
    Oct 21, 2018
    Posts:
    76
    Hello,

    Why does sometimes the dungeon looks huge, and sometimes it's super tiny? I try to change the Length Multiplier, but it still sometimes generates a huge dungeon or one with only 3 rooms, how can I fix this?

    Many thanks,
    Gabriel.
     
  45. Jbaker08

    Jbaker08

    Joined:
    Oct 8, 2012
    Posts:
    41
    Has anybody worked with this over a network?
    I'm currently using Photon, I saw some topics on using the same seed number to generate the dungeon the same.
    This isn't really the issue as the runtime generator only needs to be created on the masterclient. Once that is done, the scene can be synced across the whole server so everybody see's the same thing.

    The problem is actually the way the runtime editor is creating the dungeon. You actually need to use 'PhotonNetwork.Instantiate' instead of the standard Instantiate. This is so photon can actually read the objects over the network (incase you have network related prefabs). In my case, my tiles carry many scripts that are network related.

    How are you actually creating the dungeon? I've tried looking through the scripts but can only find one instance of instantiation, and that was with Doorobj.

    I would essentially need to add a flag to the dungeon creator that checks if the game is online or offline. If it's online, I need to instantiate the prefabs via the PhotonNetwork.Instantiate command.

    Do you have a list of the scripts that are effectively 'instanting' the tiles in the game?

    I hope you can help as I've had no reply on my email.

    Thanks
     
  46. Aegon-Games

    Aegon-Games

    Joined:
    Mar 7, 2014
    Posts:
    495
    I was thinking something along those lines. At the moment, I'm considering allowing tiles to be tagged as corridors then once the dungeon is complete, look at the end of every branch and delete the tile if it's a corridor.

    That would work for every corridor that has two doorways, but I don't yet have a general solution to force all doorways of a corridor to be used if there are more than two. That would require a lot more work (and I think it's a less problematic scenario anyway).


    I don't think it is. I don't know much about the addressables package, but I'm pretty sure I'd need to change the way assets are references throughout the project to make it work.


    The main path length should always be between the min and max length defined in the dungeon flow asset. Where you're likely to get a lot more variation in the number of rooms is with the branch paths. It's possible that the rooms on your main path don't have enough doorways to add any branches and that's causing the dungeon to generate with just the main path.

    You can lower the range between the number of branches a tile can have (as well as the length of those branches) in the archetype settings. Also, make sure that your tiles have enough doorways to support the number of branches you expect your tiles to have (this is controlled by the 'Branch Count' field in the archetype settings).


    I've never used DunGen over the network, but I'd approach it using the seed method. The vast majority of the objects in the tiles don't need to be replicated to the clients as they're just static geometry - creating an identical layout on each client by using the same seed should be enough. It can also save you a lot of bandwidth by not replicating objects unnecessarily.

    For network-relevant objects, you'd need to spawn them in yourself somehow. The easiest method would be to replace these objects in the tiles with an empty GameObject with a custom script attached which calls Photon's Instantiate method on a prefab you provide.

    If you really need the tiles themselves to be replicated, they're instantiated in the 'FromProxy' method in Dungeon.cs - though I don't know how Photon handles instantiating sub-objects (if at all). You might end up with a tile that's replicated, but the actual objects you care about inside the tile are not.
     
    Vincent13122 likes this.
  47. tonywalsh

    tonywalsh

    Joined:
    Jun 4, 2014
    Posts:
    15
    Hi, I am trying to fit 4 10x10 tiles into a 20x20 bounding area, but after the start tile spawns, there's not enough space around it for the rest of the tiles. This is working as DunGen is designed, I believe.

    Looking for tips on how to override start tile position (might be impossible without modifying the code). Thanks!
     
  48. thorgaming_42

    thorgaming_42

    Joined:
    Sep 25, 2015
    Posts:
    11
    Hi @Aegon-Games would just like to say your product is fantastic i've used it in tons of scenarios and find it really diverse. I wonder if I could ask you question of filling in surrounding tiles for a top-down 2d style game.

    I know this has been asked before and I did see your answers, in my approach I am happy for all tiles, corridors, corners etc to be the same size say 20x20 units, I was thinking I could create a dungeon, check the bounds of this created dungeon then create an X by X size grid that surrounds it as a rectangle. Then fill in all parts of this array with my filler tiles. Am I over simplifing the solution, can you see a flaw to this approach?

    Additionally if you can see a better way, doesn't matter if its more complex as am pretty sure I could implement it, I would love to hear your thoughts.

    Edit: In the world i'm building you can dig through all terrain pixel by pixel so its important the whole grid is filled it isn't just for cosmetic reasons around what you can see of the dungeon!

    Many Thanks.
     
    Last edited: Jan 31, 2021
  49. Aegon-Games

    Aegon-Games

    Joined:
    Mar 7, 2014
    Posts:
    495
    The start tile is always placed at (0, 0, 0) of the dungeon root object. You could change it through code (see around line 777 in DungeonGenerator.cs - the tile position is only set when fromDoorway is not null - when it's not the first tile).

    There might be an easier way though. Either of these options could work, assuming your tiles are currently built with their origin at the center:

    1. Offset the center of the placement bounds by 10 units on X and Z so the first tile is placed in a corner instead of the center of the bounds.
    2. Modify your tiles so the origin is at one of the corners. Again, this would make the tile spawn in one of the four possible places for a tile instead of right in the middle. This method requires more work, so if you can do the first one, that would be better.

    Those are some pretty restrictive constraints so you might run into some issues with the dungeon generation failing a lot, but the 'Max Failed attempts' field is only active in the editor (to prevent infinite loops for misconfigured dungeons). In a packaged game, DunGen will keep trying until it succeeds.

    You might also need to increase the bounding area slightly. 21 units for example will give you the same results, but removes the chance that a tile is considered to be out of bounds for just touching the bounding volume.


    I can't think of any issues with that approach, it seems like the most elegant way to fill surrounding tiles to me.
     
  50. Binary42

    Binary42

    Joined:
    Aug 15, 2013
    Posts:
    176
    Hello, does DunGen support alternate or cyclic paths by now?
     
unityunity