以前の記事でざっくりとしか ScriptableSingleton の使用例を書いてなかったので
使えるように整形したので紹介します
※ ScriptableSingleton は UnityEditor でしか利用できません
Selection ログ
Hierarchy の選択ログと ProjectWindow の選択ログを保持するクラス
using System; using System.Collections.Generic; using System.Text; using UnityEditor; using UnityEngine; namespace Log { [Serializable] public class HierarchyData { public string SceneName; public string Path; public override bool Equals(object obj) { var data = obj as HierarchyData; return data.SceneName == SceneName && data.Path == Path; } public override int GetHashCode() { return base.GetHashCode(); } } [InitializeOnLoad] public static class SelectionLog { private static readonly StringBuilder BuilderCache = new StringBuilder(); // Hierarchyのログ public static IEnumerable<HierarchyData> HierarchyLogs { get { return HierarchyLogData.instance.Logs; } } // Projectのログ public static IEnumerable<string> ProjectLogs { get { return ProjectLogData.instance.Logs; } } private class HierarchyLogData : ScriptableSingleton<HierarchyLogData> { public IEnumerable<HierarchyData> Logs { get { return instance._logs; } } [SerializeField] private List<HierarchyData> _logs = new List<HierarchyData>(LogMax + 1); private const int LogMax = 50; internal void AddLog(HierarchyData data) { _logs.RemoveAll(l => l.Equals(data)); _logs.Insert(0, data); while (_logs.Count > LogMax) _logs.RemoveAt(LogMax); } } private class ProjectLogData : ScriptableSingleton<ProjectLogData> { public IEnumerable<string> Logs { get { return instance._logs; } } [SerializeField] private List<string> _logs = new List<string>(LogMax + 1); private const int LogMax = 50; internal void AddLog(string data) { _logs.RemoveAll(l => l.Equals(data)); _logs.Insert(0, data); while (_logs.Count > LogMax) _logs.RemoveAt(LogMax); } } static SelectionLog() { Selection.selectionChanged += SelectionChanged; } private static void SelectionChanged() { foreach (var transform in Selection.transforms) { var data = new HierarchyData { SceneName = transform.gameObject.scene.name, Path = HierarchyPath(transform), }; HierarchyLogData.instance.AddLog(data); } foreach (var guid in Selection.assetGUIDs) ProjectLogData.instance.AddLog(guid); } private static string HierarchyPath(Transform transform) { BuilderCache.Length = 0; BuilderCache.Append(transform.name); while (transform.parent != null) { BuilderCache.Insert(0, transform.parent.name + "/"); transform = transform.parent; } return BuilderCache.ToString(); } } }
Console ログ
Console のログを保持するクラス
using System; using System.Collections.Generic; using UnityEditor; using UnityEngine; namespace Log { [Serializable] public class ConsoleData { public string Condition; public string Stacktrace; public LogType Type; public ConsoleData(string condition, string stacktrace, LogType type) { Condition = condition; Stacktrace = stacktrace; Type = type; } public override bool Equals(object obj) { var data = obj as ConsoleData; return data.Type == Type && data.Condition == Condition && data.Stacktrace == Stacktrace; } public override int GetHashCode() { return base.GetHashCode(); } } [InitializeOnLoad] public static class ConsoleLog { public static IEnumerable<ConsoleData> HierarchyLogs { get { return ConsoleLogData.instance.Logs; } } private class ConsoleLogData : ScriptableSingleton<ConsoleLogData> { public IEnumerable<ConsoleData> Logs { get { return instance._logs; } } [SerializeField] private List<ConsoleData> _logs = new List<ConsoleData>(LogMax + 1); private const int LogMax = 100; internal void AddLog(ConsoleData data) { _logs.RemoveAll(l => l.Equals(data)); _logs.Insert(0, data); while (_logs.Count > LogMax) _logs.RemoveAt(LogMax); } } static ConsoleLog() { Application.logMessageReceived += logMessageReceived; } private static void logMessageReceived(string condition, string stacktrace, LogType type) { ConsoleLogData.instance.AddLog(new ConsoleData(condition, stacktrace, type)); } } }
注意
処理が同じなため、汎用的なクラスを利用したかったが ScriptableSingleton
public class LogData<T> : ScriptableSingleton<LogData<T>> { public IEnumerable<T> Logs { get { return instance._logs; } } [SerializeField] private List<T> _logs = new List<T>(LogMax + 1); private const int LogMax = 50; internal void AddLog(T data) { _logs.RemoveAll(l => l.Equals(data)); _logs.Insert(0, data); while (_logs.Count > LogMax) _logs.RemoveAt(LogMax); } }