Home > Net >  What is the best way to create/save level data during runtime in Unity?
What is the best way to create/save level data during runtime in Unity?

Time:12-09

I am trying to make a mobile game where the player is allowed to create their own levels. At the moment the only data I am aiming to save for each level instance is the level name and author name.

I tried to get my head around scriptable objects as these instances of level data will not need to be attached to a gameobject/don't need to be a monobehaviour. But I am now extremely confused as to how one would persist these once they are created at runtime. There's not a lot of info out there about that and I see that serializing lists of scriptable objects using JsonUtility is barely talked about (so probably not something people do) and I have had trouble achieving successful serialization in this way.

In theory I could create a list of prefabs with monobehaviour scripts containing the data for each level and JSON serialize that, but that seems not very elegant and wasteful since I won't be instantiating these prefabs or monobehaviour scripts.

Would it be recommended that I don't use scriptable objects in this way for data persistence? What would be a better way to achieve this kind of save system?

CodePudding user response:

"Best" will be subjective, but we can look at ScriptableObjects .. and then discard them for your purpose.

SO's have no inherit runtime serialisation mechanisms. For that reason, they'll be a burden to wrangle them to save player data. Not impossible, just cumbersome.

Your best bet is to do the serialisation yourself. Let's consider what a player might create a level with (as you didn't supply any of that info). We can assume prop type, a position, a rotation and a colour? That being the case, we could simply build out a little class (some like to call them POCOs for Plain Old Class Object).

public class Item
{
    public string objectId {get;set;}
    public Vector3 position {get;set;}
    public Vector3 rotation {get;set;} // as a Euler rotation
    public Color colour {get;set;}
}

Then to tie these together, you'd have a level container:

public class Level
{
    public int levelNumber {get;set;}
    public List<Item> items {get;set;}
}

Now, you might be saying "hold up, Unity won't serialise properties", and you'd be right. But here comes my suggest, use a different JSON serialiser. The JsonUtility JSON serialiser that Unity uses as pretty limited. For that reason, I'd use either Newtonsoft.Json or System.Text.Json (my preference). Both of those will be able to serialise properties. A benefit of System.Text.Json is that it's the one I use with Azure, so my classes and code don't need to be changed for the two environments, but that's just a benefit in that particular situation.

Now you've got your data structures. But you'd still need to decide what persistence mechanism you want to use. Save to local storage? To a web service and/or database? PlayerPrefs if you're using WebGL? Desktop is different to mobiles, WebGL can't store locally other than to "player prefs" which is implemented in the local datastore, and then there's pushing it to a remote server. So you'd need to then work out where you're going to save that data. The outdated option was to use binary serialisation. Security issues pushed that into the unsavory basket. JSON is plain text though, so needs to be run through an encryption service to make it secure if there's a chance the user could see and modify it.

We're now starting to get into a very broad area here. Because you might want to persist your data in one of a very many places, you'd have to be a bit more specific about where you'd like that to be.

  • Related