プログラマーであれば色指定は RGB だ、それ以外は許さん、という RGB 信者は多いでしょう。
ではこの動画のような 12 色が必要になった時、RGB ですぐに作れるでしょうか?
これが unity 純正カラーパレット。
RGB のスライダーを動かしてチャッチャと作成できる人は、まずいないでしょう。
普通はその上の円から色を選び、■の部分で明るさや鮮やかさを選ぶんじゃないでしょうか。
これが HSV です。
Hue .. 色相(どんな色か) 0~360
Satuation .. 彩度(色の鮮やかさ) 0~100
Value .. 明度(色の明るさ) 0~100
HSB という言い方をすることもありますが、HSV と同じです。
HSL というものについては HSV と異なります。ここでは紹介しません。
この unity が提供してくれた優秀なカラーパレットを使って HSV を変更し色を作成、RGB 値をプログラムに入れる。
これで 12 色ならなんとかなりそうです。
では、こんなのはどうでしょう。
このような、動的な虹色変化は RGB だと作り出すのが困難です。
HSV であれば、H の値をスライドしていくだけでこういう色変化が作れます。
ColorEx.cs
というわけで本題。HSV ←→RGB に変換するクラスです。
using UnityEngine; public class ColorEx { /// <summary> /// HSV を RGB に変換する /// </summary> /// <param name="h">0-359</param> /// <param name="s">0-100</param> /// <param name="v">0-100</param> /// <returns>RGB(0~1) エラーの場合、全て 0</returns> public static (float R, float G, float B) HSVtoRGB(float h, float s, float v) { if (h < 0.0f || h >= 360.0f) { Debug.LogError($"[H] out of range] {h}"); return (0, 0, 0); } if (s < 0.0f || s > 100.0f) { Debug.LogError($"[S] out of range] {s}"); return (0, 0, 0); } if (v < 0.0f || v > 100.0f) { Debug.LogError($"[V] out of range] {v}"); return (0, 0, 0); } float hmax = v; float hmin = hmax - ((s / 255) * hmax); float r = 0; float g = 0; float b = 0; s = s / 100.0f; v = v / 100.0f; if (s == 0) { r = v; g = v; b = v; } else { float dh = Mathf.Floor(h / 60.0f); float p = v * (1 - s); float q = v * (1 - s * (h / 60.0f - dh)); float t = v * (1 - s * (1 - (h / 60.0f - dh))); switch (dh) { case 0 : r = v; g = t; b = p; break; case 1 : r = q; g = v; b = p; break; case 2 : r = p; g = v; b = t; break; case 3 : r = p; g = q; b = v; break; case 4 : r = t; g = p; b = v; break; default : r = v; g = p; b = q; break; } } return (r, g, b); } /// <summary> /// RGB を HSV に変換する /// </summary> /// <param name="r"></param> /// <param name="g"></param> /// <param name="b"></param> /// <returns>H(0-359), S(0-100), V(0-100) エラーの場合、全て 0</returns> public static (int H, int S, int V) RGBtoHSV(float r, float g, float b) { if (r < 0.0f || r > 1.0f) { Debug.LogError($"[R] out of range] {r}"); return (0, 0, 0); } if (g < 0.0f || g > 1.0f) { Debug.LogError($"[G] out of range] {g}"); return (0, 0, 0); } if (b < 0.0f || b > 1.0f) { Debug.LogError($"[B] out of range] {b}"); return (0, 0, 0); } float max = Mathf.Max(r, g, b); float min = Mathf.Min(r, g, b); float diff = max - min; float h = 0.0f; float s = 0.0f; float v = 0.0f; if (max != min) { // H(色相) if (max == r) { h = 60.0f * (g - b) / diff; } else if (max == g) { h = 60.0f * (b - r) / diff + 120.0f; } else { h = 60.0f * (r - g) / diff + 240.0f; } // S(彩度) s = diff / max; } if (h < 0) { h += 360.0f; } h = Mathf.Round(h); if (h >= 360.0f) { h -= 360.0f; } s = s * 100.0f; v = max * 100.0f; return ((int)h, (int)s, (int)v); } }
Exsample.cs(サンプルコード)
動画のサンプルコードも紹介しておきます。(一部はしょりましたが)
ヒエラルキーに TextMeshProUGUI を一つ配置し、合わせて生成された Canvas に次のコードをアタッチします。
ColorEx.cs もプロジェクトに配置しておいてください。
using System.Collections; using System.Collections.Generic; using TMPro; using UnityEngine; public class Exsample : MonoBehaviour { const int CIRCLE_MAX = 12; List<TextMeshProUGUI> texts; // Start is called before the first frame update void Start() { var baseText = GetComponentInChildren<TextMeshProUGUI>(); texts = new List<TextMeshProUGUI>(); // 12 個の●を配置 for (int i = 0; i < CIRCLE_MAX; i++) { var angle = 360 * i / CIRCLE_MAX; var text = Instantiate(baseText, this.transform); text.SetText("●"); text.fontSize = 100; var position = Quaternion.Euler(0, 0, angle) * new Vector3(0, 200, 0); var rect = text.GetComponent<RectTransform>(); rect.localPosition = position; texts.Add(text); } StartCoroutine(color()); } IEnumerator color() { var hsv = ColorEx.RGBtoHSV(texts[0].color.r, texts[0].color.g, texts[0].color.b); while (true) { for (int i = 0; i < CIRCLE_MAX; i++) { // 12 個の色相を等間隔に変化させる int _h = hsv.H + i * (360 / CIRCLE_MAX); if (_h >= 360) { _h -= 360; } var text = texts[i]; var rgb = ColorEx.HSVtoRGB(_h, hsv.S, hsv.V); text.color = new Color(rgb.R, rgb.G, rgb.B, 1); } // 少しずつ H(色相)だけ変化させる。SV はそのまま hsv.H += 2; if (hsv.H >= 360) { hsv.H -= 360; } yield return null; } } }
HSV は便利! 覚えておこう
プログラマーといえど、デザインに片足を突っ込むムーブは必要です。(大手だと、分業が進んでいて不要かもしれませんが)
こういうちょっとした事を知ってるだけで表現の幅は広がります。是非活用してください。