Unity3D: Replace Sprite Programmatically in Animation
Luigi says: Don't repeat yourself
Just starting out creating a 2D game using Unity3D, I came across a simple problem: There seems to be no easy way to swap out the sprite in an animation (think: Luigi using the same animations as Mario). It may seem simple to just create a new animation, but with many different characters (sprites) using the same animation it gets old fast. Read on for a short explanation and some code.
Note: A solution based on the same approach is also described in this video starting at 20:00. The link to the source code is broken, however.
It is assumed that you have already done the following:
- Imported the sprite sheets and split them up in sprites accordingly, making sure corresponding sprites have the same name
- Created one or more animations from the sprites
Now, in order to swap out the sprite programmatically, we create the following script and add it to the game object:
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
public class SpriteSwapDemo : MonoBehaviour
{
// The name of the sprite sheet to use
public string SpriteSheetName;
// The name of the currently loaded sprite sheet
private string LoadedSpriteSheetName;
// The dictionary containing all the sliced up sprites in the sprite sheet
private Dictionary<string, Sprite> spriteSheet;
// The Unity sprite renderer so that we don't have to get it multiple times
private SpriteRenderer spriteRenderer;
// Use this for initialization
private void Start()
{
// Get and cache the sprite renderer for this game object
this.spriteRenderer = GetComponent<SpriteRenderer>();
this.LoadSpriteSheet();
}
// Runs after the animation has done its work
private void LateUpdate()
{
// Check if the sprite sheet name has changed (possibly manually in the inspector)
if (this.LoadedSpriteSheetName != this.SpriteSheetName)
{
// Load the new sprite sheet
this.LoadSpriteSheet();
}
// Swap out the sprite to be rendered by its name
// Important: The name of the sprite must be the same!
this.spriteRenderer.sprite = this.spriteSheet[this.spriteRenderer.sprite.name];
}
// Loads the sprites from a sprite sheet
private void LoadSpriteSheet()
{
// Load the sprites from a sprite sheet file (png).
// Note: The file specified must exist in a folder named Resources
var sprites = Resources.LoadAll<Sprite>(this.SpriteSheetName);
this.spriteSheet = sprites.ToDictionary(x => x.name, x => x);
// Remember the name of the sprite sheet in case it is changed later
this.LoadedSpriteSheetName = this.SpriteSheetName;
}
}
By changing the parameter "Sprite Sheet Name", we can apply a different sprite sheet at runtime.
I hope you don't mind my terrible artwork. Have fun creating awesome games!
Update:
It happened - the game is released!
39 Comments
Subscribe to new comments by RSS