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

Efficient Tile Map for Platformer

Discussion in '2D' started by ErnestoBananez, Sep 23, 2014.

  1. ErnestoBananez

    ErnestoBananez

    Joined:
    Sep 23, 2014
    Posts:
    16
    Hey everyone, I need to find a way to create tile maps within Unity for a 2D pixel art platformer. There are a lot of options out there for how to do this, but I have some stipulations. These maps must:

    · Be able to be very large without causing slowdown*

    · Be made out of many small individual sprite objects that:

    o Come from one or more sprite sheets

    o Line up exactly within the Unity scene, so that the background is never visible between them**

    o Once placed in a scene, can have components added and deleted like any other gameobject

    o Can have their positions within the scene edited within Unity without causing problems

    I’ve scrounged a few messageboards and it seems like the Tiled editor is what keeps getting pointed to, but it seems the only ways I’ve seen for that to work with Unity force you to build the entire tile map and then import the whole thing as a prefab, which doesn’t let you work with individual tiles within Unity scenes. This of course fixes the problem of slowdown (the map is one object instead of 50,000), but it doesn’t allow editing within Unity.

    Thanks, any help or pointers you can give would be super appreciated!

    * I realize this might be a problem external to the building of the map itself, possibly involving disabling certain components once objects are out of the camera’s frustum, but I’m not sure.

    **Unity’s object placement within a scene isn’t pixel-perfect, so any time I try to make my 16x16 or 32x32 sprites line up, it looks pretty bad. I downloaded Pixel Perfect to fix this, but it seems to cause collision problems if it’s on two objects that are colliding.
     
  2. Deleted User

    Deleted User

    Guest

    Well is not easy, having too many gameobjects with even their own components will inevitably slowdown the whole thing, I think there is also a limit to the number of gameobjects unity can take (I think it was 5k, but not sure).

    I'm working on a 2d sidescroller and had to find a way to be able to do what you are doing, maybe with less stuff. I use small chunks for the map layout, a chunk have 16x16 tiles with 16x16 pixel individual tiles, this to save some performance by not displaying too many vertices at once and have the dynamic batching taking care of the chunks on screen.

    I don't use sprites , but normal meshes that are combined toghter, so the chunk is one mesh. All the interactive stuff like items or activators are normal sprites.

    About the lining up you may have to write your own tools to achieve that, you need to do some math with your camera to get a pixel perfect aspect, but even with that you may still notice small gaps or texture bleeding, for that you need to be extra carefull with the camera and the scale of your sprites. Consider that you have to do a conversion from world space coordinates to screen pixels, there isn't an automated way.

    For having components on all tiles, as I already said is a bad idea for obivious reason on performance. I would suggest something diferent, using a list of classes representing the tiles that are not derived from monobehaviour. I'd suggest to take a look at the htread called "After playing Minecraft" on the Unity Gossip section, you will find a lot of usefull informations about that with examples adn hints.

    Another method is by pooling the same objects and move them. For example you have a series of tiles thatmay repeat on the map, instead of having them already in place just move the ones that are offscreen but are of the same type. Is a bit overcomplicated and honestly I don't know where I would start with that.

    Another thing is by using the Tiled editor one object map and mix toghter the above suggestion of Minecraft plus marching cubes algorythm to destroy or manipulate parts of the mesh.

    Lastly even if I'm not too fond of suggesting assets from the store, this guy did a nice tile editor within unity:
    http://forum.unity3d.com/threads/sp...works-with-unity-4-3-sprites-released.216642/
     
    ErnestoBananez likes this.
  3. ErnestoBananez

    ErnestoBananez

    Joined:
    Sep 23, 2014
    Posts:
    16

    Thanks so much! This gives me a lot of info to work with.
     
  4. Shadeless

    Shadeless

    Joined:
    Jul 22, 2013
    Posts:
    136
    Here are some stuff I've written down.

    1. Pixel Perfect Issues
    It's easy to get Unity's Camera to be pixel perfect while it's stationary. However, the issue arises when the camera starts moving and you can notice pixel distortions happening on the sprites. After extensive testing I have come to the conclusion that the problem is the Unity Camera's floating point precision and not the sprites themselves. Basically, Unity's Camera moves in floating points so it generally moves in sub-pixel levels which I believe are causing some distortions.

    This is everything I've done to achieve the closest to pixel perfect you can get while the camera is moving.

    - Importing the assets with the proper Texture Type (Sprite), proper Pixels to Unit (the power of two size for your tiles), proper Filter Mode (Point), proper Max Size and Format (Truecolor).

    - Adding a Material to the Sprite Renderer which uses the Shader: Sprites/Default and has Pixel Snap turned on.

    - Setting the camera's orthographic size to the proper size for the target resolution using the well-known formula.
    ((resolution height / pixels to units) / 2)

    - Adding a script to the camera which rounds the camera coordinates to the nearest floating point matching a pixel as it's following the player. And optionally adding a damping effect to the camera so it smoothly approaches the player position.

    Here's the code for rounding the next position of the camera, if it's following the player. Of course you have to create the variables.

    Code (CSharp):
    1. public static float RoundToNearestPixel(float unityUnits)  
    2.     {
    3.         float valueInPixels = unityUnits * pixelToUnits;
    4.         valueInPixels = Mathf.Round(valueInPixels);
    5.         float roundedUnityUnits = valueInPixels * (1 / pixelToUnits);
    6.         return roundedUnityUnits;
    7.     }
    8.  
    As for the tilemap, I just create Tile GameObjects from the tile sheet, and then tile them programmatically with a simple for loop while reading the tile type from a two dimensional array. Unity does take care for the culling (removing tiles which are not seen by the camera for rendering). I don't know how effective it would be for a very large game tho. Maybe a chunk based mesh tilemap would work good. Something like that in this tutorial http://studentgamedev.blogspot.com/2013/08/unity-voxel-tutorial-part-1-generating.html

    Hope this helps.
     
    bob_bobbington likes this.
  5. Kiori

    Kiori

    Joined:
    Jun 25, 2014
    Posts:
    161
  6. bugmagnet

    bugmagnet

    Joined:
    Apr 16, 2013
    Posts:
    48
    I made this tool here: https://www.assetstore.unity3d.com/en/#!/content/17260/

    It can do pretty much everything you want, except these two together:
    -Be able to be very large without causing slowdown*
    -Can have their positions within the scene edited within Unity without causing problems

    You will have to choose ONE because these two are mutually exclusive. (whether you use my system or not).

    The problem is that maps with many individual tile objects cause many draw calls. You can optimize this by making them all use the same single material, and marking them 'static'. This will only take you so far, though. To really have tons of tiles on screen at once you will need to combine them yourself after they have been placed by whatever tile system you use.
    But of course, this makes changing them afterwards a problem.

    I know this because I am working on a game right now that must have about 4000 3D tiles on screen at once and must stay at 60fps.

    However, the best fix for you if it is at all possible is to simply not show them all on screen at once. If you can manage the game to only show maybe less than 300 at once, then you won't have much to worry about and having thousands of editable tiles in a huge map should definitely be possible... and Tiled to Unity, (or possibly another system?) should work well for your purpose.


    EDIT: oh and another possible workaround... since you are doing a 2D map.... is maybe manage your own grid meshes for the map (ie, manage the verts and UVs yourself). Then, you can change the materials of each face and move the UV's around to cause the changes you want and the map could be pretty big. Each grid will be limited to about 180 x 180 tiles since that will be about Unity's max poly count for a single object. (note: Tiled to Unity is probably not the best tool to use for this)
     
    Last edited: Sep 25, 2014