ScriptableObject:创建并管理资源配置文件

在项目中常常涉及到需要保存一些数据。保存数据有很多种方法.unity本身提供的方法中,playerprefs只能存简单,数据量小的数据,局限性比较大。所以统一提供了一种资源配置文件的保存数据的方法,就是个ScriptableObject类。
一,创建

1)创建继承自个ScriptableObject

[序列化]
公共类YxSettings:ScriptableObject
{
    公开串

    公开枚举Configation
    {
        低,
        中间,
        高
    }

    公开的bool playSound;

    公共Configation配置;

}
2)指定路径。(后缀名为.asset)
internal const string settingPath =“资产/资源/设置/ YxSettings .asset”;
3 )判断对应文件路径是否存在。利用Directory.Exists判断目录是否存在。利用File.Exists判断文件是否存在。
4 )调用创建接口  。AssetDatabase.CreateAsset
关于创建过程,网上文章有很多,不作过多描述。
二,管理
为了开发的效率,我们不可能每创建一个文件,就要改一次代码。所以我们利用编辑器去处理我们的创建过程。
我的想法是,每当需要创建配置文件,我只要新建好一个CS文件,继承自个ScriptableObject,那么我就可以利用编辑器一步创建出来所需文件代码文件如下:
BaseSetting基类:所有配置文件脚本的基类,继承自个ScriptableObject方便扩展。
[序列化]
公共类BaseSetting:ScriptableObject
{
    /// <summary>
    /// 保存存档。
    /// </ summary>
    public void Save()
    {
        EditorUtility.SetDirty(本);
    }
}

SettingCollection静态类:所有配置文件的存储每添加一份配置文件,需要在静态构造函数添加对应类。

静态类SettingCollection
{
    public static List <BaseSetting> baseSettingCollection = new List <BaseSetting>();

    static SettingCollection()
    {
        添加<YxSettings>();
    }

    static void添加<T>()其中T:BaseSetting
    {
        T t = ScriptableObject.CreateInstance <T>();
        baseSettingCollection.Add(T);
    }
}

YxSettingFileManager类,管理类,负责管理对配置文件的相关操作。

/// <summary>
///设置文件的管理
/// </ summary>
public static class YxSettingFileManager
{
    internal const string settingPath =“Assets / Resources / Settings / {0} .asset”;

    public static bool isCreating {get; 组; }

    public static SettingFileResult Creat(string fileName)
    {
        isCreating = true;

        //文件路径
        var realPath = PathName(fileName);

        //目录路径
        var path = Path.GetDirectoryName(realPath);

        //对应目录是否存在
        if(!Directory.Exists(path))
        {
            Directory.CreateDirectory(路径);
            AssetDatabase.ImportAsset(路径);
        }

        //从配置文件列表中取出对应类
        BaseSetting fileObj = Get(fileName);

        if(fileObj == null)
            返回SettingFileResult.ERROR;

        //对应文件是否存在
        if(File.Exists(realPath))
            返回SettingFileResult.ALREADYHAVE;

        //创建
        AssetDatabase.CreateAsset(fileObj,realPath);
        返回SettingFileResult.SUCCESS;
    }

    静态字符串PathName(string fileName)
    {
        return string.Format(settingPath,fileName);
    }

    /// <summary>
    ///通过配置文件名获取对应类
    /// </ summary>
    public static BaseSetting Get(string settingName)
    {
        var mList = SettingCollection.baseSettingCollection;
        for(int i = 0; i <mList.Count; ++ i)
        {
            if(string.CompareOrdinal(mList [i] .GetType()。Name,settingName)== 0)
                返回mList [i];
        }
        返回null;
    }

    /// <summary>
    ///获取配置文件类名集合
    /// </ summary>
    public static List <string> Keys()
    {
        返回SettingCollection.baseSettingCollection.ConvertAll <string>(m => m.GetType()。Name);
    }

    public static BaseSetting LoadAsset <T>()其中T:BaseSetting
    {
       返回AssetDatabase.LoadAssetAtPath <T>(PathName(typeof(T).Name));
    }
}

下面为编辑器界面:

我的目的是,展示所有我已创建好的配置文件名称,当我点击科瑞按钮时,如果没有创建,那么就在对应目录下创建所需文件;如果已存在,那么我就给出提示,告知已经存在该文件。其实可以整更复杂,更好一些的编辑器出来。然而……我犯懒了0.0
(其实应该说= =,研究这个东西的大部分时间都在写编辑器脚本上= =)
编辑器代码:
公共类YxSettingsEditor
{
    [MenuItem(“设置文件/创建”)]
    static void Creat()
    {
        SettingSelector settingSelector = ScriptableWizard.DisplayWizard <SettingSelector>(“Choose Settings”);
    }
}

public class SettingSelector:ScriptableWizard
{
    string mStr =“”;
    Vector2 mScrollPosition;

    private void OnGUI()
    {
        var keys = YxSettingFileManager.Keys();
        GUILayout.Label(“创意设置”,“TL选择H2”);
        DrawSeparator();
        EditorGUILayout.BeginHorizo​​ntal();
        GUILayout.Space(84F);
        string before = mStr;
        GUI.SetNextControlName( “SearchTextField”);
        string after = EditorGUILayout.TextField(“”,before,“SearchTextField”);
        if(after!= before)mStr = after;

        if(GUILayout.Button(“”,“SearchCancelButton”,GUILayout.Width(18f)))
        {
            mStr =“”;
            GUIUtility.keyboardControl = 0;
        }

        if(Event.current.Equals(Event.KeyboardEvent(“return”)))
        {
            if(GUI.GetNameOfFocusedControl()!=“SearchTextField”)
                GUI.FocusControl( “SearchTextField”);
        }

        GUILayout.Space(84F);
        EditorGUILayout.EndHorizo​​ntal();

        mScrollPosition = EditorGUILayout.BeginScrollView(mScrollPosition);

        string [] filters = mStr.Split(new char [] {'},StringSplitOptions.RemoveEmptyEntries);
        for(int i = 0; i <keys.Count; ++ i)
        {
            bool isMatch = true;
            for(int j = 0; j <filters.Length; ++ j)
            {
                if(keys [i] .IndexOf(filters [j],StringComparison.OrdinalIgnoreCase)== -1)
                {
                    isMatch = false;
                    打破;
                }                
            }

            如果(!isMatch)
                继续;

            EditorGUILayout.BeginHorizo​​ntal();
            bool select = GUILayout.Button(keys [i],EditorStyles.textField);
            选择| = GUILayout.Button(“Creat”,GUILayout.Width(120f));
            if(select &&!YxSettingFileManager.isCreating)
            {
                SettingFileResult result = YxSettingFileManager.Creat(keys [i]);
                开关(结果)
                {
                    案例SettingFileResult.ALREADYHAVE:
                        EditorUtility.DisplayDialog(“ALREADY HAVE”,string.Format(“已创建名称为{0}的设置文件”,键[i]),“OK”);
                        打破;
                    案例SettingFileResult.SUCCESS:
                        关();
                        打破;
                    默认:
                        打破;
                }
            }

            if(YxSettingFileManager.isCreating)
                YxSettingFileManager.isCreating = false;
            EditorGUILayout.EndHorizo​​ntal();
        }

        EditorGUILayout.EndScrollView();
    }


    //使用NGUI编辑器。
    private void DrawSeparator()
    {
        GUILayout.Space(12F);

        if(Event.current.type == EventType.Repaint)
        {
            Texture2D tex = EditorGUIUtility.whiteTexture;
            Rect rect = GUILayoutUtility.GetLastRect();
            GUI.color = new Color(0f,0f,0f,0.25f);
            GUI.DrawTexture(new Rect(0f,rect.yMin + 6f,Screen.width,4f),tex);
            GUI.DrawTexture(new Rect(0f,rect.yMin + 6f,Screen.width,1f),tex);
            GUI.DrawTexture(new Rect(0f,rect.yMin + 9f,Screen.width,1f),tex);
            GUI.color = Color.white;
        }
    }
}

三,存取

配置文件配置好以后,就可以根据定义的变量在检查器面板配置数据了。并且编辑器关闭配置的变量也不会改变。运行状态下也是不会改变的。而当我们使用它的时候,需要在初始化时调用接口:
AssetDatabase.LoadAssetAtPath <T>(string assetPath);

去读取配置文件。

如果在运行中需要改变配置文件的值,那么必须调用EditorUtility.SetDirty。
(在ScriptableObject中也有SetDirty接口,已过时。)