うにてぃブログ

主にUnityとC#に関する記事を書いていきます

【Unity】ScriptableSingleton の使いみち

ScriptableSingleton は UnityEditor を終了するまで存在するインスタンスです

主な利用用途としては
・EditorWindow 間でのデータ共有 ・EditorWindow を開いていない間データを確保したい場合 が考えられる

EditorWindow 間でのデータ共有

例えば Selection のログを 複数の EditorWindow で利用する場合
各 EditorWindow で ログをハンドルするよりも、共通のクラスを作成しておき
各 EditorWindow がそのクラスからデータをもらったほうが良い

EditorWindow を開いていない間データを確保したい場合

上記の続きであるが EditorWindow 側に Selection のログ機能を実装した場合
EditorWindow が開いていない場合はログを取ることができなくなってしまう

そのため static なクラスと ScriptableSingleton を利用するといい感じにできる

実装例

ProjectWindow の Selection のログを常に取得するクラスです

ScriptableSingletonで共有・保存したい値はシリアライズ可能なフィールドである必要があります

using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;

[InitializeOnLoad]
public static class SelectionProjectLog
{
    public static IEnumerable<string> Logs => ScriptableSingleton<Log>.instance.Queue;
    
    public static Action SelectionChanged;

    private class Log : ScriptableSingleton<Log>
    {
        private const int MAX_SIZE = 50;
        
        public Queue<string> Queue = new Queue<string>();
        
        public bool Enqueue(params string[] guids)
        {
            if (!guids.Any())
                return false;
            
            foreach (var guid in guids)
                Queue.Enqueue(guid);

            while (Queue.Count > MAX_SIZE)
                Queue.Dequeue();

            return true;
        }
    }
    
    static SelectionProjectLog()
    {
        Selection.selectionChanged += () =>
        {
            if (ScriptableSingleton<Log>.instance.Enqueue(Selection.assetGUIDs))
                SelectionChanged?.Invoke();
        };
    }
}