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

Creating 2D game with a very long ground surface sprite

Discussion in '2D' started by noambe, Sep 13, 2014.

  1. noambe

    noambe

    Joined:
    Aug 13, 2014
    Posts:
    32
    Hello,

    My 2d game consists of a very long "surface" sprite - with many hills and falls. This is eventually the ground surface where the players walks on (I define it as Poligon colider 2d). The height remains the same but the camera keeps track over the walking person horizontally.

    For that I created a very long sprite - 204800 (width) by 1024 (height).

    Of course that unity can't have sprites longer than 4096, so I know I need to split them to (4096x1024). But then I need to place the sprites pieces one next to another, and for each sprite add the "Poligon Colider 2d" component and place it exactly next to the previous sprite piece. I need to do that 204800/4096 = 50 times :(

    Is there a better way or automatic way to achieve that?

    Thanks,
    Noam
     
  2. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Does that really need to be a unique image? I expect you'd be better off with a tile system, since many huge textures is going to use a lot of memory and be difficult to work with.

    --Eric
     
  3. noambe

    noambe

    Joined:
    Aug 13, 2014
    Posts:
    32
    I'm still new to unity so I'm not sure what a tile system is - but my "terrian" is pretty random so tiles doesn't sound right here - see attached image for clarification.

    I could obviously reduce its size but then the screen width will be very short.

    Any other suggestions?
     

    Attached Files:

  4. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    If tiles aren't appropriate, then maybe a 2D terrain system like this.

    --Eric
     
  5. noambe

    noambe

    Joined:
    Aug 13, 2014
    Posts:
    32
    This actually don't solve my need - I want an finite and fixed terrian where I can see and edit it on the unity designer...I don't want it to be created dynamically.

    I'm just looking for a way to plan a long (fixed) terrian in 2d.
     
  6. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    That was just the first one I found with a search; there are others. Do a search for Unity 2D terrain.

    --Eric
     
  7. GarBenjamin

    GarBenjamin

    Joined:
    Dec 26, 2013
    Posts:
    7,441
    Looking at the image you attached (bottom_surface.png) I think a tile map is perfect for your needs.
    By using tiles you could reduce the memory requirements dramatically.

    If you don't want to implement your own map editor and tile display engine then search the asset store for "tile":
    https://www.assetstore.unity3d.com/en/#!/search/tile

    I bought SpriteTile a month or so back and it is very good. Check out the web player demo.
     
  8. noambe

    noambe

    Joined:
    Aug 13, 2014
    Posts:
    32
    I'm not that familiar with what a tileMap is, and how do you create a 2d world with it. Could you please describe briefly what it is?

    Also, why does a tileMap dramatically reduces memory consumption? How can I tell the current memory consumption I have?

    Thanks!
    Noam
     
  9. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Tile maps are like building blocks, where you put together a level from blocks. So instead of having a massive texture that uses a huge amount of RAM, you have a number of small textures (which can be combined into a texture atlas), and each block points to one of the textures. This way you can have far bigger levels, and more of them, which use far less memory. The downside is that since you have a limited number of blocks, there's noticeable repetition since you're using the same textures all over the place. However the image you posted is mostly a repeated texture anyway, so it's not a good case for having every pixel be unique.

    --Eric
     
    noambe likes this.
  10. noambe

    noambe

    Joined:
    Aug 13, 2014
    Posts:
    32
    Thanks for this great info - now its more clear. There are many advantages to this approach, however as you say the downside is having less flexibility in creating the terrain, for example sometimes I want a terrain with 10 degrees, sometimes 15 degrees - so I need to create a tile for each on of them. That's lots of graphical work but once you have it its rather easy.

    Suppose I do have all the tile textures I want - is the "tiles map" editor exists in Unity 2d designer or I need to purchase an editor plugin?

    Thanks,
    Noam
     
  11. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    The Unity editor doesn't have any built-in tilemap functionality.

    --Eric
     
  12. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,520
    Keep in mind the sprite you are proposing to keep around (204800 x 1024) is going to require over 800mb (megabytes!) of RAM to decompress and keep in memory as RGBA 32 bit. That is a little bit ... heavy.

    I tried creating such an image on Gimp and it complained that it exceeded my maximum memory cap of 132mb.

    It might be easiest to write a tool that chops your terrain into chunks, something that Unity handles nicely, such as 1024x1024 for instance.

    chunk001.tga
    chunk002.tga
    etc.

    Then write code to keep two or three of the chunks instantiated at once, each with their own polygon2d colliders, and everything else invisible, standing by and ready to come in when the player gets near it.

    As your player moves, you know which chunk you are actually standing on by dividing your X position by 1024, and then say "I need this one, and enough chunks before and enough after to fill the screen."

    Any others can be discarded until the player travels over that chunk of land again, and then you can load the asset back in and instantiate the necessary sprite(s).

    Or, as was pointed out above, go to some kind of tilemapping system. :)

    Kurt
     
  13. noambe

    noambe

    Joined:
    Aug 13, 2014
    Posts:
    32
    Kurt - just saw your post. Thanks !

    I started going in the way you suggested. I've created a long sprite in Photoshop, and split it into chunks of 4096x1024.

    Then I laid them one next to another in Unity and actually the game ran alright - how can I tell how much memory it consumed?

    In order to reduce memory consumption - all I need to do is hide these sprites programmatically? Isn't a hidden sprite requires the same amount of RAM? Because I guess that once the game is up, before I get the chance to hide - it already loaded them to memory.

    As for the tilesmap - I ended up with a very unique layout - one that can't be created with a bunch of tiles. So I have no choice but to keep with this way...
     
  14. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    No.

    Correct, hiding will not reduce memory usage at all.

    Look at each texture in the inspector, and it will tell you how much memory it uses.

    --Eric
     
  15. noambe

    noambe

    Joined:
    Aug 13, 2014
    Posts:
    32
    So it seems like every sprite piece is 4MB (I use 4096 size compressed). And if I have 50 it means 200MB. Indeed sounds a lot.

    So your suggestion is not to embed them in the unity designer at all, and run code that programmatically places the sprites when required, with "Sprite.Create"?
     
  16. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,520
    If you have the sprites in the scene, yeah, they will consume the RAM.

    I used a vague term "hide," when what I meant was "destroy" sprites that you can no longer see, and stream in ones that you need to see. I mean write code to do those two steps dynamically based on where the player is laterally.

    But hey, 200mb is nothing on a modern desktop. It only becomes an issue if you want to go to mobile. If it works for now, leave it and thunder ahead and finish your game, and only bother to go back if it causes you problems otherwise!

    Kurt
     
    noambe likes this.
  17. noambe

    noambe

    Joined:
    Aug 13, 2014
    Posts:
    32
    Actually I am building for mobile. So I need to test is properly on various devices...

    But one question - currently when I put the sprites on the scene and assign them a 2d polygon collider, I make some manual adjustments to it, to exactly represent the lines and curves. If I load the sprites dynamically and assign the colliders - this will be without my adjustments.

    Anyway to store my sprites & adjustments and only then load them?

    Regards,
    Noam
     
  18. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,520
    Yes indeedy... Prefabs! :)

    Kurt
     
    noambe likes this.
  19. noambe

    noambe

    Joined:
    Aug 13, 2014
    Posts:
    32
    Alright, I think you answered all my questions :)

    Thanks!
     
  20. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,520
    As an aside for quick-and-dirty memory testing, try making a small number of your prefabs, say five of them selected so that they can be looped end-on-end, and then physically clone-copy the sprite graphics and prefabs 40 times to come up with a total of 200 separate prefabs.

    Then run the game engine with a trivial script to go left and right and stream in/out the sprites, and make sure you can go from left to right on the platform you want to run on ultimately.

    That way you won't hassle with making the collision for 200 prefabs only to find it won't work for you.

    Kurt

    PS - not sure if Unity is clever and hashes bitmaps to try and eliminate dupes, such that if it saw 40 copies of five identical bitmaps, it might only include five bitmaps, with enough references to appear you have 200. To get around this, you could write a little program to change one random pixel of each of your test graphics frames, to ENSURE that they are indeed unique.
     
  21. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    The concept of references is that you have pointers to assets; using the same texture on two objects does not duplicate the texture or anything, you just have two objects that point to the same texture.

    No, that would be bad, since it's quite possible you'd want to start with multiple identical bitmap instances and then change them in unique ways later. It's best when Unity just does what you tell it to do and not try to be "clever" because it's guaranteed that will screw things up. (As evidenced by renderer.material, which when accessed by, say, changing renderer.material.color, cleverly makes new material instances for you behind the scenes, which over the years has resulted in many posts on the forums and Answers asking about what's going on.)

    But as mentioned above, if you duplicate a prefab, then the only memory used is for an additional GameObject instance (not much).

    --Eric