Unity 2D : Can you change a 2D animation clip's sprites at runtime?

Hi there,

I’m working in Unity’s 2D mode and using the Unity UI I’ve created a GameObject with an Animation Controller (Animator) linked up with six different Animation Clips. While running the game this GameObject properly transitions between all of the animation clips.

I’d like to use this object as a prefab. At runtime I want to clone it and swap out the sprites being used for the animation clip key frames.

In other words I have object A that uses a Sprite_Sheet_A. Now I want to clone Object A and start using Sprite_Sheet_B.

Once I clone object A how can I access its Animation Controller, view the Animation Clips being controlled and swap out their sprites?

EDIT: When I say Animation Clip… I might mean Animation. The difference between these classes in 2D is not super clear for me.

You CAN do this.

All you need to do is to change sprite in the LateUpdate() method.

PS: Late 2018 update. The solution is still very useful. I shipped 2 games using it and will use it in future. The performance drawback is not noticeable at all. But you may consider the following optimizations:

  1. You can cache the sprite. And if it was not changed from the previous frame, you don’t need to replace it again.
  2. You can consider creating a hash of name-sprite pairs. So, you will get a “sprite by name” faster later (considering that your animation probably will need to make the same operation over and over again on the same object).

There is a better solution. Use this script - GitHub - RetryEntry/UnityAnimatorChangeSprite: This script will swap sprite of an active animator to another one with the same dimensions.
Please give thumbs up, cause I have spent two days searching through useless solutions like one that soulburner suggected.
If you have 15 gameobjects with 15 sprites in animation chain you will spend up to 225 loops every frame searching for sprites to swap to…
With such approach you CAN’T create for instance charactes with different clothes animated by one animator, cause you will spend 12000 loops every second on useless things like searching. With this script you will not spend time… It uses shaders. You can change it as you’l like, Just star please. I have spent two days… :confused:

Edit: See the accepted answer for a better solution

Animations are stored in .anim asset files. As such, there is no easy way to modify them at run time. My recommendation would be to create multiple .anim files with the variations you desire and then swap them out on the fly at runtime.

I use a script like this to swap sprites out

using UnityEngine;
using System.Linq;
using System.Collections;
using System.Collections.Generic;

public class SkinController : MonoBehaviour {

    private new SpriteRenderer renderer;
    public List<SpriteCollection> skins = new List<SpriteCollection>();
    public int skin = 0;

    void Start()
    {
        renderer = GetComponent<SpriteRenderer>();

        //First thing we must do is load all the sprites for the character
        foreach (SpriteCollection coll in skins)
            coll.sprites = Resources.LoadAll<Sprite>(coll.sheet.name);
    }

    void LateUpdate()
    {
        //Select the correct sprite
        SpriteCollection coll = skins[this.skin];

        //Get the name
        string spriteName = renderer.sprite.name;

        //Search for the correct name
        if (coll == null || coll.sprites == null) return;

        Sprite newSprite = coll.sprites.Where(item => item.name == spriteName).ToArray()[0];

        //Set the sprite
        if (newSprite)
            renderer.sprite = newSprite;
    }
}

[System.Serializable]
public class SpriteCollection
{
    public string name;
    public Texture sheet;

    [System.NonSerialized]
    public Sprite[] sprites;
}

I had the exact same problem in my own project and I was able to solve it with an editor tool which works like this:

  1. Read the contents of a user-selected Animator Controller asset
  2. Read and store sprite-related keyframe data (original sprites, frame time) from the Animation Clips which are referenced inside the Animator Controller asset
  3. Find original spritesheet texture assets used in those keyframes
  4. Allow user to select the replacements for those original spritesheet texture assets
  5. Generate a Scriptable Object containing all sprite-related keyframe data with equivalent sprites from user-specified sources for each animation state along with the state hash

The generated Scriptable Object asset can then be used to override the sprites set by the Animator component during runtime by checking the current animation hash and picking out a replacement sprite from the Scriptable Object.

This way you are able to reuse the same Animator Clips and even the Animator Controller for any amount of animated objects which differ only in spritesheet sources.

You can find my solution to this problem here:
https://assetstore.unity.com/packages/tools/animation/animator-sprite-swap-system-159842

What if i have an animated character as a sprite sheet (no bones)
After game is launched i want to add new skins so i upload to the internet. The game will look for skins in the folder download them and save as a texture. What can i do from there? apparently i cant slice up that sprite sheet at run time nor can i swap the frames in the “idle down” or “walk left” animations. Are there any solutions for this? I dont want the user to keep having to download an update every time i create a new character skin.

So I made an unlit shader similar to the solution posted by @retry_entry. It doesn’t require light in your scene. Check it out here (follow the README to make it work): GitHub - NPVallejos/SwapSpriteSheetShader: Want to change your character sprite but keep the same animations? Then this is the shader solution for you!