mirror of
https://github.com/AnnulusGames/Alchemy.git
synced 2025-01-22 08:18:51 -05:00
Add: serialization section
This commit is contained in:
parent
1ec10ab59d
commit
8be6597de0
80
docs/articles/ja/alchemy-serialization-process.md
Normal file
80
docs/articles/ja/alchemy-serialization-process.md
Normal file
@ -0,0 +1,80 @@
|
||||
# Alchemyのシリアル化プロセス
|
||||
|
||||
Alchemyでは、対象の型に`[AlchemySerialize]`属性を付加することで専用のSource Generatorが`ISerializationCallbackReceiver`を自動で実装します。この処理の中で`[AlchemySerializeField]`属性が付加されたフィールドを全て取得し、Unity.Serializationパッケージを用いてJson形式に変換します。ただし、UnityEngine.Objectのフィールドに関してはJson形式で扱うことができないため、単一のListに実体を保存しJsonにはそのindexを書き込みます。
|
||||
|
||||
例えば、以下のようなクラスがあったとします。
|
||||
|
||||
```cs
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Alchemy.Serialization;
|
||||
|
||||
[AlchemySerialize]
|
||||
public partial class AlchemySerializationExample : MonoBehaviour
|
||||
{
|
||||
[AlchemySerializeField, NonSerialized]
|
||||
public Dictionary<string, GameObject> dictionary = new();
|
||||
}
|
||||
```
|
||||
|
||||
これに対し、Alchemyは以下のようなコードを生成します。
|
||||
|
||||
```cs
|
||||
partial class AlchemySerializationExample : global::UnityEngine.ISerializationCallbackReceiver
|
||||
{
|
||||
[global::System.Serializable]
|
||||
sealed class AlchemySerializationData
|
||||
{
|
||||
[global::System.Serializable]
|
||||
public sealed class Item
|
||||
{
|
||||
[global::UnityEngine.HideInInspector] public bool isCreated;
|
||||
[global::UnityEngine.TextArea] public string data;
|
||||
}
|
||||
|
||||
public Item dictionary = new();
|
||||
|
||||
[global::UnityEngine.SerializeField] private global::System.Collections.Generic.List<UnityEngine.Object> unityObjectReferences = new();
|
||||
|
||||
public global::System.Collections.Generic.IList<UnityEngine.Object> UnityObjectReferences => unityObjectReferences;
|
||||
}
|
||||
|
||||
[global::UnityEngine.HideInInspector, global::UnityEngine.SerializeField] private AlchemySerializationData alchemySerializationData = new();
|
||||
|
||||
void global::UnityEngine.ISerializationCallbackReceiver.OnBeforeSerialize()
|
||||
{
|
||||
if (this is global::Alchemy.Serialization.IAlchemySerializationCallbackReceiver receiver) receiver.OnBeforeSerialize();
|
||||
alchemySerializationData.UnityObjectReferences.Clear();
|
||||
|
||||
try
|
||||
{
|
||||
alchemySerializationData.dictionary.data = global::Alchemy.Serialization.Internal.SerializationHelper.ToJson(this.dictionary , alchemySerializationData.UnityObjectReferences);
|
||||
alchemySerializationData.dictionary.isCreated = true;
|
||||
}
|
||||
catch (global::System.Exception ex)
|
||||
{
|
||||
global::UnityEngine.Debug.LogException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
void global::UnityEngine.ISerializationCallbackReceiver.OnAfterDeserialize()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (alchemySerializationData.dictionary.isCreated)
|
||||
{
|
||||
this.dictionary = global::Alchemy.Serialization.Internal.SerializationHelper.FromJson<System.Collections.Generic.Dictionary<string, UnityEngine.GameObject>>(alchemySerializationData.dictionary.data, alchemySerializationData.UnityObjectReferences);
|
||||
}
|
||||
}
|
||||
catch (global::System.Exception ex)
|
||||
{
|
||||
global::UnityEngine.Debug.LogException(ex);
|
||||
}
|
||||
|
||||
if (this is global::Alchemy.Serialization.IAlchemySerializationCallbackReceiver receiver) receiver.OnAfterDeserialize();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
このような手法を取っているため`[AlchemySerializeField]`を使用するとシリアライズ/デシリアライズにかかる処理負荷が増加します。そのため可能な限り`[AlchemySerializeField]`の使用を避けることが推奨されます。
|
21
docs/articles/ja/debugging-serialized-data.md
Normal file
21
docs/articles/ja/debugging-serialized-data.md
Normal file
@ -0,0 +1,21 @@
|
||||
# シリアル化データのデバッグ
|
||||
|
||||
`[AlchemySerialize]`と同時に`[ShowAlchemySerializationData]`属性を付加することで、Inspector上からシリアル化されたデータを確認することができるようになります。
|
||||
|
||||
```cs
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Alchemy.Serialization;
|
||||
|
||||
[AlchemySerialize]
|
||||
[ShowAlchemySerializationData]
|
||||
public partial class AlchemySerializationExample : MonoBehaviour
|
||||
{
|
||||
[AlchemySerializeField, NonSerialized]
|
||||
public Dictionary<string, GameObject> dictionary = new();
|
||||
}
|
||||
```
|
||||
|
||||
![img](../../images/img-show-serialization-data.png)
|
||||
|
21
docs/articles/ja/serialization-callback.md
Normal file
21
docs/articles/ja/serialization-callback.md
Normal file
@ -0,0 +1,21 @@
|
||||
# シリアル化コールバック
|
||||
|
||||
`[AlchemySerialize]`属性を使用するとSource Generatorが`ISerializationCallbackReceiver`を実装するため、通常通り`ISerializationCallbackReceiver`を使用してコールバックを追加することができません。
|
||||
|
||||
そのため、Alchemyでは代替となるインターフェースとして`IAlchemySerializationCallbackReceiver`を提供しています。`[AlchemySerialize]`を使用する際には`ISerializationCallbackReceiver`の代わりにこちらを利用してください。
|
||||
|
||||
```cs
|
||||
[AlchemySerialize]
|
||||
public partial class AlchemySerializationSample : MonoBehaviour, IAlchemySerializationCallbackReceiver
|
||||
{
|
||||
public void OnAfterDeserialize()
|
||||
{
|
||||
Debug.Log("OnAfterDeserialize");
|
||||
}
|
||||
|
||||
public void OnBeforeSerialize()
|
||||
{
|
||||
Debug.Log("OnBeforeSerialize");
|
||||
}
|
||||
}
|
||||
```
|
51
docs/articles/ja/serialization-extension.md
Normal file
51
docs/articles/ja/serialization-extension.md
Normal file
@ -0,0 +1,51 @@
|
||||
# シリアル化拡張
|
||||
|
||||
Dictionaryなどの通常のUnityがシリアル化できない型を編集したい場合、`[AlchemySerialize]`属性を使用してシリアル化を行うことができます。
|
||||
|
||||
シリアル化拡張を使用したい場合、[Unity.Serialization](https://docs.unity3d.com/Packages/com.unity.serialization@3.1/manual/index.html)パッケージが必要になります。また、リフレクションを用いたUnity.Serializationのシリアル化はUnity2022.1以前のAOT環境で動作しない可能性があります。詳細はパッケージのマニュアルを確認してください。
|
||||
|
||||
以下はAlchemyのシリアル化拡張を用いて様々な型をシリアル化し、Inspectorで編集可能にするサンプルです。
|
||||
|
||||
```cs
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Alchemy.Serialization; // Alchemy.Serialization名前空間をusingに追加
|
||||
|
||||
// [AlchemySerialize]属性を付加することでAlchemyのシリアル化拡張が有効化されます。
|
||||
// 任意の基底クラスを持つ型に使用できますが、SourceGeneratorがコード生成を行うため対象型はpartialである必要があります。
|
||||
[AlchemySerialize]
|
||||
public partial class AlchemySerializationExample : MonoBehaviour
|
||||
{
|
||||
// 対象のフィールドに[AlchemySerializeField]属性と[NonSerialized]属性を付加します。
|
||||
[AlchemySerializeField, NonSerialized]
|
||||
public HashSet<GameObject> hashSet = new();
|
||||
|
||||
[AlchemySerializeField, NonSerialized]
|
||||
public Dictionary<string, GameObject> dictionary = new();
|
||||
|
||||
[AlchemySerializeField, NonSerialized]
|
||||
public (int, int) tuple;
|
||||
|
||||
[AlchemySerializeField, NonSerialized]
|
||||
public Vector3? nullable = null;
|
||||
}
|
||||
```
|
||||
|
||||
![img](../../images/img-serialization-sample.png)
|
||||
|
||||
現在Inspectorで編集可能な型は以下の通りです。
|
||||
|
||||
* プリミティブ型
|
||||
* UnityEngine.Object
|
||||
* AnimationCurve
|
||||
* Gradient
|
||||
* 配列
|
||||
* List<>
|
||||
* HashSet<>
|
||||
* Dictionary<,>
|
||||
* ValueTuple<>
|
||||
* Nullable<>
|
||||
* 以上の型のフィールドで構成されるclass/struct
|
||||
|
||||
シリアル化の技術的な詳細については[Alchemyのシリアル化プロセス](alchemy-serialization-process.md)を参照してください。
|
@ -83,6 +83,16 @@
|
||||
- name: Hierarchyの装飾
|
||||
href: hierarchy-decoration.md
|
||||
|
||||
- name: Serialization
|
||||
- name: シリアル化拡張
|
||||
href: serialization-extension.md
|
||||
- name: Alchemyのシリアル化プロセス
|
||||
href: alchemy-serialization-process.md
|
||||
- name: シリアル化データのデバッグ
|
||||
href: debugging-serialized-data.md
|
||||
- name: シリアル化コールバック
|
||||
href: serialization-callback.md
|
||||
|
||||
- name: Others
|
||||
- name: 他ライブラリとの比較
|
||||
href: comparison-with-other-libraries.md
|
BIN
docs/images/img-serialization-sample.png
Normal file
BIN
docs/images/img-serialization-sample.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 67 KiB |
BIN
docs/images/img-show-serialization-data.png
Normal file
BIN
docs/images/img-show-serialization-data.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 57 KiB |
Loading…
Reference in New Issue
Block a user