|
声明:
- 题图来自于unsplash.com
- 欢迎分享本文
- 本文未经允许不能以任何形式转载。
Unity有一个自带的Color拾色器面板,只有16进制(例如D5B1B1FF)显示,而32位显示(213, 177, 177, 255)的颜色值是分开四个输入框的,复制起来很不方便。可是我们项目开发时,使用的Color和Color32类却不能使用16进制,所以有时候拾取的颜色值要用到代码里需要大费周章。
所以今天要做一个颜色拾取器,用于同时显示16进制,归一化颜色值,32位颜色值
知识要点:
- EditorWindow
- EditorGUILayout.TextField
- EditorGUILayout.ColorField
- ColorUtility
使用版本:
目标:
- 继续深入学习EditorGUILayout类其他功能。
整个插件的结构:
像上一节教程一样,我们要先创建一个EditorWindow面板类。 怎么样创建Editor目录的内容就不再这多说,有疑惑可以看回前两章的教程内容。
public class ColorPickerWindow : EditorWindow
{
[MenuItem("Tools/ColorPicker")]
public static void ShowWindow()
{
//调用GetWindow创建一个面板
EditorWindow.GetWindow<ColorPickerWindow>(&#34;ColorPicker&#34;);
}
}
然后是在ColorPickerWindow内定义四个属性,用于记录四种颜色表示方式的数据。
/// <summary>
/// 16进制颜色
/// </summary>
private string _hexColor = &#34;FFFFFFFF&#34;;
/// <summary>
/// 归一化颜色值
/// </summary>
private string _normalColor = &#34;1f, 1f, 1f, 1f&#34;;
/// <summary>
/// 32位颜色值显示
/// </summary>
private string _color32 = &#34;255, 255, 255, 255&#34;;
/// <summary>
/// unity颜色值
/// </summary>
private Color _color = new Color(1, 1, 1, 1);
接下来就是定义OnGUI方法,并且写入我们绘制面板的代码。
string tempHexColor = EditorGUILayout.TextField(&#34;HexColor:&#34;, _hexColor);
string tempNormalColor = EditorGUILayout.TextField(&#34;NormalColor:&#34;, _normalColor);
string tempColor32 = EditorGUILayout.TextField(&#34;Color32:&#34;, _color32);
Color tempColorValue = EditorGUILayout.ColorField(_color);
这里重点说一下EditorGUILayout.TextField,因为它是比较常用的输入框组件,它显示的是字符串,返回的是用户输入的字符串结果。第一个参数为输入框的Label(可忽略),第二个参数是输入框显示的字符串内容。
接着是EditorGUILayout.ColorField,这是我们常用来显示颜色的Color组件,Color组件也可以显示Label,不过这里忽略掉,只使用第一个参数(Color类型)。
EditorGUILayout下的组件用法大致相同,而且基本都有几种重载方法。使用的时候,可以先看看方法的定义。如果有必要,可能会另外开一节课讲GUI的绘制原理。 上面我们把四个输入框组件绘制出来,并保存下来,为的是之后的转换。
if (tempHexColor != _hexColor)
{
_hexColor = tempHexColor;
_color = HexToColor(_hexColor);
UpdateColor();
this.Repaint();
}
else if (tempNormalColor != _normalColor)
{
_normalColor = tempNormalColor;
_color = NormalToColor(_normalColor);
UpdateColor();
this.Repaint();
}
else if (tempColor32 != _color32)
{
_color32 = tempColor32;
_color = Color32ToColor(_color32);
UpdateColor();
this.Repaint();
}
else if(tempColorValue != _color)
{
_color = tempColorValue;
UpdateColor();
this.Repaint();
}
这里分别对四个属性进行判断,然后分别调用相应的转换函数,把数值转换成Color类,然后再分别格式化显示各种数值,最后调用Repaint()方法刷新界面。
注意:这里要先判断是否修改的做法,第一,是提高效率。第二,Repaint()方法会触发一次OnGUI(),这样可以防止一直刷新OnGUI() 接下来分别添加转换方法。
/// <summary>
/// 16进制转Color类
/// </summary>
/// <param name=&#34;value&#34;></param>
/// <returns></returns>
private Color HexToColor(string value)
{
Color color;
value = value.Replace(&#34;0x&#34;, &#34;&#34;);
value = value.Replace(&#34;0X&#34;, &#34;&#34;);
if (value.IndexOf(&#34;#&#34;) != 0)
{
value = &#34;#&#34; + value;
}
ColorUtility.TryParseHtmlString(value, out color);
return color;
}首先是16进制转Color,16进制颜色通常会使用“0xFFFFFFFF”、“#FFFFFFFF”、“FFFFFFFF”。由于后面用到ColorUtility.TryParseHtmlString方法要使用“#FFFFFFFF”样式,所以,先要把“0x”替换掉,然后加上“#”。
ColorUtility是Editor的颜色工具类,这里的TryParseHtmlString方法能把16进制字符串转换成Color类。很方便使用。
由于第二个参数是out,所以要加上out关键字,把color的引用传入方法。 /// <summary>
/// 归一化转Color
/// </summary>
/// <param name=&#34;value&#34;></param>
/// <returns></returns>
private Color NormalToColor(string value)
{
Color color = new Color();
value = value.Replace(&#34; &#34;,&#34;&#34;);
value = value.Replace(&#34;f&#34;, &#34;&#34;);
string[] values = value.Split(&#39;,&#39;);
float[] numbers = new float[4];
for (int i = 0; i < 4; i++)
{
if (i < values.Length)
{
float.TryParse(values, out numbers);
numbers = Mathf.Clamp(numbers, 0.0f, 1.0f);
}
else
{
numbers = 1.0f;
}
}
color.r = numbers[0];
color.g = numbers[1];
color.b = numbers[2];
color.a = numbers[3];
return color;
}
归一化颜色值(0f-1f)我们可能并不少见,在着色器shader编写上就有用到。这里的显示我们会在数字后面加上“f”,以便我们能直接复制到代码里面使用。
当然,转换的时候要把空格和“f”替换掉,然后进行分割字符,再使用float.TryParse把字符串转变成float类型。这里还要使用Mathf.Clamp方法对数值进行一个限制,限制到0f-1f之间。
/// <summary>
/// Color32转Color
/// </summary>
/// <param name=&#34;value&#34;></param>
/// <returns></returns>
private Color Color32ToColor(string value)
{
Color32 color = new Color32();
value = value.Replace(&#34; &#34;, &#34;&#34;);
string[] values = value.Split(&#39;,&#39;);
byte[] numbers = new byte[4];
for (int i = 0; i < 4; i++)
{
if (i < values.Length)
{
byte.TryParse(values, out numbers);
}
else
{
numbers = 255;
}
}
color.r = numbers[0];
color.g = numbers[1];
color.b = numbers[2];
color.a = numbers[3];
return color;
}
Color32ToColor和NormalToColor方法差不多,只是把float变成了byte
/// <summary>
/// 更新颜色值
/// 把color转成各种颜色表示方式
/// </summary>
private void UpdateColor()
{
_hexColor = ColorUtility.ToHtmlStringRGBA(_color);
_normalColor = string.Format(&#34;{0}f, {1}f, {2}f, {3}f&#34;, _color.r, _color.g, _color.b, _color.a);
Color32 color32 = _color;
_color32 = string.Format(&#34;{0}, {1}, {2}, {3}&#34;, color32.r, color32.g, color32.b, color32.a);
}最后,我们使用UpdateColor把Color格式化一遍,变成各种字符串,这就大功告成了。ColorUtility.ToHtmlStringRGBA方法可以直接把Color转成16进制颜色,很方便。
最后,你就可以用它看看效果了。
源码:L-Lawliet/UnityEditorTutorial
==========================分割线==========================
如果大家有什么意见和建议,或者是有什么疑问,或者是有想看的知识点内容,都欢迎到评论区发上你们的评论。
最后我希望有更多人参与到插件开发的队伍里。也欢迎大家投稿。
QQ群:234204968 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|