I am faced with a major design decision for my game, where I need to “shapeshift” or just change between certain characters. One of the main problems that I have is that for some characters, I would like to keep certain things “shared” such as stats, inventory, equipment, etc.
Due to how my character controller works, and how things are being setup, i can’t just swap out meshes or simply swap the prefabs and call it a day.
I then remembered that most things that I want to “share” are things that are being saved with the JsonSavingSystem, so I thought why not leverage this and somehow save the state of the character i switching from to the new character.
But this would require some changes, because I might only want to do this for certain “forms”.
Here is an example of how my TransformableCharacter class looks like:
[Serializable]
public class TransformableCharacter
{
public CharacterType characterForm;
public CharController charInstance;
public bool isActive;
public bool shouldShareState;
public string sharedStateID;
public TransformableCharacter(CharController char, CharacterType form, bool shareState, string stateID)
{
characterForm = form;
charInstance = char;
isActive = false;
shouldShareState = shareState;
sharedStateID = stateID;
}
}
I added the shouldShareState bool and the sharedStateID to show what i meant by “only certain forms” should share a state.
So, in the Swap method, I would do a check on the character to see if it should share state, and if it does then i would capture that forms state, as you would when you save the game. The tricky part is that, the save system takes in a UUID, that sits on that JsonSaveableEntity. What I need the new extension to do is to somehow have a different method that will capture the state but i would like it to use the sharedStateID to do that. Because I can’t have multiple prefabs in the scene that share the same uniqueIdentifier, like Player for example. IT would have been easier if it could.
But the idea would be to check if the form should share the state, if ti does, the save it, ideally i would like to save this as a cache, and not on file, for example do not write these values to file like the save system normally does, but to have a local cache:
private Dictionary<string, JToken> characterStateCache = new Dictionary<string, JToken>();
and just save those states there, because the idea would be that when i call the Swap method, it will do the check to see if the oldcharacter shouldShareState, if true, then CaptureState, and when i transform to the newCharacter, then i also check if it shouldShareState, and if it does, then i would do a RestoreState, from the local cache.
I think here is where i would use the sharedStateID field, where it shouldn’t necessarily be unique, because if let’s say i want to save the state between 2 humanoid forms that would share the inventory and equipment and stats, then i would use the same sharedStateID for those forms. I guess an extra check could be made to see if the newcharacter.sharedStateID is the same as the oldcharacter.sharedStateId, then I know that i can do a restoreState on the newCharacter using the sharedStateID to grab the state from the cache.
This should cover the issue i have with saving and loading the states at runtime between 2 characters, but then I would have an issue when I will actually Save the game, because while the local cache would keep the current state of the characters i am swapping from, where basically the 1st time i shape shift, it will carry over the 1st characters stats, then when i swap back to it, it will carry over the new state, meaning if when i swapped over the 1st char, i had lvl 10 and 1 item in the inventory, this would transfer over to the 2nd character, i would then proceed to level to 20 and have 3 items in the inventory and 1 in the equipment slot, and when i would switch back over to the 1st character, all these new change would basically be copied to it, so it would also be lvl 20 with 3 items in inv and 1 equipped.
Now the main concern i have is when i will save the game, if the 1st character will level to lvl 30 now, and i never to a swap back to the 2nd char so it would also have a copy of the new state, when i save, the prefab for the 2nd character will save with lvl 20, 3 items, 1 equipped, etc. When i will load the game, i would basically load in with the 1st character loaded, so if i swap to the 2nd char, then it would have the new state, but the issue would be, if i continue to play with the 2nd character, get to lvl 40 (1st char is lvl 30), then i save the game on the 2nd char and quit, when i load in i will basically be on the 1st character loaded, and it would have the old lvl 30 state, etc, so you can see where my issue is.
I remember that Brian also helped out with a nice addition to the JsonSavingSystem where you can set a character to be isManaged bool, and put that character in a managed characters list on the main prefab, so that even if a character prefab is disabled when you perform a save, it will still save its state, so that it can be loaded as well.
I was wondering if that could also be used with this new extension?
But the main concern is still that scenario where you play on the second character and save and exit and when you load back, you are on the 1st character and if you ever switch to the 2dn character you would basically loose the “shared” progress you did on it.
I am still trying to figure out a way on how to make this work, when playing multiple character, because of how the dialogue system would work, the shop system and the predicate system works.
Thanks!