Unity 反编译源码研究 获取颜色面板ColorPicker键值信息

来源:互联网 发布:知乎'' 编辑:程序博客网 时间:2024/05/16 09:26

版本:
Unity4.6.9

Unity ColorPicker可视化的颜色操作和Color库的管理、颜色别名定义、颜色序列化。为开发者带来的极大的方便。如果读者不了解Unity ColorPicker,可先转至官方文档https://docs.unity3d.com/Manual/PresetLibraries.html

Unity提供两种存储类型:
1. 全局路径(Preferences)。多个Unity项目间可以共享。具体目录C:/Users/XXX/AppData/Roaming/Unity/Editor-4.x/Preferences
2. 本地项目路径(Projects)。仅被当前Unity项目使用。具体目录Assets/Editor/

这里写图片描述这里写图片描述

保存的序列化信息%YAML 1.1%TAG !u! tag:unity3d.com,2011:--- !u!114 &1MonoBehaviour:  m_ObjectHideFlags: 4  m_PrefabParentObject: {fileID: 0}  m_PrefabInternal: {fileID: 0}  m_GameObject: {fileID: 0}  m_Enabled: 1  m_EditorHideFlags: 1  m_Script: {fileID: 12323, guid: 0000000000000000e000000000000000, type: 0}  m_Name:  m_EditorClassIdentifier:  m_Presets:  - m_Name: 1    m_Color: {r: 0, g: 0, b: 0, a: 0}  - m_Name: 2    m_Color: {r: .897058845, g: .098940298, b: .098940298, a: 0}  - m_Name: 3    m_Color: {r: .098940298, g: .897058845, b: .335623711, a: 0}  - m_Name: 4    m_Color: {r: .841121376, g: .963235319, b: .0779087543, a: 0}

笔者在此先给出结论:Unity RunTime,不提供ColorPicker信息的读写接口。
但是我们需要“玩家血量越低时,血条颜色越红”,所以希望能代码运行时,获得美术同学定义的颜色码,设置给“血条”UI。

笔者将在下文介绍,UnityEditor.dll相关的ColorPicker读取操作

UnityEditor.PresetFileLocation

颜色库存储方式枚举:

1. UnityEditor.PresetFileLocation.PreferencesFolder    全局路径(Preferences)。多个Unity项目间可以共享2. UnityEditor.PresetFileLocation.ProjectFolder   本地项目路径(Projects)。仅被当前Unity项目使用
Type enumPresetLocation = System.Type.GetType("UnityEditor.PresetFileLocation,UnityEditor");System.Object parmPreferenceLocation = Enum.Parse(enumPresetLocation, "PreferencesFolder");List<string> preferenceColorList =System.Object parmProjectLocation = Enum.Parse(enumPresetLocation, "ProjectFolder");

UnityEditor.PresetLibraryLocations

除了颜色库用后缀.color保存,还曲线库用后缀.curves等,感觉都通过UnityEditor.PresetLibraryLocations存取。

Type typeClassPresetLocaton = System.Type.GetType("UnityEditor.PresetLibraryLocations,UnityEditor");MethodInfo _GetAvailableFilesWithExtensionOnTheHDDFunc = typeClassPresetLocaton.GetMethod("GetAvailableFilesWithExtensionOnTheHDD");

UnityEditor.ColorPresetLibrary

Unity Color面板的数据序列化管理类。颜色库里的每条记录,被定义为ColorPreset。ColorPresetLibrary存储多条ColorPreset记录
这里写图片描述
ColorPrsetLibrary几个重要的反射方法

System.Type typeColorPresetLibrary = System.Type.GetType("UnityEditor.ColorPresetLibrary,UnityEditor");System.Reflection.MethodInfo _CountFunc = typeColorPresetLibrary.GetMethod("Count");System.Reflection.MethodInfo _GetNameFunc = typeColorPresetLibrary.GetMethod("GetName");System.Reflection.MethodInfo _GetPresetFunc = typeColorPresetLibrary.GetMethod("GetPreset");

我们不能直接new ColorPresetLibrary,Unity有其对应的实例方法,向UnityEditorInternal.InternalEditorUtility.LoadSerializedFileAndForget传入加载路径即可获取

string colorPath = "";System.Object instanceArray=UnityEditorInternal.InternalEditorUtility.LoadSerializedFileAndForget(colorPath );System.Object colorLibIntance = instanceArray [0];int count = (int)_CountFunc.Invoke(obj, null)string name = (string)_GetNameFunc.Invoke(colorLibIntance , new System.Object[]);Color col = (Color)_GetPresetFunc.Invoke(colorLibIntance , new System.Object[])

Demo获取本机上所有颜色库,并打印颜色对

private static void Test(){    List<string> paths = ColorPresetPaths;    for (int i = 0, iMax = paths.Count; i < iMax; ++i)    {        string colorPath = paths[i];        Debug.Log("ColorPath = " + colorPath);        List<string> pairs = GetColorPairs(colorPath);        Print(pairs);    }}/// <summary>/// 获得颜色库名称列表/// </summary>private static List<string> ColorPresetPaths{    get    {        Type typeClassPresetLocaton = System.Type.GetType("UnityEditor.PresetLibraryLocations,UnityEditor");        MethodInfo _GetAvailableFilesWithExtensionOnTheHDDFunc = typeClassPresetLocaton.GetMethod("GetAvailableFilesWithExtensionOnTheHDD");        Type enumPresetLocation = System.Type.GetType("UnityEditor.PresetFileLocation,UnityEditor");        // 全局路径。多个Unity项目间可以共享        System.Object parmPreferenceLocation = Enum.Parse(enumPresetLocation, "PreferencesFolder");        List<string> preferenceColorList = (List<string>)_GetAvailableFilesWithExtensionOnTheHDDFunc.Invoke(null, new System.Object[2] { parmPreferenceLocation, "colors" });        // 本地项目路径。仅被当前Unity项目使用。        System.Object parmProjectLocation = Enum.Parse(enumPresetLocation, "ProjectFolder");        List<string> projectColorList = (List<string>)_GetAvailableFilesWithExtensionOnTheHDDFunc.Invoke(null, new System.Object[2] { parmProjectLocation, "colors" });        // 收集所有颜色库文件路径        List<string> colorLibs = new List<string>();        for (int i = 0, iMax = preferenceColorList.Count; i < iMax; ++i)            colorLibs.Add(preferenceColorList[i]);        for (int i = 0, iMax = projectColorList.Count; i < iMax; ++i)            colorLibs.Add(System.IO.Path.GetFullPath(projectColorList[i]));        return colorLibs;        // 生成颜色选择列表        List<string> fileNames = new List<string>(colorLibs);        for (int i = 0, iMax = fileNames.Count; i < iMax; ++i)            fileNames[i] = System.IO.Path.GetFileNameWithoutExtension(fileNames[i]);        return fileNames;    }}/// <summary>/// 反序列path路径保存的颜色对/// </summary>/// <param name="path"></param>/// <returns></returns>private static List<string> GetColorPairs(string path){    List<string> pairs = new List<string>();    if (string.IsNullOrEmpty(path))        return pairs;    System.Type typeColorPresetLibrary = System.Type.GetType("UnityEditor.ColorPresetLibrary,UnityEditor");    System.Reflection.MethodInfo _CountFunc = typeColorPresetLibrary.GetMethod("Count");    System.Reflection.MethodInfo _GetNameFunc = typeColorPresetLibrary.GetMethod("GetName");    System.Reflection.MethodInfo _GetPresetFunc = typeColorPresetLibrary.GetMethod("GetPreset");    System.Object[] instanceArray = UnityEditorInternal.InternalEditorUtility.LoadSerializedFileAndForget(path);    System.Object colorLibIntance = instanceArray[0];    int count = (int)_CountFunc.Invoke(colorLibIntance, null);    for (int i = 0; i < count; ++i)    {        string name = (string)_GetNameFunc.Invoke(colorLibIntance, new System.Object[1] { i });        Color col = (Color)_GetPresetFunc.Invoke(colorLibIntance, new System.Object[1] { i });        string hexStr = ColorToHexString(col);        string val = string.Format("{0}:{1}", name, hexStr);        pairs.Add(val);    }    return pairs;}/// <summary>/// 颜色转换为十六进制字符串/// </summary>/// <param name="c"></param>/// <returns></returns>public static string ColorToHexString(Color c){    string ret = "";    ret += Mathf.RoundToInt(c.r * 255f).ToString("X2");    ret += Mathf.RoundToInt(c.g * 255f).ToString("X2");    ret += Mathf.RoundToInt(c.b * 255f).ToString("X2");    ret += Mathf.RoundToInt(c.a * 255f).ToString("X2");    return ret;}/// <summary>/// 打印颜色对/// </summary>/// <param name="pairs"></param>private static void Print(List<string> pairs){    string temp = "";    for (int i = 0, iMax = pairs.Count; i < iMax; ++i)    {        temp += pairs[i] + "\n";    }    Debug.Log(temp);}输出如下:ColorPath = C:/Users/XXX/AppData/Roaming/Unity/Editor-4.x/Preferences/Presets/Default.colorsdefault_1:39793105ColorPath = C:/Users/XXX/AppData/Roaming/Unity/Editor-4.x/Preferences/Presets/preferences.colorspreferences_1:314D7905ColorPath = D:\XXX\Assets\Editor\project.colorsproject_1:FFFFFFFF