Layering Sprite Renderers In Unity

I want to make this post real quick and short, because it’s late. But also, I’m more motivated to make a small blog post, compared to a really long one. Unless I really want to rant about somthing. Either way.

Animation has been a really painful thing for us to try and implement in Unity, and that is only because of how we need characters to be animated, and the tools that Unity provides by default. If we were building this game outside of Unity, there would be a lot of other legwork to be done, but the animations would probably be a lot easier to implement. Because Unity forces us to do animation in a specific way, and it also forces us to use “sprites” in a specific way, even if we wanted to use them an alternative way. And why take away creative power from devs?

“Well, if you do things this way, the engine will break. So we had to make it so you could only do things a certain way.“

This is not an actual quotation, keep in mind, but it is the only thing I can imagine as to why things are the way they are, because their legacy code is just ass backwards. And they won’t create certain API interfaces until they get their shit straight. Which is probably not true, and I’m missing somthing. But with perseverence, comes an eventual answer.

example.png

In Below The Stone, the character has an animation sheet; a texture with various frames of animation for the character. The clothing that the character can wear, also have their own textures with their own animation data. You can layer these textures perfectly ontop of one another and fully customize the player. The major problem is that animations in unity are based on the “auto generated” sprite objects of a texture. So for any specific sprite that is animated, it needs to have some “animation data” telling how it is to be animated. To keep the story short, I was originally annoyed at the fact that I was basically forced to create “animation clips” for EACH clothing piece. Which I never did, but instead I tried to come up with a better solution, and none seemed to really be elegant eanough to work for adding tons of different clothing pieces.

I will say this, if I had more experience outside of Unity, I would’ve had my epiphany a lot earlier, because the solution to my problem, is of coarse, UV coordinate sharing. Each texture is the same, and the sprites are all layered perfectly. So the UV coordinate for a particular sprite frame would be the same for each clothing piece. I just need to copy the UV for the body sprite, to the clothing sprites! Now how do I do that……

Turns out it’s not as simple as you would expect, and I still am not sure why they coudn’t have just made a simple interface for manually inserting your own custom “sprite rect uv” value in the Sprite Renderer, but I coudn’t seem to find anything in the docs. I did find somthing, but I gave me issues, but I may revisit that in the future. But I did find a solution which does work.

Essentially, you can set the sprite property on a SpriteRenderer, and then after doing that, reset the “_MainTex” shader property of that SpriteRenderer to the texture you want for that clothing. And it works!

This is my initial, very basic implementation of how I got all this to sync up.

example2.png

The thing that makes this work at its core is the “MaterialPropertyBlock” which your way to custom set material/shader properties for your SpriteRenderer. This is useful if you have a custom shader and you want to animate a certain value, although I bet you there is a more elegant way to do this that I haven’t discovred. As I always like to assume.

I just use Get/SetPropertyBlock() on the SpriteRenderer, and then use that to reset the Texture data after resetting the sprite data. The Sprite class holds the “rect” data that tells the shader which part of the texture to render, which is the particular sprite in the texture itself. So I am still using the sprite to set the rect data (since you are not allowed to change the rect data of a Sprite object). And then I alter the Texture data so it’s displaying the right thing.

The “SpriteLayerMaster” class just keeps track of the it’s children “SpriteLayer” classes. So they can all be manipulated all at once, from a single location. And I should be able to animate the player through the SpriteLayerMaster and have ANY clothing piece work properly without needing to create friggen animatioon data for each clothing piece. How redundant and stupid. Anyway, sorry for the mild anger. I’m really glad I found this solution.

If you want to use this in your own game, go ahead. Because I know we’re not the only ones with animated layered sprites like this. And this should be somthing that Unity should just support, having full controll of the SpriteRenderer and having full custom controll over it. Or giving us the ability to create our own Renderer classes, which it seems we are also not allowed to do, yet they give us a static GL and Graphics class to call manual render commands!

Anyway, have a good day!

Previous
Previous

ScriptableObjects Will Ease Your Sorrows

Next
Next

Ai is fickle, but it yields good results.