Save And Load Character Data
Key Problem
UploadUser Inshould Progressbe able to save the created character and load them later
Expected Behavior
User can save the created character data and load them later
Key Solution
Store the character data using JSON string format.
Proposed data structure
Character :
- gender : "male"/"female" (string)
- height : (float)
- skincolor : HTML Format Color HexCode" (string)
- items : [{"sku":(string), ["color":(string)]}]
- blendshape: [{"name":(string), "value":(float)}]
Since Unity’s integrated JSONUtility failed to serialize the proposed data structure into string, Lightweight MiniJSON is used instead.
Saving
Since every body parts and accessories have Item component, saving character data works by getting all active Item child components in active character. Then iterate through each Items to get their sku and color, then save them to the items list.
Item[] items = currentCharacter.GetComponentsInChildren<Item>();
JSONData character = new JSONData();
JSONList jsonList = new JSONList();
character.Add("gender", isMale ? "male" : "female");
character.Add("skincolor", ColorUtility.ToHtmlStringRGB(currentCharacter.GetSkinColor()));
for(int i = 0; i < items.Length; i++)
{
JSONData jsonData = new JSONData();
jsonData.Add("sku", items[i].GetSKU());
jsonData.Add("color", ColorUtility.ToHtmlStringRGB(items[i].GetColor(currentCharacter.GetClothColorName())));
jsonList.Add(jsonData);
}
The next to save is the blendshapes, the blendshapes is saved as a list of blendShapeName and Value pairs.
List<JSONData> blendShapes = new List<JSONData>();
foreach(BlendPair blendPair in blendPairs)
{
JSONData jSONData = new JSONData();
jSONData.Add("name", blendPair.name);
jSONData.Add("value", blendPair.value);
blendShapes.Add(jSONData);
}
Loading
Loading is the opposite of saving.
It start with activating or instantiating male or female character gameobject/prefab based on saved gender data, then setting his/her skincolor
Then iterate through the item in items list, getting body part or accessories with matching sku, and put them into the character, then set the item color. Note that the saved color string lack the prefix ‘#’, so it needs to be added manually for the TryParseHtmlString to work.
//iterate through all the saved item in the items list
//get item with matching sku and put it on character
//note that the stitcher can only stitch one item at one frame, thus the coroutine
JSONList items = charData.Field<JSONList>("items");
foreach(JSONData itemObject in items)
{
GameObject itemGameObject = CharacterLoader.instance.GetGameObject(isMale, itemObject.Field<string>("sku"));
Item item = PutItem(itemGameObject);
ColorUtility.TryParseHtmlString($"#{itemObject.Field<string>("color")}", out color);
item.SetColor(color, currentCharacter.GetClothColorName());
yield return null;
}
Then iterate through the blendshapes list and apply the blendshape to the character.
As for now, the data is saved to Player Preference, though since it’s formatted in plain text, it can be sent to remote server using API.