Post by echo17 on Sept 18, 2018 20:13:45 GMT
Q: What is the best way to store my game objects?
I don't believe there is a best way, but I will share the way that I personally use.
Instead of trying to store each GameObject / ScriptableObject / etc. in its own data table, I serialize the entire object, or even the set of objects into a string. Then I can just store the string itself in a simple data table that consists of minimal fields. This is actually the method that Unity uses to stores its own internal state of the GameObjects / ScriptableObjects.
Serializing is trivial and can be done with a few lines of code:
You could then use this to store an object's data in your database like:
Some examples:
MyObjectType above could be anything from simple types like int, string, bool to more complex types like custom class, ScriptableObjects, GameObjects. It could even be an array, list, dictionary, etc. of any type. The serializer can handle just about anything.
Getting data back out of the database could be done like:
You can see that serializing your data is very powerful for a few reasons:
You will, however, need to be sure you are storing and retrieving the right structure of the object. If you change your object's structure, you will need to be sure you are deserializing back to the right structure. This could be handled with something like a version number:
You would then just need to select the correct object type to deserialize to based on the version number of the state.
You are not limited to byte serialization. There are a number of serializers out there, but one I would recommend is FullSerializer. It also happens to be free, so there is no risk in trying it. Json serialization is lighter than binary serialization, so it will use up less storage in your database. FullSerializer also has an option to byte serialize. Check out FullSerializer here:
github.com/jacobdufault/fullserializer
I don't believe there is a best way, but I will share the way that I personally use.
Instead of trying to store each GameObject / ScriptableObject / etc. in its own data table, I serialize the entire object, or even the set of objects into a string. Then I can just store the string itself in a simple data table that consists of minimal fields. This is actually the method that Unity uses to stores its own internal state of the GameObjects / ScriptableObjects.
public class SerializedState
{
public int UID { get; set; }
public string State { get; set; }
}
Serializing is trivial and can be done with a few lines of code:
public static string SerializeToString(object value)
{
if (value == null)
return null;
var binaryFormatter = new BinaryFormatter();
using (var ms = new MemoryStream())
{
binaryFormatter.Serialize(ms, value);
return Encoding.ASCII.GetString(ms.ToArray());
}
}
public static T DeserializeFromString<T>(string data)
{
var byteArray = Encoding.ASCII.GetBytes(data)
var binaryFormatter = new BinaryFormatter();
using (var ms = new MemoryStream())
{
ms.Write(byteArray, 0, byteArray.Length);
ms.Seek(0, SeekOrigin.Begin);
return (T)binaryFormatter.Deserialize(ms);
}
}
You could then use this to store an object's data in your database like:
MyObjectType myObject;
SerializedState state;
state.State = SerializeToString(myObject);
Some examples:
int myIntObject;
state.State = SerializeToString(myIntObject);
// Obviously this example is a bit silly, but it still shows that you can serialize anything.
MyCustomClass myCustomClass;
state.State = SerializeToString(myCustomClass);
List<GameObject> gameObjects;
state.State = SerializeToString(gameObjects);
MyObjectType above could be anything from simple types like int, string, bool to more complex types like custom class, ScriptableObjects, GameObjects. It could even be an array, list, dictionary, etc. of any type. The serializer can handle just about anything.
Getting data back out of the database could be done like:
MyObjectType myObject;
myObject = DeserializeFromString<MyObjectType>(state.State);
You can see that serializing your data is very powerful for a few reasons:
- You are not limited to the types available in the database. Everything is stored as a string on the database.
- You do not have to reflect the changes you make to your object in the database. You can add, remove, or completely change your objects and the database will always just store a string.
- You can store a single object, a collection of objects, or an entire game state all in a single record.
- Since everything is stored in a single record, you could easily keep track of multiple states in your game. This opens up possibilities for processes like Undo / Redo, rewinding to a previous game state, playing back an entire game based on the states. The possibilities are endless.
You will, however, need to be sure you are storing and retrieving the right structure of the object. If you change your object's structure, you will need to be sure you are deserializing back to the right structure. This could be handled with something like a version number:
public class SerializedState
{
public int UID { get; set; }
public int Version { get; set; }
public string State { get; set; }
}
You would then just need to select the correct object type to deserialize to based on the version number of the state.
You are not limited to byte serialization. There are a number of serializers out there, but one I would recommend is FullSerializer. It also happens to be free, so there is no risk in trying it. Json serialization is lighter than binary serialization, so it will use up less storage in your database. FullSerializer also has an option to byte serialize. Check out FullSerializer here:
github.com/jacobdufault/fullserializer