- Home /
Simple tile-map drawing to a simple canvas (using Unity GUI)
Hello everyone...
I've started exploring Unity couple of days ago, mostly because it has such a nice build system for every platform out there. Although, I must say, I'm not a huge fan of orchestration tools, helpers, editors, 3rd party libraries and I'm probably not needing 90% of what Unity has to offer.
Nevertheless, I want to port my Android game (prototype) to Unity now. It's a 2d turn based game, where map tiles (as id's) are stored in a simple array of integers. So when the map renderer iterates through the current visible part of the map array, it takes the tile id, looks up for the tile in another array (which holds the image data, and some other information) and draws the image to a canvas. Over those tiles there can be rendered also units, items, and some special effects like lights, explosions... etc. These special effects can be, but must not be aligned to the tile grid.
In Unity, I'm looking currently for a solution to simply draw images (sprites, textures or texture parts) to a simple canvas (or whatever it's called in Unity) with following features:
draw normal image to canvas
draw part of a image to canvas
draw rotated / scaled image to canvas
draw alpha / tinted image to canvas
After searching and watching tons of tutorials for days now, I'm surprised how there isn't a simple solution for the simplest thing in game dev. Either I must instantiate tons of GameObjects for each tile, which is a no go for me, or build the map as a 3d mesh, which is also a no go, because laying out units, items and effects over that would be difficult.
Yesterday, I've found a post where someone is suggesting to use the Unity GUI which works exactly as a Canvas on Android. You have to override OnGUI() in your script and then you can use GUI.DrawTexture, GUI.color, play with matrices and use GUIUtility.ScaleAroundPivot and GUIUtility.RotateAroundPivot. I've tried it out and it renders 2000+ alpha, scaled/rotated textures at 60+ fps which is more than enough for me. The only thing what's missing is to draw a part of a texture, but, theoretically, I could copy pixels from my texture atlas to 500 new smaller textures while populating the tile data.
Finally, my questions...
Are there any drawbacks for using Unity GUI as the main rendering mechanism only for the game play? I'm pretty sure it's not meant to be used for that at all :)
Can I lay other objects over the Unity GUI like lights which will affect then the GUI, particles, or 3d objects perhaps, additional canvases with menus, buttons, texts... etc?
Is Unity GUI checking at all the camera position / angle or it's simply laying out elements on a 2d surface which has the size of the screen?
Are there any other solutions for my needs? (I don't want to use other 3rd party libraries, tools, plugins or whatever)
Thank you very much for your help.
Cheers.
Answer by landon912 · May 22, 2017 at 08:55 PM
1) Unity's immediate mode GUI is a massive garbage generator. I'm just not sure why you'd want to use it in the first place.
2) Imediate mode GUI is unlit. It wouldn't have any effect on the outside world nor receive shadows or light.
3) Immediate mode GUI is strictly screen space in nature; however, Unity easily allows you to switch into any other space but you'd have to manage that aspect on your end.
4) Unity allows you to send GL commands. Alternatively, you'd need to make a batching/chunking system(but you've stated you're not interest in such). Otherwise, I'd recommend any of the other dozens of frameworks that are cross platform and seem like they would better suit your needs(something like openFrameworks).
Hello @landon91235
Thank you very much for your help.
I didn't know that the immediate mode GUI is producing so much garbage; the performance looked great in my tests. Although, I read somewhere that it should be used only for quickly showing some debug texts or images. I'll for sure make another test with instantiating 2000 GameObjects (Sprites) and then check out the performance. Have to find a optimal number of tiles which can be shown on screen at the same time, and then nail the camera max zoom out level to this value.
Cheers.
No problem. If the GameObject overhead is too much, look into the CommandBuffer class, it's probably a much better suggestion than using GL.
Your answer
Follow this Question
Related Questions
Draw minimap on panel 2 Answers
enable a canvas on trigger 2 Answers
Is making a 2d tile based game all in UI a bad solution or is it viable? 1 Answer
How to store remaining durability of tiles? Tilemap 0 Answers
Drawing a targeting reticule 1 Answer