Featured Blog | This community-written post highlights the best of what the game industry has to offer. Read more like it on the Game Developer Blogs or learn how to Submit Your Own Blog Post
Luckslinger tech #1 - How to make 2D Sprite Animations in Unity
We explain our simple (yet effective way to use 2D sprite animations in Unity, we've used the same system for Luckslinger. In this post I’ll just go over the basics and explain how we use the basic 2D animation system.
So we've just released Luckslinger on Steam and some people were curious about the ‘system’ that we use for doing all the sprite-animations in the game. Actually the basics are quite simple, but after that it gets a bit more complicated. For this post I’ll just go over the basics and explain how we use Unity’s Sprites to make simple(and later complex) 2D sprite animations.
Basically how it works is that, we make the animations in Graphicsgale and then export it as a full png. So that the whole animation is in one image. Then we import it in Unity as a Sprite with ‘Multiple’ sprite mode, we then cut all the frames of the spritesheet correctly and filter as point and set the Format to Truecolor.
We then create an ‘SpriteAnimation’ in Unity and then add the ‘Animation2D’ component to it, we then add all the cut sprites in the array, do the settings, press Play in Unity and voila!
So how does this ‘Animation2D’ component work? We’ll make it right now!
So I’d say, create a new C# Class in your Unity project and call it Animation2D.
First of all, we’ll need to add some settings to the Class.
public float FPS;
public bool isLooping;
public Sprite[] frames;
public bool playOnStartup = false;
private SpriteRenderer outputRenderer;
private float secondsToWait;
private int currentFrame;
private bool stopped = false;
Most of these variables are quite self-explanatory, you can set the FPS in the editor, set if it’s looping or not, set drag the correct frames for the animation and choose wether the animation will play when the scene loads. And the private variables are more for internal stuff.
So where do we go from here? Create an Awake function for your class (void Awake()) and it should look like this.
public void Awake () {
outputRenderer = this.GetComponent<SpriteRenderer>();
currentFrame = 0;
if(FPS > 0)
secondsToWait = 1/FPS;
else
secondsToWait = 0f;
if(playOnStartup) {
Play(true);
}
}
What happens here is that firstly we grab the SpriteRenderer which should also be added to the GameObject which contains this script, then we just reset the frame and set the secondstoWait. If the ‘playOnStartup’ is set to true, then the animation will start playing instantly. (otherwise you can make it play from somewhere else by calling the ‘Play’ function which we’ll make in a second.
public void Play(bool reset = false) {
if(reset) {
currentFrame = 0;
}
stopped = false;
outputRenderer.enabled = true;
if(frames.Length > 1) {
Animate();
} else if(frames.Length > 0) {
outputRenderer.sprite = frames[0];
}
}
I guess most of this function also explains itself, I just reset some variables and check if there are more than 1 sprites into the array of animation sprites. If so, then start playing the animation, if not, then just set the sprite to the outputRenderer so it’s a still animation.
So next up if the final part, and the ‘core’ part of the Animation2D class, and can be used to add more functionality to the Animation2D class (as we have!)
public virtual void Animate() {
CancelInvoke("Animate");
if(currentFrame >= frames.Length) {
if(!isLooping) {
stopped = true;
} else {
currentFrame = 0;
}
}
outputRenderer.sprite = frames[currentFrame];
if(!stopped) {
currentFrame++;
}
if(!stopped && secondsToWait > 0) {
Invoke("Animate", secondsToWait);
}
}
So this function is called by ‘Invoke’ and first of all Cancels any Invoke that might have been called (so that the animation doesn’t mess up by accident). Basically what it does is increment the ‘currentFrame’ counter by 1 and then takes the sprite in the animation’s array at that index and applies it to the output.
And it checks if you want it to loop. If you want it to loop and the counter is longer or equal to the size of the animation array, then it will reset. If not, it will just stop.
And then if the animation hasn’t stopped yet it will use Invoke to re-call the Animation function.
I guess you could easily make a ‘Stop’ function which Cancels any Invoke of ‘Animate’ and sets ‘stopped’ to true.
Horse running animation in Luckslinger made with this system
That’s all for now, if you have any question or so feel free to email (duckbridge.dev[at]gmail.com) or comment. This animation class is quite simple, but we built our whole animation system based on this little class here!
I guess I could do more of these posts about more code-stuff of our game, like the loading system, saving system, some minigames, Ui stuff, some AI stuff, whatever.
My name is Marciano Viereck and I’m the programmer at Duckbridge and we’ve recently released Luckslinger on Steam. (with a 2 man team)
Read more about:
Featured BlogsAbout the Author
You May Also Like