Unity如何将Color转换为C# KnownColor对应的颜色名称
Unity Color 转 KnownColor 获取颜色名称方案
需求背景
Unity 内置的静态颜色属性仅有8种(例如 Color.red),甚至未覆盖橙色这类常用色彩。虽然支持自定义任意RGB值的颜色,但业务开发中需要获取颜色对应的可读字符串名称(例如 Color.red 对应 "red" 或 "Red"),用于环形菜单颜色选择器的预览区域下方展示。
最初通过反射Unity内置Color类型的静态属性实现名称获取,代码如下:
private static String GetColorName(Color color, bool caps = false) { var colorProperty = typeof(Color).GetProperties(BindingFlags.Public | BindingFlags.Static).FirstOrDefault(p=> (Color)(p.GetValue(p, null)) == color); return (colorProperty != null) ? caps ? string.Concat(colorProperty.Name[0].ToString().ToUpper(), colorProperty.Name.Substring(1)) : colorProperty.Name : color.ToString(); }
该方案仅能识别Unity自带的8种内置颜色,覆盖度不足,期望改用C#自带的KnownColor颜色体系扩展支持的颜色范围,同时避免手动维护颜色-名称映射字典。
最终实现
实现逻辑拆为两步,首先初始化时一次性构建KnownColor到Unity Color的映射字典,过滤掉随系统主题变化的系统UI类颜色,仅保留固定名称的标准色彩:
using System.Drawing; using System.Linq; using System.Collections.Generic; using UnityEngine; public static class ColorNameMapper { public static Dictionary<string, Color> NamedColors = Enum.GetValues(typeof(KnownColor)) .OfType<KnownColor>() .Where(kc => !System.Drawing.Color.FromKnownColor(kc).IsSystemColor) .ToDictionary( kc => kc.ToString(), kc => { System.Drawing.Color sysColor = System.Drawing.Color.FromKnownColor(kc); return new Color(sysColor.R/255f, sysColor.G/255f, sysColor.B/255f, sysColor.A/255f); }); }
注意:Unity中使用
System.Drawing需要先在Player Settings中开启对应程序集的引用支持,否则会报类型找不到的错误。
之后通过匹配方法查找对应颜色名称,自动兼容Unity Color 0-1浮点范围和0-255整数范围的入参,支持严格Alpha匹配、大小写格式配置:
public static string GetColorName(Color color, bool strictAlphaMatch = false, bool outputLowerCase = false) { // 兼容0-255范围的Color入参,统一转换为Unity标准0-1范围 if(color.r > 1f || color.g > 1f || color.b > 1f || color.a > 1f){ color = new Color(color.r/255f, color.g/255f, color.b/255f, color.a/255f); } string matchedName = ColorNameMapper.NamedColors.FirstOrDefault(kv => Mathf.Approximately(kv.Value.r, color.r) && Mathf.Approximately(kv.Value.g, color.g) && Mathf.Approximately(kv.Value.b, color.b) && (!strictAlphaMatch || Mathf.Approximately(kv.Value.a, color.a)) ).Key; return outputLowerCase ? matchedName.ToLower() : matchedName; }
注意事项
- 字典仅需在程序初始化阶段构建一次即可,不要每次调用查找方法时重复生成,避免不必要的性能开销
- 非严格匹配模式默认忽略Alpha通道差异,适配绝大多数颜色选择器场景下不透明度不影响色彩语义的需求
- 浮点值比较使用
Mathf.Approximately替代直接等号判断,避免浮点精度误差导致匹配失败 - 若需要支持自定义别名(如中文颜色名),可以在字典初始化后追加自定义键值映射,不影响原有匹配逻辑
内容的提问来源于stack exchange,提问作者Spencer Cornwall
相关产品推荐
相关产品推荐

