きゅぶろぐ

きゅぶんずの ぶろぐができて べんりだな

最近Editorでのみキャッシュして起動高速化したいものが増えてきたのでEditorPrefsWrapperでも作った

EditorPrefsを気軽に使いたいけど、
UnityEditor.EditorPrefsのためだけにdefine書いたり、
そもそもstringしかダメだから一回シリアライズするのも面倒だな・・・って時のために、
EditorPrefsWrapperを作ったのでメモ。

使い方

MessagePack-CSharpに依存しています。

// define切らなくてもEditor以外ではTryLoadがfalseを返すだけ。
if (EditorPrefsWrapper.TryLoad<HogeCache>(out var hogeCache))
{
    // キャッシュ使う
}

// Saveも同様、こっちはEditor以外では引数の評価も行われない。
EditorPrefsWrapper.Save(new HogeCache("value", DateTime.Now));

// もちろんこれでもオッケーだけどTryLoadの方が便利じゃない?
if (EditorPrefsWrapper.HasKey<HogeCache>())
{
    var hogeCache = EditorPrefsWrapper.Load<HogeCache>();
}

[MessagePackObject]
public class HogeCache
{
    [Key(0)] public string Value { get; }
    [Key(1)] public DateTime Time { get; }

    public HogeCache(string value, DateTime time)
    {
        Value = value;
        Time = time;
    }
}

中身

using System;
using System.Diagnostics;
using MessagePack;

namespace Sandbox
{
    public static class EditorPrefsWrapper
    {
        public static bool HasKey<T>()
        {
#if UNITY_EDITOR
            return UnityEditor.EditorPrefs.HasKey(GetKey<T>());
#else
            return false;
#endif
        }

        [Conditional("UNITY_EDITOR")]
        public static void Save<T>(T value)
        {
#if UNITY_EDITOR
            var key = GetKey<T>();
            var base64String = Convert.ToBase64String(MessagePackSerializer.Serialize(value));
            UnityEditor.EditorPrefs.SetString(key, base64String);
#endif
        }

        public static bool TryLoad<T>(out T result)
        {
            if (!HasKey<T>())
            {
                result = default;
                return false;
            }

            result = Load<T>();
            return true;
        }

        public static T Load<T>()
        {
#if UNITY_EDITOR
            var key = GetKey<T>();
            var base64String = UnityEditor.EditorPrefs.GetString(key);
            var fromBase64String = Convert.FromBase64String(base64String);
            return MessagePackSerializer.Deserialize<T>(fromBase64String);
#else
            throw new NotSupportedException("Editor Only");
#endif
        }

#if UNITY_EDITOR
        private static string GetKey<T>()
        {
            return $"EditorPrefsWrapper_{typeof(T).Name}";
        }
#endif
    }
}