Hi all,
I was curious to know -- is it possible to do character customization in AC? I am hoping to allow players to choose certain accessories and hairstyles from a set, along with having a full hex color chooser / palette palette for skin tone and hair color.
Might this be possible to do in AC, and is it possible for these attributes to be saved in AC? I am having a single player, so no player switching will be involved.
Thanks!
It looks like you're new here. If you want to get involved, click one of these buttons!
Comments
There are a few general approaches, depending on how things should work.
If you have a fixed set of options, then one way is to enable Player-switching, create appearance as a separate Player prefab, assign them all in the Settings Manager, and then switch between them based on the Player's choice.
For a mix-and-match behaviour, where the different combinations would be too many to go with the above, you can either spawn in the accessories at runtime, and parent them to your character's skeleton, or use Animation sub-layers.
With animation, you can create e.g. a sub-layer named "Hat", which contains different animations that each cause a different "Hat" sprite to be shown in the character's hierarchy. That "Hat" SpriteRenderer object would be a part of the Player prefab, invisible by default, but then controlled through animation. An integer parameter in your Animator would then be used to control which animation is shown.
You could then link this parameter's value to e.g. a Global Integer variable by attaching the Link Variable To Animator component to the Animator. That way, you can control which hat is shown by using the Variable: Set Action - which will also allow such changes to be stored in save-game files.
For skin/hair tones, where the value can be anything, you'd need a custom script/asset that can update your character sprite's appearance through a special shader. This'll be handled outside of AC, but you can save the result with a custom Remember component.
I see, thank you so much -- this is really helpful!
@ChrisIceBox Is there a way to constantly update the value? So in-game, if I change the value for the variable that links to the hair sub-layer from 3 to 4, I want the new hair (style 4) to show up -- it looks like right now it does work when I change the global variable before I run the game, but when I change the global variable's value during the game, there is no update.
Actually nevermind -- I think it's only through the Variables tab in the AC game editor that it doesn't work. The Variable: Set seems to be ok as you mentioned above.
Is that intended behavior? Just wanted to cross-check!
I wouldn't say its intended exactly, but that is how it currently works.
Ah gotcha, thanks for the heads up!
When I change scenes, it looks like my character is reset to default (both color and animator)-- is there a way I can fix this?
This is my Remember Component for the Color:
using UnityEngine;
using System.Collections;
namespace AC
{
[RequireComponent(typeof(SpriteRenderer))]
public class RememberColor : Remember
{
// Save the SpriteRenderer's color data
public override string SaveData()
{
SpriteRendererData spriteRendererData = new SpriteRendererData();
spriteRendererData.color = new float[] {
GetComponent().color.r,
GetComponent().color.g,
GetComponent().color.b,
GetComponent().color.a
};
spriteRendererData.objectID = constantID;
}
** sorry I meant just the colors, not the animator -- the animator is ok.
The colors are resetting to the default white color for the player when I switch scenes.
`using UnityEngine;
using System.Collections;
namespace AC
{
[RequireComponent(typeof(SpriteRenderer))]
public class RememberColor : Remember
{
// Save the SpriteRenderer's color data
public override string SaveData()
{
SpriteRendererData spriteRendererData = new SpriteRendererData();
spriteRendererData.color = new float[] {
GetComponent().color.r,
GetComponent().color.g,
GetComponent().color.b,
GetComponent().color.a
};
spriteRendererData.objectID = constantID;
}
`
The Remember script's LoadData function won't be called as a result of a scene-switch if it's attached to a persistent Player. If it's becoming reset, it may be because of a separate script.
How/when are you altering the Player's color property in the first place? Is it possible that's causing the reset in a new scene?
This is the script I have going on for that --
In my scene, I have the player prefab, in which I assign values for the public spriterenderers.
Here's how a color swatch looks in the inspector: https://drive.google.com/file/d/1wmJuLn-Kj6VSTYmKgENu9ak-0Z2w5cMh/view?usp=sharing
Here's an example of how one of the sprite renderers in the character that is changing color looks in the inspector: https://drive.google.com/file/d/1L_EeetRNjBYexcbtT18E89Uq1F5Zd9zF/view?usp=drive_link
And this is the code for it:
`using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ChangeCharItemColor : MonoBehaviour
{
// Array sprite renderer list
public SpriteRenderer[] hairItems;
public SpriteRenderer[] shoeItems;
public SpriteRenderer[] sleeveItems;
public SpriteRenderer[] skinItems;
}
`
This issue would typically occur either if the Player is not persistent (so that the data is simply reset), or if the data is reset manually (i.e. through script).
Is any of that code run after the scene changes?
Is the Player object that you're applying these changes to persistent, i.e. carried over to the next scene, or is this a separate/local Player?
I see, thank you for the heads up!
No I'm not running any of the above code after the scene changes --
So I do have a player object in my "customization" scene, where I dragged the sprite renderers of the objects I want the color to change for into the script's inspector.
In the second scene, there is no player object in the scene. Rather, it is spawned!
In case it helps, here's a video!
https://drive.google.com/file/d/16i3TQxVmusoxZLqxZIT4GnzhZtCz5oa9/view?usp=drive_link
Looks good!
The issue, though, will be that the customised Player is local to the scene. It's a separate object to your spawned Player, so any changes made to one won't be automatically reflected in the other.
Best to use the spawned Player in both scenes. To have the UI reference their Sprite Renderers, you could attach a script to the Player that provides them, i.e.:
And then have your UI reference this script (using FindObjectOfType) instead of the renderers directly.
Thank you so much! This worked perfectly!