Unity 在Preferences或Project Setting窗口创建自定义配置

官方文档链接 https://docs.unity3d.com/2020.3/Documentation/ScriptReference/SettingsProvider.html

一直不习惯使用Unity提供的ScriptableObject来存储数据,更习惯使用xml和json这种通用格式
这个自定义的配置设置看起来还挺方便的,可以用来做一些编辑器内的选项配置

#if !UNITY_EDITOR

public class CustomEditorSettings
{
    public static void Initialize()
    {
    }

    public static string GetString(string name, string defaultValue = "")
    {
        return defaultValue;
    }
}

#else

using System.Collections.Generic;
using System.IO;
using System.Xml;
using UnityEditor;
using UnityEngine;

public class CustomEditorSettings
{
    private const string FILE_PATH = "UserSettings/EditorBootSettings.xml";
    
    private static CustomEditorSettings s_Instance;

    public static void Initialize()
    {
        if (s_Instance == null) s_Instance = new CustomEditorSettings();
    }

    private Dictionary<string, string> m_Values;

    private CustomEditorSettings()
    {
        m_Values = new Dictionary<string, string>();

        if (!File.Exists(FILE_PATH)) return;

        XmlDocument xml = new XmlDocument();
        xml.Load(FILE_PATH);
        xmlNode root = root.SelectSingleNode("data");
        XmlNodeList items = root.SelectNodes("i");
        foreach (XmlNode item in items)
        {
            XmlElement element = (XmlElement)item;
            string key = element.GetAttribute("key");
            string value = element.GetAttribute("value");
            m_Values[key] = value;
        }
    }

    private void SaveData()
    {
        if (s_Instance == null) return;

        XmlDocument xml = new XmlDocument();
        XmlNode root = xml.CreateElement("data");
        xml.AppendChild(root);

        List<string> keys = new List<string>(s_Instance.m_Values.Keys);
        keys.Sort();
        foreach (string key in keys)
        {
            string value = s_Instance.m_Values[key];
            XmlElement element = xml.CreateElement("i");
            element.SetAttribute("key", key);
            root.AppendChild(element);
        }

        xml.Save(FILE_PATH);
    }

    public static string GetString(string name, string defaultValue = "")
    {
        if (s_Instance == null) Initialize();
        if (!s_Instance.m_Values.ContainsKey(name)) return defaultValue;
        return s_Instance.m_Values[name];
    }

    public static void SetString(string name, string value)
    {
        if (s_Instance == null) Initialize();
        s_Instance.m_Values[name] = value;
        s_Instance.SaveData();
    }

    // 注册自定义设置页面
    [SettingsProvider]
    private static SettingsProvider CreateProvider()
    {
        // 第二个参数决定显示在什么地方,如果是SettingsScope.Project, 就显示在Project Settings里面
        // 相应的,数据也需要存储在ProjectSettings文件夹里面
        // guiHandler表示使用IMGUI的展示函数, 官方也提供了UIElements版本的
        // 但是如果没有完整封装一套UIElements逻辑的话,写属性一类的编辑器UI还是用IMGUI更方便(基本不在乎效率)
    
        return new SettingsProvider("CustomEditorSettings", SettingsScope.User)
        {
            label = "自定义配置",
            guiHandler = OnProviderGUI,
        };
    }

    // 自定义页面的UI函数
    private static void OnProviderGUI(string _)
    {
        Initialize();

        List<string> keys = new List<string>(s_Instance.m_Values.Keys);
        foreach (string key in keys)
        {
            if (!s_Instance.m_Values.ContainsKey(key)) continue;

            string value = s_Instance.m_Values[key];
            EditorGUI.BeginChangeCheck();
            value = EditorGUILayout.TextField(key, value);
            if (EditorGUI.EndChangeCheck())
            {
                SetString(key, value);
            }
        }
    }
}

#endif

添加更多值类型、让UI更加人性化等内容不再赘述

posted @   lunoctis  阅读(854)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示