If you quickly want to add this feature to your game without having to watch the video, the pastebin is here: pastebin.com/u/GoldenEvolution/1/waWzHmvC Also if you are learning and do copy paste the scripts over, make sure you understand what is written in them. Next to that, the main CustomizableCharacter.cs script is slightly adjusted from the video to make it easier to add accessories with the other script in the pastebin called CustomizableAccessories.cs. The comments in both scripts respectively explain more.
Here is a very important bit of information that will make this click for anyone who doesn't get how this works. The animation frames in Unity overwrite the sprite in Sprite Renderer component (spriteRenderer.sprite) at runtime and they also change the name of it (spriteRenderer.sprite.name) with the name of the actual image used for the frame in the animation. If you put a Debug.Log on the Update function and put (spriteRenderer.sprite.name) inside the brackets you will see the name be updated in real time. This is why it's possible in LateUpdate to override whatever the animation has put inside by checking the number in the image that is being used in this frame and just exchange it for whatever new sprite with the same number you want to put in there. Thank you for this video, took really long to understand how to do this in a neat way, but I believe I have it figured out now!
How does this work in regards to if an Idle sprite switches to a Run sprite in the Animator? Right now it switches the Idle sprite, but it doesn't set the Run sprite to coincide with the skin change. The Idle/Run are both used on one player object. How would switch all relevant sprites (Run, Jump, Idle, etc) to the new versions at the same time?
Very cool tutorial - i have a question about the accessories : do you have a spritesheet for the accessoir which has the certain height so that it act as an overlay ? or do you have made idle animation for every accessoirs with the hamster ?
Can you add accessories on animated character for example rigged one? meaning When animation is being played characters components transform and rotation do not change, is it possible to take animation component's animated transform position and rotation and use that exact position to animate attachments overlay on a character's head such as glasses?
Very nice video Golden! Never knew I had to learn how to change skins for a character, but the hamsters convinced me! Came for the hamsters, stayed for the tutorial! :D
Thanks. This is the beginning of what i needed. I'd replace the string.Replace for a string.Split("_") to avoid hard coding when possible. It makes it easier to adapt for addition customization options like hair, clothing, etc.
Thank you for this tutorial! Though i am wondering how this will work with multiple animations? for example if i wanna change the skin color of the player, but there are multiple animations, and the sprites are named based off of the animations, e.g Skin 1_Walk_Up_0, Skin 1_Walk_Up_1, Skin 1_Walk_Up_2, Skin 1_Walk_Down_0, Skin 1_Walk_Down_1, etc. Thanks again!
Personally I had it set up with multiple animations as well in one singular spritesheet, but I kept the names all the way the same throughout every animation (which of course is not as clear and easily readable as you mentioned). The only problem with your approach is that you're probably gonna end up with a bit more of a messy code. You're most likely going to need to adjust the struct a little where each animation gets its own array 'sprites'. Afterwards you're gonna have to check which animation is actually running and once again strip away the text here so you get the number at the end and replace the sprite accordingly.
Very Late reply, but you can rename the original animations in a consecutive order (e.g. CharacterMain_0, CharacterMain_1, et cetera), and then import the corresponding alternate animations into the array in that order.
do we have to add an example of blue, green ? or if you have finished coding, the color will automatically change? hehe such as adding a green character sprite or something else?
Is it only me that sprite not changed during animation? If I set animator active false, then I can change the sprite in the code, but when animator is active, sprite is not changed by code.
You could either use Playerprefs in Unity or save it in a JSON file. I think there's plenty information available online on those topics 😁. Playerprefs is super easy to set up!
Great Tutorial!😁 How do you handle the Sprite Order? If they have different "Order in Layer" in the Sprite Renderer, Others gameobject Like structures will be affected.
Thanks!! That totally depends on what type of game you're making. Right here for this tutorial I am simply offsetting the accessories on the z-axis by a very tiny amount of like 0.001. For platformers for example it's good to have different Sorting Layers, like a foreground, middleground, background, player layer and so on. And then next to that you can sort those by the Order in Layer. Next to that you can also play around a bit with the values on the Z-axis if needed. For a top-down game I usually set the pivot points of my sprites at the bottom center and then sort my sprites by whatever value they have on the Y-axis. That means if a sprite has a higher Y-value, it should appear behind a sprite that has a lower Y-value.
@@GoldenEvolution Thanks for the answer, if I only use the y axis in a top down game, it won't work with accessories because they are usually a child with the coordinates x = 0 y = 0 (they have the same pivot) and when i change the Order in Layer it will affect the others gameobject. I still not sure how i can do this 😕
@@lumer7430 That's indeed a tough one. Not fully sure how to solve that either. Have you tried asking around in gamedev discords? They might know an answer 😅
Hello! This is the tutorial that Ive been lookin for! Thank you for making this! Just one question: If I have hundreds of different skins, do I have to attach all of them into my game object? Or is there a more efficient method? Thank you (:
Hahahaha I found the solution awhile back! Its called Sprite Library Assets! Allows you to only attach a single sprite object to the player object and you can swap between whatever sprites you want (:
Your tutorial was Awesome 👌! But i have an error. "Index was outside the bounds of the array" at line 46 and line 46 is : spriteRenderer.sprite = skins[skinNr].sprites[spriteNr]; When i paused game and saw at in the inspector the value of spriteNr goes between 20 to 27 . Means it not remove 1, 2, 3 from 1HamsterMain, 2HamsterMain, 3HamsterMain. Please suggest what should i need to change in my script. 🙏
Why the hole time your script is called customizable character, but at the end on the button is called hamster customizable, im trying to set my buttons but it appers no function and thats all
It's still called CustomizableCharacter. When you want to add an onClick function to a button, you have to drag the GameObject the script is attached to into the box. In this case it's attached to the GameObject 'Hamster', that's why it says Hamster right there. From that point on you can select the public functions from your script
@@GoldenEvolution Done thanks, but still have an error every time i click the button it says something like “SkinRenderer not found” but i have the exact same words than you in my script
Hey o/ Thanks a lot, this looks like what I've been struggling to find for my pixel art character customization. Will take some time later to watch it in depth, but in the mean time maybe I can ask this So using your method in my head would be something like: -having my main character+animations as a paper doll, -draw my clothing+animtions over it but export them separately (without the character on the atlas), -then in unity having clothes as child gameobjects of my main character to make them overlay, is that correct ? Thanks again :]
Hey I have several Problems. First amazing tutorial the skins worked for me but the hair wont change I made it exactly like the skin. The hair is a child component of the skin, do I have to give it the script too or what am I doing wrong?
I assume the hair serves the same purpose as the accessories in the tutorial. The hair does indeed also need the same script with the same functions. Also make sure the hair is in front of the character (layermask, layer order, Z-axis).
@@GoldenEvolution wow thank you so so much for the fast reply!! So everything I add gets the same script or a modified version because the get component for the sprite renderer has a different name for each thing like hair, clothes, etc.?
@@Wonderchocolate Yes it does get a slight modified version with indeed the different spriterenderer and the different name for the sprites. Next to that you could check the number of the parent spriterenderer component and make sure the accessory copies that number over. Either that or you remake the whole animation state for the animations as well, but that sounds like too much work too me haha. I could try to make a quick script that you could easily add and fill in to your child components
@@GoldenEvolution that would be perfect I am quite new to Unity and struggle with making scripts up myself but I think I unterstand how it works thank you so much again for your help!!
@@Wonderchocolate It's always good to try to make it work yourself first, since that's the best way to make the information stick in your head. If you end up not figuring out how to make it work though, I have updated the 'pastebin' in the description with an extra script. I've also adjusted the main script slightly to make this accessory script work.
Hey dude, anytime I try to swap I get a 'FormatException: Input string was not in a correct format.' error message in Unity. Would you know the reason I'd be getting this? Cheers
My guess is that the string that you're trying to parse in the Int.Parse method is not just a number, but still contains letters. Make sure the string "spriteName" only contains numbers
@@GoldenEvolution I've attached an image and a paste of the code but I think you tube keeps removing it? Or it's ended up in your spam probably. I've tried different naming conventions but still not sure, when trying to switch via the inspector is when the message gets thrown out. 'FormatException: Input string was not in a correct format. System.Number.StringToNumber (System.String str, System.Globalization.NumberStyles options, System.Number+NumberBuffer& number, System.Globalization.NumberFormatInfo info, System.Boolean parseDecimal) (at :0) System.Number.ParseInt32 (System.String s, System.Globalization.NumberStyles style, System.Globalization.NumberFormatInfo info) (at :0) System.Int32.Parse (System.String s) (at :0) CustomizableCharacter.SkinChoice () (at Assets/Scripts/CustomizableCharacter.cs:40) CustomizableCharacter.LateUpdate () (at Assets/Scripts/CustomizableCharacter.cs:31)'
@@TheEqualityComedy Like I said before, I think the problem is that you're trying to parse a string into a number, but this string still contains characters that aren't numbers. Make sure that in this line (line 37 in the pastebin): int spriteNr = int.Parse(spriteName); the spriteName that you're trying to parse only contains numbers. It shouldn't contain any characters like underscores or commas or anything either. Make sure you are replacing all the characters that aren't numbers with an empty string, as done in line 36 according to the pastebin.
@@GoldenEvolution Hey you legend, the problem I had was definitely to do with the naming convention! Instead of an underscore "_" I needed a space, and it's all gravy now! Cheers again mate keep up the good work
Right now the way it is set up it would work with multiple animations too, except the naming of the sprites wouldn't be as clear as you maybe would like it to be. With this you would have a giant spritesheet of all animations with sprite_1 to sprite_50 (however many sprites you have in total). Otherwise you would most likely need to make a new struct with specific animation states and their respective name. You would need to strip out the name of the animation state from the main animation, and loop through these for the specific skin in order to find the right ones. It's definitely a bit more complex, but would make your project files a lot more clear.
@@GoldenEvolution Thank you for your replying. it seems you provided 2 methods. I wish I can understand your first method so I don't have to do more coding, but for your second one, do you mean to create another SkinChoice() and struct Skins for another animation and name the sprite file in different way? Hopefully, you will have time to make another tutorial for multiple animations for both methods, before that I will do my best to achieve it.
@@GoldenEvolution save the skin setting, once you changed the skin and continue with the game the skin should have the changed skin not the previous or default one.
I still don't fully understand what you mean. If you change the skin number, then your character should change into that skin. Do you mean the skin number doesn't save after closing the game and reopening?
If you quickly want to add this feature to your game without having to watch the video, the pastebin is here: pastebin.com/u/GoldenEvolution/1/waWzHmvC
Also if you are learning and do copy paste the scripts over, make sure you understand what is written in them. Next to that, the main CustomizableCharacter.cs script is slightly adjusted from the video to make it easier to add accessories with the other script in the pastebin called CustomizableAccessories.cs. The comments in both scripts respectively explain more.
please give the spritesheet
Here is a very important bit of information that will make this click for anyone who doesn't get how this works.
The animation frames in Unity overwrite the sprite in Sprite Renderer component (spriteRenderer.sprite) at runtime and they also change the name of it (spriteRenderer.sprite.name) with the name of the actual image used for the frame in the animation.
If you put a Debug.Log on the Update function and put (spriteRenderer.sprite.name) inside the brackets you will see the name be updated in real time.
This is why it's possible in LateUpdate to override whatever the animation has put inside by checking the number in the image that is being used in this frame and just exchange it for whatever new sprite with the same number you want to put in there.
Thank you for this video, took really long to understand how to do this in a neat way, but I believe I have it figured out now!
Besides the system relying on naming convention and parsing, I think this is absolutely genius.
How does this work in regards to if an Idle sprite switches to a Run sprite in the Animator? Right now it switches the Idle sprite, but it doesn't set the Run sprite to coincide with the skin change. The Idle/Run are both used on one player object. How would switch all relevant sprites (Run, Jump, Idle, etc) to the new versions at the same time?
This video saved my ass, I couldn't find any good tutorials on this anywhere, thanks!!!
Glad it helped! When I had to solve this problem I couldn't find any good tutorials on it either, so once I solved it, I just had to make this video 😄
@@GoldenEvolution youll get a slow trickle of people coming in with the problem 😂 easy views
How could i make this work for more than just the idle animation?
Very cool tutorial - i have a question about the accessories : do you have a spritesheet for the accessoir which has the certain height so that it act as an overlay ? or do you have made idle animation for every accessoirs with the hamster ?
Yes this is what I want to know as well. It is not clear from this video. I fear they did the latter, which does not seem very scalable to me.
I am 99.9% sure, that he just made spritesheets of levitating accessories and applying them as an overlay
I want to do this but without the animation frames, just one. Can you help me please?
Will the skins stay even if I switch scenes?
Static variables carry over to other scenes, so simply change the skinNr to a public static int
Can you add accessories on animated character for example rigged one? meaning When animation is being played characters components transform and rotation do not change, is it possible to take animation component's animated transform position and rotation and use that exact position to animate attachments overlay on a character's head such as glasses?
Very nice video Golden! Never knew I had to learn how to change skins for a character, but the hamsters convinced me! Came for the hamsters, stayed for the tutorial! :D
Thanks! Happy to hear that :D
Did you do all the frame by frame animations in the character?
I don't fully know what you mean but I did draw out all the character animations frame by frame if that's what you mean.
Thanks. This is the beginning of what i needed. I'd replace the string.Replace for a string.Split("_") to avoid hard coding when possible. It makes it easier to adapt for addition customization options like hair, clothing, etc.
Thank you for this tutorial! Though i am wondering how this will work with multiple animations? for example if i wanna change the skin color of the player, but there are multiple animations, and the sprites are named based off of the animations, e.g Skin 1_Walk_Up_0, Skin 1_Walk_Up_1, Skin 1_Walk_Up_2, Skin 1_Walk_Down_0, Skin 1_Walk_Down_1, etc.
Thanks again!
Personally I had it set up with multiple animations as well in one singular spritesheet, but I kept the names all the way the same throughout every animation (which of course is not as clear and easily readable as you mentioned). The only problem with your approach is that you're probably gonna end up with a bit more of a messy code. You're most likely going to need to adjust the struct a little where each animation gets its own array 'sprites'. Afterwards you're gonna have to check which animation is actually running and once again strip away the text here so you get the number at the end and replace the sprite accordingly.
Very Late reply, but you can rename the original animations in a consecutive order (e.g. CharacterMain_0, CharacterMain_1, et cetera), and then import the corresponding alternate animations into the array in that order.
dude you save my life in 5 minutes acct 3 min i was already saved
Glad I could save your life haha
do we have to add an example of blue, green ? or if you have finished coding, the color will automatically change? hehe such as adding a green character sprite or something else?
Can you do it but when the player does an action?
Can someone confirm or deny, you have to manually remake every piece of animation for this, right?
not for the accessory but if you have different character sprites then yeah
Is it only me that sprite not changed during animation? If I set animator active false, then I can change the sprite in the code, but when animator is active, sprite is not changed by code.
Maybe my animation is keyframe recording style animation.
Awesome stuff! Definitely will be doing some character customization eventually. Thanks for sharing!!
Glad you liked it 😄
Amazing tutorial! Would love to know how to save the current skinNumber on a savefile aswell :)
You could either use Playerprefs in Unity or save it in a JSON file. I think there's plenty information available online on those topics 😁. Playerprefs is super easy to set up!
@@GoldenEvolution Thanks! Will look into it!
Great Tutorial!😁 How do you handle the Sprite Order? If they have different "Order in Layer" in the Sprite Renderer, Others gameobject Like structures will be affected.
Thanks!!
That totally depends on what type of game you're making. Right here for this tutorial I am simply offsetting the accessories on the z-axis by a very tiny amount of like 0.001.
For platformers for example it's good to have different Sorting Layers, like a foreground, middleground, background, player layer and so on. And then next to that you can sort those by the Order in Layer. Next to that you can also play around a bit with the values on the Z-axis if needed.
For a top-down game I usually set the pivot points of my sprites at the bottom center and then sort my sprites by whatever value they have on the Y-axis. That means if a sprite has a higher Y-value, it should appear behind a sprite that has a lower Y-value.
@@GoldenEvolution Thanks for the answer, if I only use the y axis in a top down game, it won't work with accessories because they are usually a child with the coordinates x = 0 y = 0 (they have the same pivot) and when i change the Order in Layer it will affect the others gameobject.
I still not sure how i can do this 😕
@@lumer7430 That's indeed a tough one. Not fully sure how to solve that either. Have you tried asking around in gamedev discords? They might know an answer 😅
Hello! This is the tutorial that Ive been lookin for! Thank you for making this! Just one question: If I have hundreds of different skins, do I have to attach all of them into my game object? Or is there a more efficient method?
Thank you (:
I feel there should be a more savvy way to go about this.
Hahahaha
I found the solution awhile back!
Its called Sprite Library Assets!
Allows you to only attach a single sprite object to the player object and you can swap between whatever sprites you want (:
You're a legend! Was looking everywhere for something like this, thanks for sharing
Your tutorial was Awesome 👌!
But i have an error.
"Index was outside the bounds of the array" at line 46 and line 46 is :
spriteRenderer.sprite = skins[skinNr].sprites[spriteNr];
When i paused game and saw at in the inspector the value of spriteNr goes between 20 to 27 . Means it not remove 1, 2, 3 from 1HamsterMain, 2HamsterMain, 3HamsterMain.
Please suggest what should i need to change in my script. 🙏
In this case it should remove the "HamsterMain" from these where only the 1, 2, 3, etc. is left over.
@@GoldenEvolution okay, i will try something else..
@@bherulalsahu9531 bro ek spritesheet de do aisa hamster jaisa
Awesome tutorial! Exactly what I was looking for and so simple and easy to maintain! Thanks a lot!
Why the hole time your script is called customizable character, but at the end on the button is called hamster customizable, im trying to set my buttons but it appers no function and thats all
It's still called CustomizableCharacter. When you want to add an onClick function to a button, you have to drag the GameObject the script is attached to into the box. In this case it's attached to the GameObject 'Hamster', that's why it says Hamster right there. From that point on you can select the public functions from your script
@@GoldenEvolution Done thanks, but still have an error every time i click the button it says something like “SkinRenderer not found” but i have the exact same words than you in my script
Do you mean the SpriteRenderer? Make sure that your GameObject with the script has a SpriteRenderer component attached to it
@@GoldenEvolution yes the Sprite renderer
@@GoldenEvolution your game object is the hamster? Or the empty object where you put the script for the button?
Hey o/
Thanks a lot, this looks like what I've been struggling to find for my pixel art character customization. Will take some time later to watch it in depth, but in the mean time maybe I can ask this
So using your method in my head would be something like:
-having my main character+animations as a paper doll,
-draw my clothing+animtions over it but export them separately (without the character on the atlas),
-then in unity having clothes as child gameobjects of my main character to make them overlay, is that correct ?
Thanks again :]
Yep that is correct!
@@GoldenEvolution Thank you so much ! Glad I've found your video :]
Harder than it sounds to find actual good pixel art related tutorials on youtube
Hey I have several Problems. First amazing tutorial the skins worked for me but the hair wont change I made it exactly like the skin. The hair is a child component of the skin, do I have to give it the script too or what am I doing wrong?
I assume the hair serves the same purpose as the accessories in the tutorial. The hair does indeed also need the same script with the same functions. Also make sure the hair is in front of the character (layermask, layer order, Z-axis).
@@GoldenEvolution wow thank you so so much for the fast reply!! So everything I add gets the same script or a modified version because the get component for the sprite renderer has a different name for each thing like hair, clothes, etc.?
@@Wonderchocolate Yes it does get a slight modified version with indeed the different spriterenderer and the different name for the sprites. Next to that you could check the number of the parent spriterenderer component and make sure the accessory copies that number over. Either that or you remake the whole animation state for the animations as well, but that sounds like too much work too me haha. I could try to make a quick script that you could easily add and fill in to your child components
@@GoldenEvolution that would be perfect I am quite new to Unity and struggle with making scripts up myself but I think I unterstand how it works thank you so much again for your help!!
@@Wonderchocolate It's always good to try to make it work yourself first, since that's the best way to make the information stick in your head.
If you end up not figuring out how to make it work though, I have updated the 'pastebin' in the description with an extra script. I've also adjusted the main script slightly to make this accessory script work.
Thanks! I really needed something like this
Hey dude, anytime I try to swap I get a 'FormatException: Input string was not in a correct format.' error message in Unity. Would you know the reason I'd be getting this? Cheers
Could you copy paste the code and the line in which the error occurs?
My guess is that the string that you're trying to parse in the Int.Parse method is not just a number, but still contains letters. Make sure the string "spriteName" only contains numbers
@@GoldenEvolution I've attached an image and a paste of the code but I think you tube keeps removing it? Or it's ended up in your spam probably. I've tried different naming conventions but still not sure, when trying to switch via the inspector is when the message gets thrown out.
'FormatException: Input string was not in a correct format.
System.Number.StringToNumber (System.String str, System.Globalization.NumberStyles options, System.Number+NumberBuffer& number, System.Globalization.NumberFormatInfo info, System.Boolean parseDecimal) (at :0)
System.Number.ParseInt32 (System.String s, System.Globalization.NumberStyles style, System.Globalization.NumberFormatInfo info) (at :0)
System.Int32.Parse (System.String s) (at :0)
CustomizableCharacter.SkinChoice () (at Assets/Scripts/CustomizableCharacter.cs:40)
CustomizableCharacter.LateUpdate () (at Assets/Scripts/CustomizableCharacter.cs:31)'
@@TheEqualityComedy Like I said before, I think the problem is that you're trying to parse a string into a number, but this string still contains characters that aren't numbers. Make sure that in this line (line 37 in the pastebin):
int spriteNr = int.Parse(spriteName);
the spriteName that you're trying to parse only contains numbers. It shouldn't contain any characters like underscores or commas or anything either. Make sure you are replacing all the characters that aren't numbers with an empty string, as done in line 36 according to the pastebin.
@@GoldenEvolution Hey you legend, the problem I had was definitely to do with the naming convention! Instead of an underscore "_" I needed a space, and it's all gravy now! Cheers again mate keep up the good work
Awesome tutorial. What should I do if I have multiple animations?
Right now the way it is set up it would work with multiple animations too, except the naming of the sprites wouldn't be as clear as you maybe would like it to be. With this you would have a giant spritesheet of all animations with sprite_1 to sprite_50 (however many sprites you have in total).
Otherwise you would most likely need to make a new struct with specific animation states and their respective name. You would need to strip out the name of the animation state from the main animation, and loop through these for the specific skin in order to find the right ones. It's definitely a bit more complex, but would make your project files a lot more clear.
@@GoldenEvolution Thank you for your replying. it seems you provided 2 methods. I wish I can understand your first method so I don't have to do more coding, but for your second one, do you mean to create another SkinChoice() and struct Skins for another animation and name the sprite file in different way? Hopefully, you will have time to make another tutorial for multiple animations for both methods, before that I will do my best to achieve it.
@@GoldenEvolution Actually., I created 2 different skin functions and 2 data structs, and problem solved. Thank you so much!
@@linsfunbox4052 Great to hear, nice job!!
How to save??
What do you need to save?
@@GoldenEvolution save the skin setting, once you changed the skin and continue with the game the skin should have the changed skin not the previous or default one.
I still don't fully understand what you mean. If you change the skin number, then your character should change into that skin. Do you mean the skin number doesn't save after closing the game and reopening?
Thank you so much for this
Is this working on the unreal engine ?
Nope
@@GoldenEvolution ok thx
Damn they squichy :3
Many thanks for making this video. Really helpful for me
Thanks will use :D
SpriteLibrary and SpriteResolver might make for an easier solution to this problem
I had no clue these existed, thanks for mentioning it!
SUPER LIKE TO THIS VIDEO
YES
Cool :D
♥
I love you
First
third