Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

2D game based on tilesets - looking for direction

Discussion in '2D' started by Craiglowdon, Sep 16, 2014.

  1. Craiglowdon

    Craiglowdon

    Joined:
    Nov 17, 2013
    Posts:
    4
    Hello,

    My name is Craig and I am looking to get unity experience and build a game based on an idea I have had for a while. I have some OOP experience and use .net applications at work, mostly c#. I have also got some experience with C++ from a developer course and I wrote some very small games with microsofts XNA tools (c# again but with some pre-built code).

    I know what I want to do is relatively easy but I want it to be as tidy as possible and want level creation to be simple and allowing player level creation. I don't have much experience with tilesets (slight experience using things like gamemaker a long time ago and other drag and drop programs) but I have looked around and found a few things.

    What I would like ideally is to implement tilesets from scratch, however I can't really find much on how to do that from the point of a blank project, a video tutorial would be ideal. I notice there are things in the unity store to help me and probably already have the functionality and more for what I want to do, but as I am on a developer course and coming up to a project I should really be looking to do this for myself to bump it up.

    Any help at all would be greatly appreciated, even if it is just a link to something that I should have found on google! (but I promise I tried :))

    Thank you,
    Craig
     
  2. Shadeless

    Shadeless

    Joined:
    Jul 22, 2013
    Posts:
    136
    Hey Craig,

    I totally understand what you mean. I came to Unity from XNA as well. And while there are tons of premade assets in the Unity store, I prefer to do it myself so I can get more experience in the subject.

    I've found that the information for 2D games based on tilesets and tilemaps is surprisingly lacking. When I switched to Unity I got the impression that there are tons of resources for it, but most of them were for 3D games and not the new 2D system with sprites. And the fact that Unity updates so frequently (which is a good thing), makes a lot of resources outdated. (Although some still apply)

    So far I haven't been able to find a 2D tilemap tutorial using 2D sprites tilesets for Unity. Let me share some useful resources I've found until now.

    The first tutorials that I did find were from the user Quill18creates on YouTube. He has a long series of mesh-based tile map tutorials and shows a bit of procedural generation as well. However, I feel that the tutorials on studentgamedev are way better and helped me understand a lot more. http://studentgamedev.blogspot.com/2013/08/unity-voxel-tutorial-part-1-generating.html
    First, he created a mesh based tile map. (which you could use for 2D games) And then he goes to create a voxel "engine" (you know like Minecraft) which is really cool.

    The issue that I encountered was that they used Mesh Colliders, which you can't use with the 2D Physics system (You could use the 3D Physics system on 2D stuff though), but I really wanted a sprite based solution that works with the 2D Physics.

    This is where the fun starts. Since I've not been able to find tutorials for 2D sprite based tile maps together with the 2D physics system I improvised, and there are a lot of issues. ( If anyone has any information or resources, I'd really appreciate if you shared or helped )

    First, I import the tile sheet with the proper Pixel Per Units (so 1 tile is 1 unity unit), and create Tile game objects for each tile I have in the sheet. Place them at (0, 0, 0). You can add colliders to the tiles now, or add them programmatically, just where colliders are needed, cause some tiles will be inaccessible. Then make them into prefabs.

    Then, I create an Empty Game Object and add to it a TileMap script. Now you need to reference all the Tile prefabs (public GameObject tileName). The tile map script reads from a text file that has the information for which tile goes where. Like so:

    1 1 1 1 1 1
    1 1 0 0 0 0
    1 1 0 0 0 0
    1 1 1 1 1 1

    Where 1 is a solid tile ( wall ) and 0 is a passable tile ( background wall ).

    Then I use a for loop to tile everything based on the text file info.
    Code (CSharp):
    1. for (int x = 0; x < tileMapSize; x++) {
    2.     for (int y = 0; y < tileMapSize; y++) {
    3.         if(stringArray[x, y] = "1")
    4.         PlaceTile(x, y, Wall);
    5.         if(stringArray[x,y] = "0")
    6.         PlaceTile(x, y, BackgroundWall);
    7.         }
    8. }
    I'll stop here, hope this helped.

    Just a note on the issues that I had:

    1. Unity's camera is not Pixel Perfect, so while moving the camera your sprites could distort, or you might get weird lines separating the tiles in the wrong aspect ratio. I have a temporary fix, but I'd like to find a good fix.

    2. If you use colliders on all of your tiles you might get some weirdness. For example the character might bump while walking on the floor, cause the floor is a lot of floor tiles with separate colliders. (I'm talking about a side scroller)

    3. Thank you Unity Technologies for all the beginner content, and no intermediate or advanced tutorials, thank you for teaching me how to move a character 20 times already. And no 2D pixel perfect camera for 2D games. Thanks for the free software though. :p

    Cheers
     
  3. JanDawid

    JanDawid

    Joined:
    Jul 7, 2014
    Posts:
    283
    Hi Craig,

    My method on making a tileset-based 2D game is to have basic shapes, each with a single collider on them, and have a code draw all the tiles along it. For example, I have a 64x64 empty block with a box collider. The block is stretched along it's x-axis and depending on the x-scale it will instantiate the tile (which is a prefab that only has a transform and a sprite renderer on it) along the empty block.
    You'd want to code something like this for a 64x64 tile:

    (for when the x-scale is odd)
    int i = 0;
    while(i < transform.localscale.x / 2)
    if(i < 1)
    instantiate(tileSprite, transform.position, transform.rotation);
    if(i >= 1)
    instantiate(tileSprite, new Vector2(transform.position.x + (i * 64), transform.position.y), transform.rotation);
    instantiate(tileSprite, new Vector2(transform.position.x - (i * 64), transform.position.y), transform.rotation);
    i ++;

    (for when the x-scale is even)
    int i = 0;
    while(i < transform.localscale.x)
    instantiate(tileSprite, new Vector2(transform.position.x + (i * 32), transform.position.y), transform.rotation);
    instantiate(tileSprite, new Vector2(transform.position.x - (i * 32), transform.position.y), transform.rotation);
    i += 2;

    And of course, you may want to take into account the empty block's rotation and whatnot; and as for slopes, you may want to adjust the y values accordingly too.
    I've found that this is a very efficient way of building a tile-based game; it's only called when the level is loaded, it uses only the colliders of the empty blocks that you build the level with, and it makes building levels MUCH faster as you only have to build it with the basic building blocks.
     
  4. Craiglowdon

    Craiglowdon

    Joined:
    Nov 17, 2013
    Posts:
    4
    Hi both, thanks for the reply. I am now half way through the tutorial on studentGameDev and it is really helpful.

    I think I am going to use something similar to that and the text file approach or similar to create my scene, my needs for this particular game are not particularly great as I will most likely only need a static tileset, however it is slightly different in the fact that it is a top down game and not a platformer.

    Given what I see here I think i might approach it a little differently, create my colliders and other modifiers as appropriate and have my player "fall" onto the floor anyway as if it was a side scrolling platformer.

    I was wondering what the point is of creating the mesh in that way, could you not instantiate a plane to get the same result? or a box in the case of a 3d example? is it something to do with performance?

    Jake,it seems like you have done something more similar to the above but I am not sure how I could use that to define additional properties to my blocks.

    I think i'm going to create a block array in which I can set each of my blocks up similar to how the tutorial did, except instead of using bytes I would use a block game object which has some set properties including the texture position from the tilemap. I will continue thinking about different ways to achieve it but I just wanted to say thanks for the link as it was a real help.
     
    Last edited: Sep 17, 2014