Savegame Pro | Unity3D package
Version 1.0, 2019/10/17 support@peterverstappen.com
User documentation for the Unity3D Savegame Pro package by Peter Verstappen.
Table of Contents
Summary
Savegame Pro is an extensible Unity3D package that allows you to quickly implement saving and loading to and from files into your game. Out-of-the-box support for GameObjects, Components, primitive types and many UnityEngine types and structs is provided. Savegame Pro can be extended easily, either with custom surrogates classes or by simply defining the type you need to save with the provided default surrogate.
The Savegame Pro workflow provides easy saving and loading to one or more files.
Files are kept small and duplicate data is avoided by not saving recursively.
This keeps you in full control on what is saved for an object.
Writing to disk happens only when you call the function for it.
Reading from disk occurs only when creating the Savegame
object or
when you call the function.
Code
This section provides code samples for the basic functionalities of the package.
Creating a savegame
Import the package with using SavegamePro
.
//Import the package
using SavegamePro;
Savegame
needs a SavegameSettings
object that contains at least the filename.
//Creating a standard savegame
public void ExampleSavegame() {
SavegameSettings settings = new SavegameSettings("my-save-game-filename");
Savegame savegame = new Savegame(settings);
}
SavegameSettings
can be set with additional parameters to customize where the file
is saved and with what extension.
//Customizing savegame settings
public void ExampleSavegameSettings() {
//Saved in the persistent data directory with filename "my-save-game.sav"
SavegameSettings settings = new SavegameSettings("my-save-game");
//Saved in the given directory relative to executable, with filename "my-save-game.sav"
SavegameSettings settings = new SavegameSettings("my-save-game", "my-directory");
//Saved in the given directory, with filename "my-save-game.sav"
SavegameSettings settings = new SavegameSettings("my-save-game",
"C:\\my-directory\\sub-directory\\save-directory");
//Saved in the executable directory, with filename "my-save-game.custom"
SavegameSettings settings = new SavegameSettings("my-save-game", "", "custom");
}
Saving
All objects are saved with the public void Save(string key, object value)
method.
The full list of tested saveable types can be found here.
Theoretically, all types are supported.
//Saving an object
public void ExampleSave() {
//Create the savegame
SavegameSettings settings = new SavegameSettings("my-save-game");
Savegame savegame = new Savegame(settings);
//Saving a simple string
savegame.Save("my-string-key", "My Hero Name");
//Saving a Vector3
savegame.Save("my-vector3-key", new Vector3(1, 2, 3));
//Saving a GameObject
GameObject go = GameObject.Find("Cube");
savegame.Save("my-gameobject-key", go);
//Saving a Component
Transform transform = go.GetComponent<Transform>();
savegame.Save("my-transform-key", transform);
}
Loading
There are two load methods. public T Load<T>(string key)
is used for loading
types that are serializable or have a surrogate defined in the UnitySurrogateSelector
class.
You can load any primitive type, enum or serializable struct with this method. Also all structs defined here.
//Loading objects without a reference
public void ExampleLoadingWithoutReference() {
//Create the savegame
SavegameSettings settings = new SavegameSettings("my-save-game");
Savegame savegame = new Savegame(settings);
//Loading a string
String myString = savegame.Load<String>("my-string-key");
//Loading a Vector3
Vector3 myVector3 = savegame.Load<Vector3>("my-vector3-key");
}
The public void Load<T>(string key, ref T obj)
method is used to load objects with a reference.
GameObjects
, Components
and complex UnityEngine
types and structs can only
be loaded with this method because it does not create new instances,
rather uses the given reference to load values into it.
//Loading objects with a reference
public void ExampleLoadingWithReference() {
//Create the savegame
SavegameSettings settings = new SavegameSettings("my-save-game");
Savegame savegame = new Savegame(settings);
//Loading a GameObject
GameObject go = GameObject.Find("Cube");
savegame.Load("my-gameobject-key", ref go);
//Loading a Transform (or any Component)
Transform transform = GameObject.GetComponent<Transform>();
savegame.Load("my-transform-key", ref transform);
}
Persisting to disk
The Savegame
is only written to disk when you call the WriteToDisk()
function.
//Persisting the savegame to disk
public void ExamplePersistance() {
//Create the savegame
SavegameSettings settings = new SavegameSettings("my-save-game");
Savegame savegame = new Savegame(settings);
//Saving a simple string
savegame.Save("my-string-key", "My Hero Name");
//Write to disk
savegame.WriteToDisk();
}
Deleting from disk
Deleting the Savegame
will remove the file from disk and clear all keys.
//Deleting a savegame
public void ExampleDelete() {
//Create the savegame
SavegameSettings settings = new SavegameSettings("my-save-game");
Savegame savegame = new Savegame(settings);
//Delete from disk and clear savegame
savegame.DeleteFromDisk();
}
Logging
Savegame is able to provide detailed debug logs by adjusting the Savegame.Logging
property. The default value is LogLevel.ReadingWriting
and shows when I/O file interactions are happening.
//Loglevels
Savegame.Logging = LogLevel.None;
Savegame.Logging = LogLevel.ReadingWriting;
Savegame.Logging = LogLevel.Keys;
Savegame.Logging = LogLevel.Serialization;
Savegame.Logging = LogLevel.Full;
//Mixing and mashing
Savegame.Logging = LogLevel.ReadingWriting | LogLevel.Serialization;
Additional functions
Remove(string key)
will remove that key from theSavegame
ReadFromDisk()
will load the keys from disk.Clear()
will remove all keys from thisSavegame
.
SavegameController
The SavegameController
is a Component
that can be added to any GameObject
.
It provides the basic structure to save and load in-game. This controller can be modified.
Best practices
- To save your own type, annotate it with
[System.Serializable]
or add a surrogate for it to theUnitySurrogateSelector.cs
file. Do not add types withUnityEngine
properties. - As a rule, always load
UnityEngine
types that contain properties withUnityEngine
types withpublic void Load<T>(string key, ref T obj)
. - Save the data you need. If you need the
Mesh
of aMeshRenderer
, save theMesh
directly.MeshRenderer
does not save theMesh
.
Supported types
This package has implementations for the types below. All of these types have been tested. This package saves the settable properties of the given type.
- Fully saved: All settable fields and properties are saved.
- Partially saved: Type contains UnityEngine properties that are not saved.
- Unsupported: The type cannot (should not) be saved.
Examples:
- SAVED: Matrix4x4 contains properties of struct Vector4, it is saved.
- NOT SAVED: Material contains a Texture property. It is not saved. You can save the Texture manually.
The structs below are saved in any type, even when nested within another type.
Structs
Struct | Unsupported | Partially saved | Fully saved |
---|---|---|---|
Primitive types (string, int, float, etc.) | X | ||
Vector2 | X | ||
Vector2Int | X | ||
Vector3 | X | ||
Vector3Int | X | ||
Vector4 | X | ||
Quaternion | X | ||
Color | X | ||
Color32 | X | ||
Bounds | X | ||
BoundsInt | X | ||
Matrix4x4 | X | ||
BoneWeight | X | ||
BoneWeight1 | X |
Components
Components
save the structs defined above and all their settable fields and properties.
References to other GameObjects
, Components
or complex UnityEngine
types are not saved.
Component | Unsupported | Partially saved | Fully saved |
---|---|---|---|
GameObject | X | ||
Transform | X | ||
BoxCollider | X | ||
AudioSource | X | ||
MeshFilter | X[1] | ||
MeshRenderer | X | ||
RigidBody | X[2] | ||
Light | X |
- [1] MeshFilter only contains a Mesh; save the Mesh directly instead.
- [2] Rigidbody might throw an error when loading because of inertia tensor values. It still loads normally; error can be caught/ignored.
UnityEngine Types
UnityEngine
types save the structs defined above and all their settable fields and properties.
References to other GameObjects
, Components
or complex UnityEngine
types are not saved.
UnityEngine Type | Unsupported | Partially saved | Fully saved |
---|---|---|---|
Mesh | X | ||
Material | X |
What is saved
It is important to note that only settable fields and properties are saved. All types in the structs table are always saved in any type. UnityEngine types that are not in this table are always skipped. You can save them separately.
The table below shows a sample of Components and some of their saved properties. As you can see, only UnityEngine types are skipped when saving. If you need them, save them separately and assign them to the component in code.
Component | Saves | Does not save |
---|---|---|
GameObject | Name, Tag, HideFlags, Layer, IsStatic | Hierarchy, Components |
Transform | Position, Rotation, Scale, LocalPosition, LocalRotation, LocalScale | Parent, Hierarchy |
BoxCollider | Center, Size, IsTrigger, ContactOffset | Material, RigidBody |
AudioSource | Volume, Pitch, Time, Loop, PlayOnAwake | AudioClip, AudioMixer |
When loading a GameObject, Component or UnityEngine type, only the values are loaded from disk, no new object is created. This is to prevent leaks for objects such as GameObjects, Meshes and Materials.