自定义ProjectSettings设置项

基于ScriptableObject资源和SettingsProvider特性方式实现

1.实现ScriptableObject数据设计


/// <summary>
/// 用于存储我们的设置配置
/// </summary>
public class EditorLearnSettings : ScriptableObject
{
    /// <summary>
    /// 用于我们设置的保存位置
    /// </summary>
    private const string SettingsFile= "Assets/Settings/EditorLearnSetting.asset";

    #region 此处可以存储我们自定义的配置信息
    /// <summary>
    /// 模拟我们的配置
    /// </summary>
    public int m_ConfigVersionCode = 1;
    #endregion
}

2.提供配置文件内容的全局实例方法 

在我们的EditorLearnSettings类提供以下方法,为我们提供全局配置信息。

    /// <summary>
    /// 这里提供一个配置对象
    /// </summary>
    /// <returns></returns>
    public static EditorLearnSettings GetOrCreateSettings()
    {
        var settings = AssetDatabase.LoadAssetAtPath<EditorLearnSettings>(SettingsFile);
        if (settings == null)
        {
            settings = ScriptableObject.CreateInstance<EditorLearnSettings>();
            settings.m_ConfigVersionCode = 0;
            if (!Directory.Exists(Path.GetDirectoryName(SettingsFile)))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(SettingsFile));
            }
            AssetDatabase.CreateAsset(settings, SettingsFile);
            AssetDatabase.SaveAssets();
        }
        return settings;
    }

    /// <summary>
    /// 提供一个SerializedObject的对象
    /// </summary>
    /// <returns></returns>
    public static SerializedObject GetSerializedSettings()
    {
        return new SerializedObject(GetOrCreateSettings());
    }
  • 当资源配置被创建出来我们可以直接进行配置,如果不想通过资源配置文件配置,可以为其制定一个CustomEditor。
[CustomEditor(typeof(EditorLearnSettings))]
public class EditorLearnSettingsView:Editor
{
    protected override void OnHeaderGUI()
    {
        GUILayout.Label("请从Project Settings配置");
    }
    public override void OnInspectorGUI() { }
}

3.编写一个提供SettingsProvider数据的静态方法。

我们继续在EditorLearnSettings类提供以下方法。

    /// <summary>
    /// 这里主要是制定我们的Settings路径
    /// </summary>
    private const string ProjectSettingPtah = "Project/编辑器学习";

    /// <summary>
    /// 将我们的Setting提供给Unity
    /// </summary>
    /// <returns></returns>
    [SettingsProvider]
    public static SettingsProvider CreateEditorLearnSettingsProvider()
    {
        ///创建一个SettingsProvider
        var provider = new SettingsProvider(ProjectSettingPtah, SettingsScope.Project)
        {
            guiHandler = (searchContext) =>
            {
                ///searchContext:提供用户搜索的信息
                ///这里是一个gui的处理行为
                var settings = EditorLearnSettings.GetSerializedSettings();
                EditorGUILayout.PropertyField(settings.FindProperty("m_ConfigVersionCode"), new GUIContent("版本码:"));
                settings.ApplyModifiedPropertiesWithoutUndo();
            },

            // 用于搜索的关键字,在Project 可以搜索对应的配置
            keywords = new HashSet<string>(new[] { "Learn", "KTGame" })
        };

        return provider;
    }

 4.到此我们就可以在Project Setting看见我们自定义的配置模块了。

5.完整代码

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

[CustomEditor(typeof(EditorLearnSettings))]
public class EditorLearnSettingsView:Editor
{
    protected override void OnHeaderGUI()
    {
        GUILayout.Label("请从Project Settings配置");
    }
    public override void OnInspectorGUI() { }
}

/// <summary>
/// 用于存储我们的设置配置
/// </summary>
public class EditorLearnSettings : ScriptableObject
{
    /// <summary>
    /// 用于我们设置的保存位置
    /// </summary>
    private const string SettingsFile= "Assets/Settings/EditorLearnSetting.asset";

    #region 此处可以存储我们自定义的配置信息
    /// <summary>
    /// 模拟我们的配置
    /// </summary>
    public int m_ConfigVersionCode = 1;
    #endregion

    /// <summary>
    /// 这里提供一个全局的设置获取方式
    /// </summary>
    /// <returns></returns>
    public static EditorLearnSettings GetOrCreateSettings()
    {
        var settings = AssetDatabase.LoadAssetAtPath<EditorLearnSettings>(SettingsFile);
        if (settings == null)
        {
            settings = ScriptableObject.CreateInstance<EditorLearnSettings>();
            settings.m_ConfigVersionCode = 0;
            if (!Directory.Exists(Path.GetDirectoryName(SettingsFile)))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(SettingsFile));
            }
            AssetDatabase.CreateAsset(settings, SettingsFile);
            AssetDatabase.SaveAssets();
        }
        return settings;
    }

    /// <summary>
    /// 提供一个SerializedObject的获取
    /// </summary>
    /// <returns></returns>
    public static SerializedObject GetSerializedSettings()
    {
        return new SerializedObject(GetOrCreateSettings());
    }

    /// <summary>
    /// 这里主要是制定我们的Settings路径
    /// </summary>
    private const string ProjectSettingPtah = "Project/编辑器学习";

    /// <summary>
    /// 将我们的Setting提供给Unity
    /// </summary>
    /// <returns></returns>
    [SettingsProvider]
    public static SettingsProvider CreateEditorLearnSettingsProvider()
    {
        ///创建一个SettingsProvider
        var provider = new SettingsProvider(ProjectSettingPtah, SettingsScope.Project)
        {
            guiHandler = (searchContext) =>
            {
                ///searchContext:提供用户搜索的信息
                ///这里是一个gui的处理行为
                var settings = EditorLearnSettings.GetSerializedSettings();
                EditorGUILayout.PropertyField(settings.FindProperty("m_ConfigVersionCode"), new GUIContent("版本码:"));
                settings.ApplyModifiedPropertiesWithoutUndo();
            },

            // 用于搜索的关键字,在Project 可以搜索对应的配置
            keywords = new HashSet<string>(new[] { "Learn", "KTGame" })
        };

        return provider;
    }
}

基于继承SettingsProvider的实现方式。

1.同样需要一个配置文件。

配置文件我们直接使用上面的文件。

/// <summary>
/// 用于存储我们的设置配置
/// </summary>
public class EditorLearnSettings : ScriptableObject
{
    /// <summary>
    /// 用于我们设置的保存位置
    /// </summary>
    private const string SettingsFile= "Assets/Settings/EditorLearnSetting.asset";

    #region 此处可以存储我们自定义的配置信息
    /// <summary>
    /// 模拟我们的配置
    /// </summary>
    public int m_ConfigVersionCode = 1;
    #endregion

    /// <summary>
    /// 这里提供一个全局的设置获取方式
    /// </summary>
    /// <returns></returns>
    public static EditorLearnSettings GetOrCreateSettings()
    {
        var settings = AssetDatabase.LoadAssetAtPath<EditorLearnSettings>(SettingsFile);
        if (settings == null)
        {
            settings = ScriptableObject.CreateInstance<EditorLearnSettings>();
            settings.m_ConfigVersionCode = 0;
            if (!Directory.Exists(Path.GetDirectoryName(SettingsFile)))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(SettingsFile));
            }
            AssetDatabase.CreateAsset(settings, SettingsFile);
            AssetDatabase.SaveAssets();
        }
        return settings;
    }

    /// <summary>
    /// 提供一个SerializedObject的获取
    /// </summary>
    /// <returns></returns>
    public static SerializedObject GetSerializedSettings()
    {
        return new SerializedObject(GetOrCreateSettings());
    }
}

2.继承 SettingsProvider

首先我们创建EditorLearnSettingsProvider类并继承SettingsProvider

public class EditorLearnSettingsProvider: SettingsProvider{}

实现SettingsProvider构造函数。

public EditorLearnSettingsProvider(string path, SettingsScope scope) : base(path, scope) { }

重写OnGUI和OnActivate

    /// <summary>
    /// 当模块被激活时被调用
    /// </summary>
    /// <param name="searchContext">用户搜索的内容</param>
    /// <param name="rootElement">UIElements根节点。如果添加到此,则 SettingsProvider 使用 UIElements 而不是调用 SettingsProvider.OnGUI 来构建 UI。如果不添加到此 VisualElement,则必须使用 IMGUI 来构建 UI。</param>
    public override void OnActivate(string searchContext, VisualElement rootElement)
    {
        serializedObject = EditorLearnSettings.GetSerializedSettings();
    }

    public override void OnGUI(string searchContext)
    {
        EditorGUILayout.PropertyField(serializedObject.FindProperty("m_ConfigVersionCode"), new GUIContent("版本码:"));
    }

3.通过SettingsProvider方法特性注册到SettingsProvider中

    [SettingsProvider]
    public static SettingsProvider CreateMyCustomSettingsProvider()
    {
        var provider = new EditorLearnSettingsProvider(ProjectSettingPtah, SettingsScope.Project);
        provider.keywords = new[] { "Learn", "KTGame" };
        return provider;
    }

4.完整代码

using UnityEditor;
using UnityEngine;
using System.IO;
using UnityEngine.UIElements;

[CustomEditor(typeof(EditorLearnSettings))]
public class EditorLearnSettingsView:Editor
{
    protected override void OnHeaderGUI()
    {
        GUILayout.Label("请从Project Settings配置");
    }
    public override void OnInspectorGUI() { }
}

/// <summary>
/// 用于存储我们的设置配置
/// </summary>
public class EditorLearnSettings : ScriptableObject
{
    /// <summary>
    /// 用于我们设置的保存位置
    /// </summary>
    private const string SettingsFile= "Assets/Settings/EditorLearnSetting.asset";

    #region 此处可以存储我们自定义的配置信息
    /// <summary>
    /// 模拟我们的配置
    /// </summary>
    public int m_ConfigVersionCode = 1;
    #endregion

    /// <summary>
    /// 这里提供一个全局的设置获取方式
    /// </summary>
    /// <returns></returns>
    public static EditorLearnSettings GetOrCreateSettings()
    {
        var settings = AssetDatabase.LoadAssetAtPath<EditorLearnSettings>(SettingsFile);
        if (settings == null)
        {
            settings = ScriptableObject.CreateInstance<EditorLearnSettings>();
            settings.m_ConfigVersionCode = 0;
            if (!Directory.Exists(Path.GetDirectoryName(SettingsFile)))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(SettingsFile));
            }
            AssetDatabase.CreateAsset(settings, SettingsFile);
            AssetDatabase.SaveAssets();
        }
        return settings;
    }

    /// <summary>
    /// 提供一个SerializedObject的获取
    /// </summary>
    /// <returns></returns>
    public static SerializedObject GetSerializedSettings()
    {
        return new SerializedObject(GetOrCreateSettings());
    }
}

public class EditorLearnSettingsProvider: SettingsProvider
{
    private const string ProjectSettingPtah = "Project/编辑器学习";
    public EditorLearnSettingsProvider(string path, SettingsScope scope) : base(path, scope) { }

    private SerializedObject serializedObject;
    /// <summary>
    /// 当模块被激活时被调用
    /// </summary>
    /// <param name="searchContext">用户搜索的内容</param>
    /// <param name="rootElement">UIElements根节点。如果添加到此,则 SettingsProvider 使用 UIElements 而不是调用 SettingsProvider.OnGUI 来构建 UI。如果不添加到此 VisualElement,则必须使用 IMGUI 来构建 UI。</param>
    public override void OnActivate(string searchContext, VisualElement rootElement)
    {
        serializedObject = EditorLearnSettings.GetSerializedSettings();
    }

    public override void OnGUI(string searchContext)
    {
        EditorGUILayout.PropertyField(serializedObject.FindProperty("m_ConfigVersionCode"), new GUIContent("版本码:"));
    }

    [SettingsProvider]
    public static SettingsProvider CreateMyCustomSettingsProvider()
    {
        var provider = new EditorLearnSettingsProvider(ProjectSettingPtah, SettingsScope.Project);
        provider.keywords = new[] { "Learn", "KTGame" };
        return provider;
    }
}

总结

  • SettingsScope共有两项,User显示在Preferences 窗口;Project显示在Project Settings窗口。
  • 这里我们使用的是ScriptableObject方式对配置进行存储,我们也可以使用其它的方式存储在非工程里或者存在ProjectSettings文件夹里。
  • 我们存储的配置目标尽可能的保证全局的唯一性。
  • 关于Project Settings配置模块和Preferences 配置我们还是最好进行一个统一的管理。
  • AssetDatabase.CreateAsset创建资源时要保证路径有效。
  • 此主题所有代码都是编辑器代码应该放在Editor下。
  • 如果我们需要提交多个配置模块可以使用SettingsProviderGroup,你的方法应该提供一个SettingsProvider[]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
"Could not resolve dependencies for project" 是一个常见的 Maven 构建错误,它表示 Maven 无法解析目的依赖关系。这可能是由于以下几个原因导致的: 1. 依赖不存在或版本不匹配:检查目的 pom.xml 文件,确保所有依赖的坐标和版本号正确。如果依赖不存在或版本不匹配,Maven 将无法解析它们。 2. 仓库配置问题:Maven 默认从中央仓库下载依赖,但有时可能需要访问其他自定义或私有仓库。确保你的 Maven 配置文件(settings.xml)中包含正确的仓库配置,并且可以访问这些仓库。 3. 网络连接问题:如果你的网络连接存在问题,Maven 可能无法下载依赖。确保你的网络连接正常,并且可以访问所需的仓库。 4. 依赖冲突:如果目中存在多个依赖,它们之间可能存在冲突。这可能是由于不同的依赖引入了相同的类或资源文件。在这种情况下,你可以使用 Maven 的 dependency tree 命令来查看依赖树,并解决冲突。 解决此问题的一般步骤如下: 1. 检查并修复 pom.xml 文件中的依赖坐标和版本号。 2. 检查并修复 Maven 配置文件中的仓库配置。 3. 确保网络连接正常,并且可以访问所需的仓库。 4. 使用 Maven 的 dependency tree 命令来查看依赖树,并解决冲突。 如果你能提供更具体的错误信息或目配置,我可以给出更详细的帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值