Let’s say you are fairly new to coding and you want to make a 2D game in Unity. You watch some tuts, you get excited, you come up with a concept, you make some art, you figure out how to create sprites, you make some game objects, you add behavior to those game objects, etc. Eventually you realize that part of your game needs to dynamically change the sprite displayed on an object based on a game event, like user interaction. It’s not an animation, you just need to swap the displayed sprite.
At first you might just have a bunch of object prototypes with sprites directly assigned to their SpriteRenderer. Then you just swap those objects out as needed. However, as your list of sprites grows, this quickly becomes a pain in the ass.
You are already using a
SpriteAtlas to handle your sprite sheet, so your next
move might be to simply add some dynamism to an object’s sprite renderer like
spriteRenderer.sprite = spriteAtlas.GetSprite(spriteName);
Cool! This seems to work great and was super easy. Also, it just looks right, so this must be what you are supposed to do.
You test your game out. You play for a while, do lot’s of interactions with lots of objects that update their sprites, and you start to notice the game getting slower and slower. After a few minutes it becomes unplayable. You try to exit the game and it takes 45 seconds to close.
Let’s take a look at the documentation for SpriteAtlas.GetSprite():
“Clone the first Sprite in this atlas that matches the name packed in this atlas and return it. The clone will use the packed texture of this atlas.”
Because you are new to programming you might not even really understand what this documentation means. You also may not have playtested your game long enough to see the leak. In fact, you may have gone to production and release not even knowing this was an issue, particularly if the number of objects and sprites isn’t very large, only to get crash reports from users.
If you did notice the leak through playtesting you might have turned to Unity’s much touted Profiler to figure out what’s going on. After reading the docs you record some gameplay through the editor then check the Memory category, which shows something like this:
What the hell?? 243 textures? I only have one! Half a gig of overall mem usage? What am I doing wrong??!?!
Of course, what you don’t realize is that the profiler is showing you what the Unity editor is using, not just your game. To accurately profile your game you need to do so against a stand-alone build, something the Unity docs don’t even cover.
I don’t want to rag on Unity too much. There’s a lot about Unity that is great and I love seeing all the amazing stuff that Unity is enabling.
But as an introduction to programming, it is just plain bad. The above example is only one of very very many. You can swap “sprite” for “material” and get another example, which is probably a lot more common since it impacts both 2D and 3D games. (Search for “unity material leak” if you want to become very sad.)
Which brings me to my primary gripe about the platform:
If you learn to program through Unity, you are going to be a bad programmer.
That is Unity’s fault, not yours.
Unity does not take it’s role seriously as a developer gateway. Which is a real shame because a lot of potentially amazing programmers are getting the shaft right when their enthusiasm should be transmuted into strong fundamentals.