2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Unity】PlayerPrefs に任意の型を保存する拡張

Last updated at Posted at 2024-03-26

こんにちは uni928 です。
皆さんは PlayerPrefs を使用する機会はありますか?

私はほとんどありませんが
プログラミング初心者の方には使いやすい
機能だと思います。

Unity を習得する際も
PlayerPrefs で練習するのは
多くの人が通る道ではないでしょうか?
そうでもないでしょうか?

しかしながら PlayerPrefs は
string int float しか保存する事はできません。

そこで PlayerPrefs に
任意の型を保存する拡張を
提供したいと思います。

Unity 習得中の人も
是非導入して頂けると幸いです。


https://drive.google.com/file/d/1KFfQqLLjSHW8_n1Mr5V9bPV-a_K7ye31/view?usp=sharing

unitypackage 版は
上記の URL からダウンロードして下さい。

SephirothPlayerPrefsExtension.cs
以外のファイルは削除してかまいません。
HowToUse.pdf 等は容量が大きいため
削除する事を推奨します。


では仕組みを作成していきます。

SephirothPlayerPrefsExtension.cs を作成して
下記の内容にして下さい。

SephirothPlayerPrefsExtension.cs
using System.Security.Cryptography;

namespace SephirothTools
{
    public static class SephirothPlayerPrefsExtension
    {
        private static readonly System.Runtime.Serialization.Formatters.Binary.BinaryFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
        private static readonly System.IO.MemoryStream ms = new System.IO.MemoryStream();

        public static void Save<T>(string key, T value)
        {
            ms.Position = 0;
            ms.SetLength(0);
            formatter.Serialize(ms, value);
            UnityEngine.PlayerPrefs.SetString(key, System.Convert.ToBase64String(Encrypt(ms.ToArray())));
        }

        public static T Load<T>(string key, T defaultValue = default)
        {
            string loadValue = UnityEngine.PlayerPrefs.GetString(key, "");
            if (string.IsNullOrEmpty(loadValue))
            {
                return defaultValue;
            }

            byte[] bytes = Decrypt(System.Convert.FromBase64String(loadValue));
            ms.Position = 0;
            ms.Write(bytes, 0, bytes.Length);
            ms.Position = 0;

            return (T)formatter.Deserialize(ms);
        }

        private const string AesIV = @"kgificpplgodckdi"; // Declare a random string of 16 single-byte characters.
        private const string AesKey = @"lfsaokfdsjhahfppjdfjshfsdgssdfas"; // Declare a random string of 32 single-byte characters.
        private const int KeySize = 256;
        private const int BlockSize = 128;

        private static byte[] Encrypt(byte[] byteValue)
        {
            return GetAes().CreateEncryptor().TransformFinalBlock(byteValue, 0, byteValue.Length);
        }

        private static byte[] Decrypt(byte[] byteValue)
        {
            return GetAes().CreateDecryptor().TransformFinalBlock(byteValue, 0, byteValue.Length);
        }

        private static AesManaged GetAes()
        {
            var aes = new AesManaged();
            aes.KeySize = KeySize;
            aes.BlockSize = BlockSize;
            aes.Mode = CipherMode.CBC;
            aes.IV = System.Text.Encoding.UTF8.GetBytes(AesIV);
            aes.Key = System.Text.Encoding.UTF8.GetBytes(AesKey);
            aes.Padding = PaddingMode.PKCS7;
            return aes;
        }
    }
}

PlayerPrefs.SetString("key1", value);
の代わりに
SephirothTools.SephirothPlayerPrefsExtension.Save<string>("key1", value);
を使用します。

PlayerPrefs.GetString("key1");
の代わりに
SephirothTools.SephirothPlayerPrefsExtension.Load<string>("key1");
を使用します。

多くの型を保存できるため
SephirothTools.SephirothPlayerPrefsExtension.Save<List<int>>("key2", new List(){1, 2, 3});
List<int> loadList = SephirothTools.SephirothPlayerPrefsExtension.Load<List<int>>("key2");
のような記述もできます。

Save<T> Load<T> の T の部分に
保存する型を入れる事で使用できます。

暗号化に関しては
直接書いてしまっているため
逆コンパイルに対応できません。
おまじない程度の認識でお願いします。
暗号化しても速度がほとんど変わらないため
やる意味は薄くても記述する価値があります。


あとがき

以上が PlayerPrefs に
任意の型を保存する仕組みになります。

PlayerPrefs の代わりに
SephirothTools.SephirothPlayerPrefsExtension.Save
SephirothTools.SephirothPlayerPrefsExtension.Load
を使用するだけなので
使用するのは簡単だと思います。

この仕組みが
皆さんの開発の助けになれば幸いです。
閲覧ありがとうございました。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?