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

版本:
Unity4.6.9

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

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

Unity 源码研究 获取颜色面板ColorPicker键值信息_第1张图片Unity 源码研究 获取颜色面板ColorPicker键值信息_第2张图片

假设你通过ColorPicker面板,缓存了颜色信息。根据你的存储形式选择,unity会在相应路径下保存*.color文件。文件里的序列化信息大概如下

%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &1
MonoBehaviour:
  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信息的读写接口。那么美术同学通过ColorPicker调整的调好颜色信息,就没法代码运行时使用了呀!!!!!!!

做个工具导出ColorPicker颜色对,能不能!!!

研究了一番UnityEditor.dll的源码。可以做到哇!以文本将贴出ColorPicker部分的源码,同时写个小程序打印所有*.color文件内的颜色对

UnityEditor.PresetLibraryLocations

需要通过其来*.color路径。我估计除了颜色库用后缀.color保存,曲线库(后缀.curves)等,都可以通过UnityEditor.PresetLibraryLocations存取。

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

UnityEditor.PresetFileLocation

颜色库存储方式枚举:

1. UnityEditor.PresetFileLocation.PreferencesFolder 
   全局路径(Preferences)。多个Unity项目间可以共享
2. UnityEditor.PresetFileLocation.ProjectFolder
   本地项目路径(Projects)。仅被当前Unity项目使用

以下是获取PreferencesFolder存储类型下的路径对象,该对象在后面的逻辑里会被UnityEditor.PresetLibraryLocations使用

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.ColorPresetLibrary

Unity Color面板的数据序列化管理类。颜色库里的每条记录,被定义为ColorPreset。ColorPresetLibrary存储多条ColorPreset记录
Unity 源码研究 获取颜色面板ColorPicker键值信息_第3张图片
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);
    }
}

/// 
/// 获得颜色库名称列表
/// 
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;
    }
}

/// 
/// 反序列path路径保存的颜色对
/// 
/// 
/// 
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);

    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;
}

/// 
/// 颜色转换为十六进制字符串
/// 
/// 
/// 
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;
}

/// 
/// 打印颜色对
/// 
/// 
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.colors
default_1:39793105
ColorPath = C:/Users/XXX/AppData/Roaming/Unity/Editor-4.x/Preferences/Presets/preferences.colors
preferences_1:314D7905
ColorPath = D:\XXX\Assets\Editor\project.colors
project_1:FFFFFFFF

你可能感兴趣的:(Unity3d)