I’m creating an rpg where at the start of a new game the player creates a party of different character classes whose prefabs get stored in an array of Gameobjects, but since i’m using prefabs if they choose two of the same character class those two characters share the same properties.
I can’t use Instantiate because their data needs to persist between scenes and sessions. Is there to create copies of the prefabs and store them in an array?
public void SetCharacterType()
{
gameManager.characters[partyIndex] = gameManager.characterClasses[characterSpritesIndex];
}
If you want data to persist between sessions you can’t use prefabs or gameobjects nor scriptableobjects rather you need some kind of custom serialization.
In the other hand for data to persist between scenes you have couple options, as scriptableobjects, don’t destroy on load marked components and my favorite one additive scene loading where you create your persistant objects and then load/ unload other scenes. Custom serialization is an option too but I find it cumbersome and redundant in most senarios.
Don’t see any other option. Instantiate does create a deep* copy afterall.
As for prefabs you can’t really create them in runtime. The term prefab is a bit missleading as they are normal serialized GameObjects not bound to a scene, but for you to create one at runtime would require the use of Unity’s serializer something that is not possible. Keep in mind that a build’s files are immutable**.
*deep copy: partially true, it is more of mix between deep and shallow copy.
**immutable: kinda, afterall one could argue that asset bundles/ addressables break immutability.
Don’t use the binary formatter/serializer: it is insecure, it cannot be made secure, and it makes debugging very difficult, plus it actually will NOT prevent people from modifying your save data on their computers.
When loading, you can never re-create a MonoBehaviour or ScriptableObject instance directly from JSON. The reason is they are hybrid C# and native engine objects, and when the JSON package calls new to make one, it cannot make the native engine portion of the object.
Instead you must first create the MonoBehaviour using AddComponent() on a GameObject instance, or use ScriptableObject.CreateInstance() to make your SO, then use the appropriate JSON “populate object” call to fill in its public fields.