Changing sprite and animation, through script
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.
Answer by kalen_08 · Jul 19, 2018 at 03:05 PM
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();
}
}
Does this mean I would have to hook up each skin, with a Skin class, inside the editor? I kind of want to avoid having to do this manual work when I add new skins, and have a somewhat generic way of doing it. $$anonymous$$aybe just load up all the skins through code.
Yes but this is the easiest way. Copy the three scripts in and create up a few Skin assets and a single SkinAtlas. Add the code from my player script to yours and then drag the Atlas to your player object. This is the most flexible way because you can create as many skins as you want. $$anonymous$$anually loading them will probably take time and also adding in all the different code will be a lot more work and WAY more messy way to do it. This is exactly how I do my weapons and there attacks.
The skin and skin atlas are scriptable objects with [CreateAsset$$anonymous$$enu] so if you right click in the project window at the top should be options to create the two objects. :) Generally the logic is this: If something is a behaviour then you I herit from amonovegacuour If it is data (which this is) then you inherit from ScriptableObject And if its logic or calculations you inherit from nothing.
Your answer
Follow this Question
Related Questions
Sprite sheet and animation slice doubt 0 Answers
Multiple Sprite Pivot Points 0 Answers
Same animation from multiple spritesheets 1 Answer
Should weapons be different sprites? 1 Answer
Sprite Animation via script C# 1 Answer