SRPG游戏开发(十四)第五章 颜色映射与职业动画 - 六 颜色组编辑器(EditorWindow)
2018-02-06 02:35
561 查看
返回目录
第五章 颜色映射与职业动画
六 颜色组编辑器(EditorWindow)
每次导入进素材还要把颜色一个一个的输入进去,是不是很麻烦?这一节我们来解决这个问题,更方便的编辑我们的颜色组。1 自动填充贴图颜色(ColorChartEditor.cs)
首先,创建ColorChartEditor.cs:using UnityEditor; using UnityEngine; namespace DR.Book.SRPG_Dev.ColorPalette { [CanEditMultipleObjects] [CustomEditor(typeof(ColorChart))] public class ColorChartEditor : Editor { public ColorChart chart { get { return target as ColorChart; } } public override void OnInspectorGUI() { DrawDefaultInspector(); // TODO 自动填充贴图颜色 } } }
4000
同样的,我们并不需要自定义Inspector面板,而只是需要一个自动获取贴图颜色的方法。
其次,要获取贴图的颜色,首先得先获取贴图。我们用一个按钮,来获取贴图并获取颜色:
if (GUILayout.Button("Load Colors From Texture")) { string path = EditorUtility.OpenFilePanelWithFilters("Create Chart", "Assets", new string[] { "PNG Image", "png", "JPG Image", "jpg", "GIF Image", "gif" }); if (!string.IsNullOrEmpty(path) && path.Contains(Application.dataPath)) { path = path.Replace(Application.dataPath, "Assets"); Texture2D texture = AssetDatabase.LoadAssetAtPath<Texture2D>(path); // TODO 获取贴图颜色 } }
最后,我们在ColorChart.cs中完成获取贴图颜色的方法,Texture需要设置成可读:
/// <summary> /// 从Texture中读取颜色 /// </summary> /// <param name="chart"></param> /// <param name="texture"></param> /// <returns></returns> public static bool LoadColorsFromTexture(ColorChart chart, Texture2D texture) { if (chart == null || texture == null) { return false; } Color[] colors = texture.GetPixels(); List<Color> list = new List<Color>(); for (int i = 0; i < colors.Length; i++) { if (colors[i].a != 0 && !list.Contains(colors[i])) { list.Add(colors[i]); } } chart.m_Colors = list.ToArray(); return true; }
调用此方法来填充颜色:
if (GUILayout.Button("Load Colors From Texture")) { string path = EditorUtility.OpenFilePanelWithFilters("Create Chart", "Assets", new string[] { "PNG Image", "png", "JPG Image", "jpg", "GIF Image", "gif" }); if (!string.IsNullOrEmpty(path) && path.Contains(Application.dataPath)) { path = path.Replace(Application.dataPath, "Assets"); Texture2D texture = AssetDatabase.LoadAssetAtPath<Texture2D>(path); ColorChart.LoadColorsFromTexture(chart, texture); } }
是不是简单多了?只要Texture可读,选择此选项立刻填充颜色。
2 动态读取Texture2D颜色的坑
读取Texture2D的方法有很多,可以使用Resources,AssetBundle,WWW,System.IO等方法读取,在Editor中还可以用AssetDatabase读取。但这其中有一个问题。在用WWW与System.IO读取一部分PNG(我只测试了PNG)的Texture2D时,颜色可能会严重失真,获取的颜色和实际颜色相差非常大,测试了一下,和原始颜色RGB(255)数值都有相差10到20不等。而其他方式读取的没有问题。
出现这个的原因,经过测试,是PNG文件的问题,PNG文件也分多种。本人用Photoshop测试结果:
另存为PNG,没有问题,容量较大;
快速导出,层导出与导出PNG,颜色失真,容量较小;
使用旧版导出PNG,颜色失真,容量较小。
可以看出,另存为时保存了一些额外信息,这些信息和颜色有关(你用PS打开这些PNG时,你可以看到,普通PNG是“RGB颜色”模式,而那些较小的文件是“索引颜色”模式,所以额外容量至少有RGB颜色信息)。
图 5 - 12 PNG在PS中的模式
所以如果你使用WWW和System.IO读取文件后,如果要放到ColorChart中,要注意文件是否正确。
你可能会问Unity其它方式读取它为什么没有问题,这是因为Unity在内部帮我们保存了文件的一些额外信息,例如.meta文件就是一个例子。
由于我对图像学不是很了解,只能尽量不使用WWW与System.IO直接读取Texture2D,而实际项目中也基本很难遇到,多数都是用AssetBundle。发现这个坑的原因是,WWW与System.IO读取的文件无论Unity中设置如何,都可以读写(毕竟是流),所以使用它们读取了文件,结果就中坑了,不过也因此学到了一些东西。
3 颜色组编辑器(ColorChartEditorWindow.cs)
我们要在一个窗口中编辑颜色组的颜色,所以新建Editor窗口类ColorChartEditorWindow.cs。using UnityEditor; using UnityEngine; namespace DR.Book.SRPG_Dev.ColorPalette { public class ColorChartEditorWindow : EditorWindow { [MenuItem("Window/SRPG/Color Chart")] public static ColorChartEditorWindow OpenColorChartEditorWindow() { ColorChartEditorWindow window = EditorWindow.GetWindow<ColorChartEditorWindow>(false, "Color Chart"); window.Show(); return window; } } }
在窗口中,我们需要对比源颜色和转换颜色,来更好的辅助我们编辑颜色。所以他还需要两个ColorChart;而且因为颜色数量可能很多,需要ScrollView滚动条来控制;绘制Window是在OnGUI()的Callback里面,添加它们。
private ColorChart m_SrcChart; private ColorChart m_SwapChart; private Vector2 m_Scroll = Vector2.zero; public ColorChart src { get { return m_SrcChart; } set { m_SrcChart = value; } } public ColorChart swap { get { return m_SwapChart; } set { m_SwapChart = value; } } private void OnGUI() { // TODO 绘制GUI }
首先,要绘制GUI,首先我们需要两个ColorChart,必须保证它们都同时存在:
// 设置src与swap src = EditorGUILayout.ObjectField("Source Chart", src, typeof(ColorChart), false) as ColorChart; swap = EditorGUILayout.ObjectField("Swap Chart", swap, typeof(ColorChart), false) as ColorChart; if (src == null || swap == null) { EditorGUILayout.HelpBox("Please select source chart and swap chart.", MessageType.Info); return; }
其次,要能设置它们的颜色数量,且Swap Chart的颜色数量要和Source Chart的颜色数量相等:
// 设置Color的数量 EditorGUI.BeginChangeCheck(); int count = Mathf.Max(0, EditorGUILayout.DelayedIntField("Color Count", src.count)); if (EditorGUI.EndChangeCheck() && src.count != count) { src.count = count; EditorUtility.SetDirty(src); } if (swap.count != src.count) { int swapCount = swap.count; swap.count = src.count; if (swapCount < src.count) { ColorChart.CopyColors(src, swapCount, swap, swapCount, src.count - swapCount); } EditorUtility.SetDirty(swap); }
在这之中,如果Swap Chart的颜色数量小于Source Chart的颜色数量的话,是需要保留原来的颜色,并且新增颜色和Source Chart对应颜色相同,这样更便于我们编辑,打开ColorChart.cs添加方法CopyColors。
/// <summary> /// 复制颜色 /// </summary> /// <param name="src"></param> /// <param name="srcIndex"></param> /// <param name="dst"></param> /// <param name="dstIndex"></param> /// <param name="length"></param> public static void CopyColors(ColorChart src, int srcIndex, ColorChart dst, int dstIndex, int length) { Array.Copy(src.m_Colors, srcIndex, dst.m_Colors, dstIndex, length); }
最后,来绘制我们的颜色:
// 设置颜色 EditorGUI.BeginChangeCheck(); m_Scroll = EditorGUILayout.BeginScrollView(m_Scroll, "box"); { EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelFiel a8a8 d("Index", GUILayout.MaxWidth(50)); EditorGUILayout.LabelField("Source Chart", GUILayout.MaxWidth(150)); EditorGUILayout.LabelField("Swap Chart", GUILayout.MaxWidth(150)); EditorGUILayout.EndHorizontal(); for (int i = 0; i < count; i++) { EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField(i.ToString(), GUILayout.MaxWidth(50)); src[i] = EditorGUILayout.ColorField(src[i], GUILayout.MaxWidth(150)); swap[i] = EditorGUILayout.ColorField(swap[i], GUILayout.MaxWidth(150)); EditorGUILayout.EndHorizontal(); } } EditorGUILayout.EndScrollView(); if (EditorGUI.EndChangeCheck()) { EditorUtility.SetDirty(src); EditorUtility.SetDirty(swap); }
这样我们就完成了编辑器。将Source Chart放入,然后想编辑哪个Swap Chart就把哪个拖入到Swap Chart中,就可以对比看了,来看看效果吧。
图 5 - 13 Color Chart Editor Window
相关文章推荐
- SRPG游戏开发(十三)第五章 颜色映射与职业动画 - 五 修正颜色转换器(Fix Color Swapper)
- SRPG游戏开发(十五)第五章 颜色映射与职业动画 - 七 减少Draw Call与使用Cache
- SRPG游戏开发(九)第五章 颜色映射与职业动画 - 一 颜色映射流程(Flow Chart)
- SRPG游戏开发(十)第五章 颜色映射与职业动画 - 二 颜色组(Color Chart)
- SRPG游戏开发(十一)第五章 颜色映射与职业动画 - 三 颜色转换器(Color Swapper)
- SRPG游戏开发(十二)第五章 颜色映射与职业动画 - 四 测试与创建Class Animator
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(三十五)地图编辑器的初步使用
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(三十四)地图编辑器诞生啦!
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(三十四)地图编辑器诞生啦!
- 十四 手游开发神器 cocos2d-x editor 之串联游戏流程
- 【Android2D游戏开发十四】(未完待续)手把手教你在SurfaceView中照样使用Android 动画—Tween Animation!
- 十四 手游开发神器 cocos2d-x editor 之串联游戏流程 推荐
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(三十四)地图编辑器诞生啦!
- 十四-2 手游开发神器 cocos2d-x editor 之串联游戏流程
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(十四) 精灵控件横空出世!①
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(十四) 精灵控件横空出世!①
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(十四) 精灵控件横空出世!①
- SRPG游戏开发(七)第三章 绘制地图 - 四 初步完善地图编辑器(Map Graph)
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(三十五)地图编辑器的初步使用
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(三十五)地图编辑器的初步使用