Need help with incorporating 2D dungeon algorithm into Unity.
So, I have went through dozens of the answers already in the forum and watched every tutorial I can locate. I can't seem to get my Unity to do what it does in the videos. I've landed on the conclusion that its either me failing miserably or something to do with the different versions that the person and I am using.
In Visual Studio, I have all the code to make an old school *, &, @, # kind of dungeon but no idea how to combine the two. The way I have it now, it makes a blank board of a given character, then iterates through the blank board generating random rooms, checking to make sure they fit, and if they do, iterate back through and create the room. Super Basic.
//Creating a blank board
for (int i = x - 1; i >= 0; i--)
{
for (int j = y - 1; j >= 0; j--)
{
board[i, j] = new Tile("▓", ConsoleColor.DarkGreen);
}
}
//Gathers room sizes for checking
for (int i = 0; i <= 11; i++)
{
int roomX = StaticRandom.Instance.Next(1, height -2);
int roomHeight = StaticRandom.Instance.Next(roomX +1, height - 2);
int roomY = StaticRandom.Instance.Next(1, length - 2);
int roomLength = StaticRandom.Instance.Next(roomY +1, length - 1);
bool result = CheckRoom(roomX, roomY, roomHeight, roomLength);
if (result == false)
{
i--; continue;
}
else
{
MakeRoom(roomX, roomY, roomHeight, roomLength);
}
}
}
public bool CheckRoom(int x, int y, int h, int l)
{
for (int i = x; i <= h; i++) {
for (int j = y; j <= l; j++)
{
if (board[i, j].symbol != "▓")
{
return false;
}
}
}
return true;
}
//iterate through the blank board and changes spaces to create 'rooms'
public void MakeRoom(int x, int y, int h, int l)
{ int midX = (x + h) / 2;
int midY = (l + y) / 2;
for (int i = x; i <= h; i++)
{
for (int j = y; j <= l; j++)
{
board[i, j] = new Tile("░", ConsoleColor.DarkGray);
}
}
midPoints.Add(new int[] { midX, midY });
}
I'll admit that its incredibly possible that this question has been answered, but there are SO many answers and I didn't have any luck going through them.
You haven't really described the problem at all. Please describe in detail specifically what problem you are having, what you have tried, and so on.
Sorry. I want to build the board in 2D with tiles that I made in photoshop ins$$anonymous$$d of the ascii characters that are in the loops right now.
I followed along with the 2D roguelike tutorial on here and got it to show my tiles that I created but when it came to the point to take it from a single square room with walls into a bunch of rooms and corridors and etc, I have no idea how to incorporate my code into the tutorial code.
So then I used... https://www.youtube.com/watch?v=ZoAu$$anonymous$$UE9SiY since his ends up looking essentially like what I ultimately want $$anonymous$$e to look like. In the very beginning, just to create the tiles the way he does wont work on my end. Can that be a version difference?
In a perfect world, I would just want to keep the current code and ins$$anonymous$$d of saying...
board[i, j] = new Tile("░", ConsoleColor.DarkGray);
I would want to say
board[i, j] = new whatever prefab in unity i want to use
Also..the reason I was thinking it could've been a version difference is because I downloaded the final project from his website and it didn't run correctly.
Answer by Statement · Oct 20, 2015 at 01:39 PM
It sounds like you just want to add a graphics layer to an already existing code base.
Given you have some classes already created for this purpose, you could generate graphical tiles based on your Ascii tiles.
It sounds like it boils down to two questions, at least for getting graphics going.
How will you render one tile?
You could create a game object per tile if you wanted, or if you want, you could generate one mesh with all of them if your tiles are atlased.
How will you map one ascii tile to a texture?
This is pretty straight forward. For any given character you have, bind data to that character that can represent your graphical image. It could be a loose texture, or a texture and texture coordinates.
So you would write a class that takes a tilemap as input, and spits out a mesh or lots of gameobjects as output.
Example
So I took the time to write up an example on how to do with generating a single mesh.
Ascii folder
Contains code regarding Ascii tilemap, a simple procedural ascii tile generator. Think of this as the system you already likely have in place.
Bridge folder
Contains code regarding converting Ascii into Sprite tiles. It is the glue which separates Ascii from Sprite. Sprite knows nothing about Ascii and Ascii knows nothing about Sprite. They are totally separated. Bridge is the glue between them.
Sprite folder
Contains the definition for SpriteTile and code to generate the mesh based on a SpriteTilemap. Note that SpriteTilemap is an interface, as such there is actually no code written specially to handle a tilemap of sprites. Instead, I use the bridge, which uses ascii.
Answer.cs
Well, cheeky file name apart, this is the entry point you should look at.
The code is very sparsly commented, so if you have questions, please drop a comment and I'll try to explain better and update the answer. If you get confused about the mesh generation, I'd recommend that you check out the Mesh class or reading up in general about how meshes operate. I can also provide a simpler implementation which creates lots and lots of game objects instead if you want. I need some time to sort out a proper github repo for all answers threads for that to happen though.
Note: The SpriteMeshBuilder is providing vertex colors, but the material I used does not use vertex colors. You'll need to use a shader which uses vertex color to see any color effects!
Absolutely. The game is going to have different levels (i.e. water, grass, castle, .....) so i think I remember seeing in a tutorial along my way saying that the mesh is a better way to tackle the random rooms and such.
We have the majority of the logic and everything for the game already to print in the normal console environment. Graphics, in general, are all CO$$anonymous$$PLETELY foreign to me and I'm trying to learn just off these forums and videos. Not my strong suit.
Is there any way you could point me toward a tutorial or ".... for dummies" for what you are explaining that will work in ver. 5?
So if you are new to graphics you should know that graphics cards render primitives. There are a few kinds, but triangles are the most common. To make a box for example, you create two triangles. To create five boxes, you create ten triangles. Each corner of a triangle is called a vertex, and can have different vertex attributes. In my example, each vertex has a position, uv coordinate and color associated with them. (Unity calls vertex position "vertex" so don't get confused by the SetVertices method). So, you upload a bunch of vertices (position,color,uv) and then a bunch of triangle indices. An index is a mapping that says which of the vertices to use. This is to reduce memory use. One triangle can share corner with another triangle. Ins$$anonymous$$d of uploading 2 vertices (two sets of position, uv and color), you ins$$anonymous$$d reference those vertices. This is what indices or "triangles" is. A lookup table.
So to define a triangle, you give it three indices. 0, 1, 2 for example, to create a triangle using the first, second and third vertex you uploaded. The second triangle could be 2, 1, 3, using the third, second and fourth vertex you uploaded. So you see, you can make a quad by sending 4 vertices and 6 indices.
Then to actually get anything rendered on screen you need to supply a shader and some textures etc. This is what a material is. It is basically "which shader do we want to use, and what properties (textures etc) should it get?" Unity uses a $$anonymous$$eshRenderer component to handle $$anonymous$$esh Rendering. The $$anonymous$$eshRenderer has a material you can set. The $$anonymous$$eshRenderer also looks for a $$anonymous$$eshFilter, to get a mesh. Once the $$anonymous$$eshRenderer has a valid material and a valid mesh, it'll render that mesh, with that material.
Hours of youtube video and pages upon pages of other forum material didn't explain that as simply and clearly as you did in just a few paragraphs. I'm definitely following you.
I'm currently a software major in a two year program so I've only been through basics of some of the major languages. Unity seems pretty in depth as far as all the ways you can interact with the components in your scripts. I think that's where I keep losing it.
This is incredible. Above and beyond any help I anticipated receiving on here. I can't possible thank you enough.
As far as using this option or the option of having a bunch of game objects, I trust your guidance. Your the expert and I know nothing about what would work the best. I haven't had the chance to jump all the way into your example yet, but for the sake of furthering my sketchy explanations..
I know this much: in the beginning my goal was something similar to ....
https://i.ytimg.com/vi/wmVNgHf87oo/mqdefault.jpg
I don't know whether its within my capabilities or not but I just want a top down, rooms, inaccessible walls(colliders?), follow the path to find the "stairs" kind of thing. We've been making our own grass and water etc tiles that are co$$anonymous$$g out pretty good. The best example I know for what I was ultimately shooting for was like ...
Once again, those kind of tiled worlds may be way over my head to implement, I was just furthering my explanation based on your allusion to another way to approach the problem. Whichever you feel would most easily and effectively accomplish a tiled board of my homemade "terrain" pngs
Thanks, it's nice to hear that the effort put into the work is appreciated. I also find it valuable to do complete examples as it becomes a coding kata for me (a good opportunity to practice skills).
One mesh is faster to process than a few thousand tiles. For performance reasons having one mesh would be nicer.
I think your goal seem reasonable. I don't know what the difference is apart from art style (I am a coder so I concern with code issues). It looks like rooms light up when you are inside them, and it should be pretty easy to add a lighting filter that implements SpriteTilemap.
It should be fairly easy to add "levels" to the system. Just think of it as having multiple AsciiTilemaps which you swap.
One way to do this is to extract the interface from AsciiTilemap, called IAsciiTilemap for example and then add a class AsciiTilemapWorld : IAsciiTilemap
which has a list of AsciiTilemaps. $$anonymous$$eep track of the current (loaded) tilemap and route all calls to GetTile and SetTile to current.GetTile and current.SetTile.
That way you don't have to change any of your other code.
To load a different Tilemap you could do something like
world.Load("Dungeon");
And the rest of the system should work as usual. Note that you need to update the mesh through builder.Update$$anonymous$$esh, so it could be nice to add an event to AsciiTilemapWorld to automatically update the mesh. Yes, I guess it may sound daunting if you are not experienced with events, delegates and interfaces but in practice it is pretty simple. I'll actually look into updating the example as I found it enjoyable to work on.
Here are the changes (comments, full project, Answer.cs) to add a world that contain multiple tilemaps.
For the most part, I understand whats going on in most of the scripts. Aside from some unity things that are a little over my head. I'm having trouble pinpointing the exact spot where you instantiate the sprites. $$anonymous$$aybe thats not the right way to say it. Basically, where does it say..
This is where my sprites are located....the png you created this is which one is grass and which one is stone
See SpriteEditor. You can also select the Tilemap texture and open the Sprite Editor on the button there.
When you have made some sprites, you can set them in the inspector of the script.