First of all a little premise. We are making Empires in Ruins with pre-rendered 3d models that are turned into sprites and sprites sheets before getting into Unity. Long story short, this involves a pretty long and slow production pipeline, but allows us to use very high res textures to provide very sharp visuals. This style winks at the 90s strategy games of AoE (and ofc a lot of other ones), mixes it with Baldur’s gate production workflow and then adds some modern style and the option for the player to zoom in and out a LOT. Basically we love to show off.
I have to say, we ABSOLUTELY love the results this far, and people all across the web seem to like it as well, but there is a higher chance of us deciding to gold plate our crotches than making another game with this style after this one.
The reasons are simple: the results can be amazing, but it’s harder to find a slower workflow. So, for our very first game, it’s taking forever and we are loving it, ok lesson learned. For the future instead we forecast the need of producing maybe more than one game every five years.
For those still not believing me, here we go with a set of reasons that are behind my words. I would suggest reading them if you’re thinking about making an old school isometric-like strategy game with Unity3D.
I am sure you made all of your homeworks, and you finally know all the suggested (and usually very helpful) optimization technique for Unity production. Time to apply them to your new game, and see them failing one after another.
- Forget about batching if you want to have a working “depth” in the scene. Even two objects with the same sprite and same material, if they are at different depths (either in terms of z axis or in terms of sorting layer) and some other objects are in the position between them (and it will happen often), they will require each a drawcall. The sky is the only limit. PS forget about mobiles deployement because of that.
- If you chose 2D over 3D because the number of tris scared, don’t think, if you wanna use alpha-channel endowed sprites, that you will stay too low. Sprites with alpha, and therefore with irregular contour, can use a LOT of tris and vertices too.
- ALWAYS and ONLY use POT spritesheets. Specially if you want a high resolution and a high level of zoom in the game, this might be the only thing saving your game from being GB and GB of occupied space on disc (in Unity don’t forget to crunch your textures before the final build to help this) and video memory pretty soon. Not that with POT you will fit a build easily a floppy disk if your units have many frames of animation and multiple directions, but you might have a chance to occupy less space than MKX.
- Prepare for some math-endowed pain. You want to simulate 3d-like perspective trajectories of all kind while on a flat plane with an orthographic camera looking at it. Doable, but not as smooth as one could imagine at first.
- One huge pain will arise if you animations are slightly more complex than basic ones as well. Unless you break them down into a lot of sub-animations (with the consequence of humungous animators to control them), what happens, let’s say if you soldier attacks? Ok, it charges the hit, and at frame X of the animation it will have to cause the damage, play the hit sound, etc. Ok, so how to tell the game when does that happen? The only reasonable way it to attach an event to the animation, and till here it’s ok. But one big problem might not be obvious at first. You will definitely want your game logic to run on FixedUpdates (because that’s how it should run to be reliable and deterministic), but the animations run on the simple Update. Can’t you forecast any issue already?
- ALWAYS activate mipmaps for your textures. Don’t even ask why, automate the idea. Activate mipmaps unless you only allow a single predefined level of zoom in your game. Keep in mind that with mipmaps active, textures grow (TL:DR imagine having a 1024×1024 texture, when you generate mipmaps, Unity will spawn a 512×512, a 256×256, etc etc versions of it). I am not trying to explain you mipmaps but know they are needed.
- Pool pool pool objects. You’re trying to take away strain from the CPU, lots of Instantiate and Destroy calls are bound to be your best friends….NOT!
- You like Unity physics, don’t you? A pity that the gravity is not aligned nor can be aligned with your game world fake vertical axes right? So it’s life, unfair!
And in the very end, to summarize a bit :
- High drawcalls will be almost unavoidable. Drawcalls can create bottlenecks on CPU and therefore on the fps of the game. Solution is (good luck) to keep everything else belonging to the game logic as smart and lightweight as possible. Use coroutines, consider about having some operations not per frame but for example per x frames. Try and optimize for batching when you can, but be aware that for a lot of things you can’t.
- Big textures and big spritesheets mean a lot of videomemory usage. Keep that in mind and never stop aiming for a target maximum usage. True that computers nowadays are endlessly stronger than how they were few years ago only, but unless you are making a game for gamer highend PCs only (and you are probably not), any video memory consumption that risks going above 1 GB is nuts.
- Make sure you have very good animators/3d guys in the team, sprites animation is unforgiving and uncontrollable once it gets into Unity.
- Take a very good look at the Asset store for 2d-related ones. There is plenty of assets that for a few bucks can save you hours and hours of painful work and swearing, I guess you can imagine why it might make sense to buy them.
- If you have a life beside developing your game, pick another style.
- Unity profiler is your very best friend. Spend hours with it, it might make all the difference you need.
Now ok, I might be coming out of a very nasty week in which i had to charge face first against most of the above topics in the attempt to optimize the game. This might have not helped me in being nice or in sounding optimistic, even though i gotta admit that a lot of stuff got heavily improved now in these last few days.
If I said something wrong, please, really please, prove me wrong and give me a link to something that shows what I can do better. I really hope to be wrong and to find new ways to optimize further our game!