Hi,
I’m trying to build multiple skins, for the hero character, into my game.
I can’t really figure out exactly how to do it though.
Basically, the move animation is the same on all of them, so each sprite is a spritesheet with 3 pictures in it. Exactly the same setup for each.
So, can I create a generic animation, that will simply go for the next sprite in the sheet, and re-use that for each “skin”?
Also, how do I set these sprites from script? I’ve tried various methods but I end up with a blank character, each time.
I’ve tried various combinations of the following code:
renderer = GetComponent<SpriteRenderer>();
var spriteName = PlayerPrefs.GetString("Sprite", "flaming");
var charSprite = Resources.Load("CharAssets/" + spriteName, typeof(Sprite)) as Sprite;
renderer.sprite = charSprite;
But as mentioned, not much luck. My sprites for the hero character, is in a folder called CharAssets, in the Assets folder.
First of all don’t be using Resources.Load and that kinda thing,
the solution is simple yet hard…
The thing for this is a AnimationControllerOverride,
- Create it in the same way as creating an Animator, you should see the option.
- Drag the Animator into the Override as the runtimeAnimatorController
- Create Default Animations (ie: IDLE, MOVE), they can just be empty animations
- Place these defaults into the Animator. (you should now see in the overrideController the names of the normal states.)
- Create a scriptableObject to store all of the different skins
script being able to switch skins:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
[CreateAssetMenu (menuName = "Skin", fileName = "New Skin")]
public class Skin : ScriptableObject
{
[SerializeField] AnimationClip idleAnimation = null;
[SerializeField] AnimationClip movingAnimation = null;
public AnimationClip GetIdleAnimation ()
{
return idleAnimation;
}
public AnimationClip GetMovingAnimation ()
{
return movingAnimation;
}
}
[CreateAssetMenu (menuName = "Skin Atlas", fileName = "New Skin Atlas")]
public class SkinsAtlas : ScriptableObject
{
[SerializeField] Skin defaultSkin = null;
[SerializeField] List<Skin> Skins = new List<Skin> ();
public Skin GetSkinAtIndex (int index)
{
if (index < Skins.Count)
{
return Skins[index];
}
else
{
Debug.LogWarning("index is not in range, add more skins or request a lower index");
return defaultSkin;
}
}
}
public class Player : MonoBehaviour
{
[SerializeField] SkinsAtlas skinAtlas = null;
Animator animator;
AnimatorOverrideController overrideController;
const string IDLE = "IDLE";
const string MOVING = "MOVING";
void SetSkinFromAtlas (int index)
{
var skin = skinAtlas.GetSkinAtIndex(index);
SetSkinAnimations(skin);
}
void SetSkinAnimations (Skin skin)
{
animator = overrideController;
overrideController.animationClips[IDLE] = skin.GetIdleAnimation();
overrideController.animationClips[MOVING] = skin.GetMovingAnimation();
}
}
This solution is too tedious and scales bad.
Nobody seem to found out how to change sprite on runtime but my massive 2D game guide:
See chapter 9.) How to swap sprites for an animated object in the Animator / Animator Controller / Animation Clip, including blend trees - ON RUNTIME ?
https://forum.unity.com/threads/sharing-means-caring-things-i-wish-i-knew-before-starting-with-tilemaps-2d-2-5d.771020/
The solution above is too tedious when one wants to scale through hundreds of skins and skin parts etc.
Nobody seem to found out how to change sprite on runtime but my massive 2D game guide:
See chapter 9.) How to swap sprites for an animated object in the Animator / Animator Controller / Animation Clip, including blend trees - ON RUNTIME ?
https://forum.unity.com/threads/sharing-means-caring-things-i-wish-i-knew-before-starting-with-tilemaps-2d-2-5d.771020/