-
Notifications
You must be signed in to change notification settings - Fork 16
Data
Notes: Data use Unity.Serialization to serialize data
It allows you to store data in byte[] form in blocks called profiles. Usage is quite simple and similar to PlayerPrefs
Each profile is a Dictionary with the key as a string and the value as a byte[].
The default profile will be 0 if you want to Load or Save in another profile you will need to call the ChangeProfile
function.
using Pancake;
Data.ChangeProfile(1);
The Load
function will load all the data of the current profile into memory. When the game starts it will be called automatically
using Pancake;
Data.Load();
The Save
function will save all changes of the current profile to a file. It will be called automatically when you leave the game.
using Pancake;
Data.Save();
When you switch profiles, it will save the data of the current profile and then load the profile you need.
After you have successfully loaded the profile you can Load
part data from the profile by key in memory using the following two methods
using Pancake;
PlayerData player = Data.Load<PlayerData>("hero");
Data.Load<PlayerData>("hero", out PlayerData player);
Call Save
if you want to add new or overwrite data to the profile in memory
using Pancake;
PlayerData player = new PlayerData();
Data.Save<PlayerData>(player);
To check if the profile has a key, you can use the HasKey
function
using Pancake;
bool exist = Data.HasKey("hero");
To delete the key from the profile you can use the function DeleteKey
using Pancake;
Data.DeleteKey("hero");
To delete the entire key, call DeleteAll
using Pancake;
Data.DeleteAll();
public class PlayerData : UnitData
{
public int health;
public int damage;
}
public class UnitData
{
public int id;
public string name;
}
var player = new PlayerData()
{
id = 1, name = "Anya", health = 100, damage = 25
};
Data.Save("all-player", player);
In case your data class changes over each version such as adding or removing data, you need to create a binary adapter class to implement serialization/deserialization for that class. You can follow the following example for easier visualization.
using Unity.Collections.LowLevel.Unsafe.NotBurstCompatible;
[Serializable]
public class Enemy // Old data class
{
public string name;
public float damage;
public int health;
}
public class EnemyBinaryAdapter : VersionedBinaryAdapterBase, IBinaryAdapter<Enemy>
{
private const byte CURRENT_ADAPTER_VERSION = 0;
public EnemyBinaryAdapter(byte adapterVersion)
: base(adapterVersion)
{
}
public unsafe void Serialize(in BinarySerializationContext<Enemy> context, Enemy value)
{
var writer = context.Writer;
WriteAdapterVersion(writer);
writer->AddNBC(value.name);
writer->Add(value.damage);
writer->Add(value.health);
}
public unsafe Enemy Deserialize(in BinaryDeserializationContext<Enemy> context)
{
var reader = context.Reader;
byte serializedVersion = ReadAdapterVersion(reader);
if (serializedVersion == CURRENT_ADAPTER_VERSION)
{
reader->ReadNextNBC(out string name);
float damage = reader->ReadNext<float>();
int hp = reader->ReadNext<int>();
return new Enemy {name = name, damage = damage, health = hp};
}
throw new SerializationVersionException(GetVersionExceptionMessage(serializedVersion));
}
}
In the next version the damage attribute is removed and the description attribute is added.
using Unity.Collections.LowLevel.Unsafe.NotBurstCompatible;
[Serializable]
public class Enemy
{
public string name;
// public float damage;
public int health;
public string description;
}
public class EnemyBinaryAdapter : VersionedBinaryAdapterBase, IBinaryAdapter<Enemy>
{
private const byte CURRENT_ADAPTER_VERSION = 1;
private const byte OLD_ADAPTER_VERSION = 0;
public EnemyBinaryAdapter(byte adapterVersion)
: base(adapterVersion)
{
}
public unsafe void Serialize(in BinarySerializationContext<Enemy> context, Enemy value)
{
var writer = context.Writer;
WriteAdapterVersion(writer);
writer->AddNBC(value.name);
writer->Add(value.health);
writer->AddNBC(value.description);
}
public unsafe Enemy Deserialize(in BinaryDeserializationContext<Enemy> context)
{
var reader = context.Reader;
byte serializedVersion = ReadAdapterVersion(reader);
if (serializedVersion == OLD_ADAPTER_VERSION)
{
reader->ReadNextNBC(out string name);
reader->ReadNext<float>(); // skip bytes for: damage
int hp = reader->ReadNext<int>();
return new Enemy {name = name, health = hp};
}
if (serializedVersion == CURRENT_ADAPTER_VERSION)
{
reader->ReadNextNBC(out string name);
int hp = reader->ReadNext<int>();
reader->ReadNextNBC(out string description);
return new Enemy {name = name, health = hp, description = description};
}
throw new SerializationVersionException(GetVersionExceptionMessage(serializedVersion));
}
}
When you deploy a binary adapter you need to register it to the serialize/deserialize process via the command Data.SetAdapters
Data.SetAdapters(new EnemyBinaryAdapter(1));
Call Data.Load<>
10000 times
-
Use serialize
Newtonsoft.Json
-
Use
Unity Serialization Binary
Call Data.Load<>
1000 times
Load<int> |
NewtonSoft (json) | Unity.Serialization (binary) |
---|---|---|
UnityEditor (window 11 core i7 10700) | 195ms | 2ms |
LDPlayer 9 (4 core ARM64) | 348ms | 10ms |
Samsung S10 (Android 12 ARM64) | 216ms | 5ms |
Iphone 12 ProMax (iOS 16.3 ARM64) | 72ms | 1ms |
Load<string> |
NewtonSoft (json) | Unity.Serialization (binary) |
---|---|---|
UnityEditor (window 11 core i7 10700) | 402ms | 1ms |
LDPlayer 9 (4 core ARM64) | 791ms | 16ms |
Samsung S10 (Android 12 ARM64) | 519ms | 8ms |
Iphone 12 ProMax (iOS 16.3 ARM64) | 173ms | 1ms |
Load<float> |
NewtonSoft (json) | Unity.Serialization (binary) |
---|---|---|
UnityEditor (window 11 core i7 10700) | 211ms | 1ms |
LDPlayer 9 (4 core ARM64) | 308ms | 9ms |
Samsung S10 (Android 12 ARM64) | 183ms | 5ms |
Iphone 12 ProMax (iOS 16.3 ARM64) | 53ms | 1ms |
Load<DateTime> |
NewtonSoft (json) | Unity.Serialization (binary) |
---|---|---|
UnityEditor (window 11 core i7 10700) | 348ms | 13ms |
LDPlayer 9 (4 core ARM64) | 492ms | 48ms |
Samsung S10 (Android 12 ARM64) | 314ms | 14ms |
Iphone 12 ProMax (iOS 16.3 ARM64) | 95ms | 4ms |
Load<Vector2> |
NewtonSoft (json) | Unity.Serialization (binary) |
---|---|---|
UnityEditor (window 11 core i7 10700) | 766ms | 3ms |
LDPlayer 9 (4 core ARM64) | 2246ms | 35ms |
Samsung S10 (Android 12 ARM64) | 1379ms | 21ms |
Iphone 12 ProMax (iOS 16.3 ARM64) | 309ms | 7ms |
Load<Vector3> |
NewtonSoft (json) | Unity.Serialization (binary) |
---|---|---|
UnityEditor (window 11 core i7 10700) | 791ms | 3ms |
LDPlayer 9 (4 core ARM64) | 2727ms | 36ms |
Samsung S10 (Android 12 ARM64) | 1578ms | 19ms |
Iphone 12 ProMax (iOS 16.3 ARM64) | 357ms | 9ms |