【Unity】ISerializationCallbackReceiverを使ったサンプル

ISerializationCallbackReceiverは、Unity Engineのインターフェースの1つであり、オブジェクトのシリアル化(保存)とデシリアル化(読み込み)のタイミングでコールバックを受け取るために使用されます。

このインターフェースを実装することで、オブジェクトがシリアル化される前後に特定の処理を実行することができます。たとえば、オブジェクト内のフィールドの値を変更する必要がある場合や、シリアル化されたデータの復元に必要な情報を収集する必要がある場合に使用されます。

ISerializationCallbackReceiverは、2つのメソッドを持っています。OnBeforeSerializeは、オブジェクトがシリアル化される前に呼び出されます。OnAfterDeserializeは、オブジェクトがデシリアル化された後に呼び出されます。これらのメソッドは、オブジェクト内のデータを操作するために使用されます。

ISerializationCallbackReceiverは、Unityのシリアル化システムで広く使用されており、プログラマーが独自のデータ構造を作成する場合に便利です。

ScriptableObjectを使用して作成された簡単なサンプル

using UnityEngine;

[CreateAssetMenu(fileName = "NewData", menuName = "Sample Data")]
public class SampleData : ScriptableObject, ISerializationCallbackReceiver
{
    [SerializeField] private string data;
    [SerializeField] private string encryptedData;

    public void OnBeforeSerialize()
    {
        // dataを暗号化して、encryptedDataにセットする
        encryptedData = MyEncryptionUtility.Encrypt(data);
    }

    public void OnAfterDeserialize()
    {
        // encryptedDataを復号化して、dataにセットする
        data = MyEncryptionUtility.Decrypt(encryptedData);
    }
}

この例では、SampleDataというクラスを作成し、ScriptableObjectを継承しています。このクラスは、インスペクターから作成できるように、CreateAssetMenu属性を使用して定義されています。

SampleDataクラスには、dataというフィールドとencryptedDataというフィールドがあります。OnBeforeSerializeメソッドは、dataを暗号化してencryptedDataにセットします。OnAfterDeserializeメソッドは、encryptedDataを復号化してdataにセットします。これにより、SampleDataクラスのインスタンスは、シリアル化される前にデータを暗号化し、デシリアル化された後にデータを復号化することができます。

この例は、暗号化および復号化のためのMyEncryptionUtilityクラスが定義されていることを想定しています。このように、ISerializationCallbackReceiverを使用することで、オブジェクトのシリアル化やデシリアル化のタイミングでカスタム処理を実行することができます。

MyEncryptionUtilityのサンプル

安全な暗号化アルゴリズムとしては、AES (Advanced Encryption Standard) などがあります。以下は、AESを使用して文字列を暗号化および復号化するためのサンプルコードです。

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

public static class MyEncryptionUtility
{
    private const string key = "MySecretKey123"; // 暗号化に使用するキー

    public static string Encrypt(string data)
    {
        byte[] keyBytes = Encoding.UTF8.GetBytes(key);
        byte[] dataBytes = Encoding.UTF8.GetBytes(data);

        using (Aes aes = Aes.Create())
        {
            aes.Key = keyBytes;
            aes.GenerateIV();

            using (MemoryStream ms = new MemoryStream())
            {
                ms.Write(aes.IV, 0, aes.IV.Length);

                using (CryptoStream cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(dataBytes, 0, dataBytes.Length);
                    cs.FlushFinalBlock();
                }

                return Convert.ToBase64String(ms.ToArray());
            }
        }
    }

    public static string Decrypt(string encryptedData)
    {
        byte[] keyBytes = Encoding.UTF8.GetBytes(key);
        byte[] dataBytes = Convert.FromBase64String(encryptedData);

        using (Aes aes = Aes.Create())
        {
            byte[] iv = new byte[aes.IV.Length];
            Array.Copy(dataBytes, 0, iv, 0, aes.IV.Length);

            aes.Key = keyBytes;
            aes.IV = iv;

            using (MemoryStream ms = new MemoryStream())
            {
                using (CryptoStream cs = new CryptoStream(ms, aes.CreateDecryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(dataBytes, aes.IV.Length, dataBytes.Length - aes.IV.Length);
                    cs.FlushFinalBlock();
                }

                byte[] decryptedDataBytes = ms.ToArray();
                return Encoding.UTF8.GetString(decryptedDataBytes, 0, decryptedDataBytes.Length);
            }
        }
    }
}

この例では、MyEncryptionUtilityという静的クラスが作成されています。このクラスには、EncryptメソッドとDecryptメソッドがあります。これらのメソッドは、文字列をAESを使用して暗号化および復号化するために使用されます。

暗号化には、キーを使用してIVを生成し、IVとデータをAESで暗号化します。復号化では、キーを使用してIVを復元し、IVと暗号化されたデータをAESで復号化します。

この例では、UTF-8エンコーディングを使用して文字列をバイト配列に変換しています。暗号化されたデータをBase64エンコーディングでエンコードして、復号化時にデコードします。

ScriptableObject,Unity

Posted by hidepon