Basic Skeletal Animation in Unity
I’m very lazy and dislike hand-animating. This is a problem in game development, so I have a workaround.
The above animation is skeletal instead of hand-drawn. Skeletal animation is nothing new, but at this resolution I can make it work effectively without looking like a mobile game. The trick is to use to make it run at a choppy 16 FPS, like most hand-drawn animations.
Why not use sharper, smoother vector animations that run at a smooth 60 FPS? Because we like looking at things that take effort. By lowering the visual fidelity, I’m hinting that each frame is hand-drawn, which is more work than what I’m actually doing here.
1. Add the pixel perfect camera
This is an official Unity asset available here. It renders everything to a smaller texture at runtime, so smooth edges will be automatically pixelated as they’re reduced.
An 800×450 target texture will work out to a pixel scale of 2:1 at 900p and 1080p. I import my sprites normally at 100 PPU, so each pixel is 0.01 units wide inside Unity.
2. Draw sprite atlas
Hey, wait, this looks large.
This atlas is drawn at 8x resolution and imported at 800 PPU. That’s because pixel art can’t hold its shape when it gets rotated, or else it gets jagged.
There’s a very simple way around this.
RotSprite is an algorithm for smoothly rotating pixel art. We can’t perform all of its steps at runtime in Unity, but we can do one of its essential pieces: scaling a sprite up by 8x before applying the transform. That’s why the original atlas is so giant.
Put each sprite’s pivot where it connects to its parent limb. Bicep pivot goes on the shoulder, calf pivot on the knee, etc.
Then build the hierarchy and shuffle sorting order as needed.
Build the character animation and use motion lines to signify when the hitboxes are active. Use a low sample count that pairs with your target animation frame rate.
That motion line is a script of mine, CircleRenderer.cs, wrapping a LineRenderer class. It’s performant and lets you key properties in an animation.
The material on the motion line is very simple; it’s this texture that’s been stretched with the Sprites/Default renderer.
5. Cut to target framerate
I modified this script, ToonMotion.cs to suit my needs. It affects the children of all of its transforms at runtime. If you want your character to move smoothly through the world with choppy sub-animations, make a child RigContainer object that contains the base rig and put the script on that.