Creating a custom sprite animation script

Hey all,

It’s been a while (too long) since I’ve worked on game stuff, and I’m diving straight into something I should have attempted a long time ago: I want to make a custom sprite animation system because dealing with Mechanim has just been such a pain. I know I’m not the first person to come to that decision, and I’ve looked at other people’s posts on Unity Answers/forums to get an idea of what needs to be done. I still have question though.

My idea was to create an AnimationScript that looks like this (so far):

using UnityEngine;
using System.Collections;

public class AnimationScript : MonoBehaviour
{
    public Sprite[] frames;
    public bool loop = false;
    public float speed = 0.13f;
    private SpriteRenderer rend;
    private int currentFrame;
    public bool playing = false;

    public void Awake()
    {
        rend = GetComponent<SpriteRenderer>();
        Play();
    }

    public void Play()
    {
        StartCoroutine(PlayAnim());
    }

    private IEnumerator PlayAnim()
    {
        playing = true;
        currentFrame = 0;
        rend.sprite = frames[currentFrame];
        currentFrame++;

        while (currentFrame < frames.Length)
        {
            yield return new WaitForSeconds(speed);
            rend.sprite = frames[currentFrame++];
            Debug.Log("frame: " + currentFrame);
        }

        if (loop)
            Play();
        else
            playing = false;
    }
}

So the idea was that any animated sprite would have an AnimationScript member (or, more likely, an array of them for multiple animations). Then, the sprites of each animation would be set in the inspector. Doing it this way doesn’t quite work though because the AnimationScript member shows up as a script object in need of an object reference. How is this done then? Like, a public Vector2 member lets you set the x and y values in the inspector, so what do I need to do to make my AnimationScript behave that way? That’s the current problem with the execution of my plan.

I’m sure there are problems with the plan itself that I’m not seeing right now, but one potential issue I do see is that my method doesn’t actually save animations outside of the object they’re created for. This means that if I accidentally killed a prefab, all of the animations made for it would be gone too, and I’d have to re-assign all of the sprite frames.

Any suggestions? Thanks in advance!

The AnimationScript is a MonoBehaviour so if you want to modify its public members, add it to the game object, typically the one that has the sprite.

However, if you want to have varying sets of animations, you’ll either need to:

  • make your script aware of the different animation sequences (have multiple lists in there)
  • put multiple AnimationScripts on the object and write a manager to turn them all off and switch on only the one that you want.

This is all yucky, much yuckier than MecAnim, honestly. Yuck.

If you really insist on “rolling your own,” look into moving the animation frames data out of the AnimatorScript object and make the AnimationScript a simple “data player.”

Then you make a ScriptableObject (perhaps called FrameList?) and you can make instances of that contain sequences of sprites, then name them accordingly, and plug them into public fields in your data player animation script.

Still though, I’d recommend finding a way to live at peace with MecAnim. It might be that you are just not quite thinking about MecAnim the way it is intended to be used, and if you try and check out a few more tutorials on it, you might find that it will do you quite nicely for your job.

In relation to what I suggest in the paragraphs above, in the case of MecAnim and animations, what will effectively happen is that you will be using MecAnim and the Animator as the “data player,” and you will be using native Unity Animations as your “frame list” data object, which is exactly how it is intended. Data for the win.

Good luck!

1 Like

I don’t really see how mecanim is a problem for sprites. Linkages can simply stem from “any state” since there is no need to worry about animation blending, and states to change to can use a single integer parameter in the animator. All this applies as long as you are handling states via script, and mecanim is merely used to call what animations to play.

You haven’t specifically stated the problems you faced in mecanim, being the aims this script is meant to solve, so it’s hard to comment on whether what you’ve done is any better.

2 Likes