【Unity】プロジェクト内の色を一元管理&一括変更する「uPalette」を公開しました

Unityプロジェクト内の色を一元管理&一括変更する「uPalette」を公開しました。

github.com

概要

uPaletteはプロジェクト内の色を一元管理&一括変更するシステムです。

f:id:halya_11:20210516220837g:plain
デモ

特徴
  • Unityプロジェクト内で使用している色を一元管理
  • 色を変更するとプロジェクト全体に自動反映されるため、デザインの変更が容易に
  • Adobe XDのアセットパネルのようなUX
  • Prefab/Prefab Variantにも対応

セットアップ

バージョン要件

Unityのバージョンは2020.1以上に対応しています(Generic型のシリアライズを使っているため)。

インストール
  1. Window > Package ManagerからPackage Managerを開く
  2. 「+」ボタン > Add package from git URL
  3. 以下を入力

f:id:halya_11:20210407093633p:plain
Package Manager

あるいはPackages/manifest.jsonを開き、dependenciesブロックに以下を追記します。

{
    "dependencies": {
        "com.harumak.upalette": "https://github.com/Haruma-K/uPalette.git?path=/Assets/uPalette"
    }
}

バージョンを指定したい場合には以下のように記述します。

ライセンス

本ソフトウェアはMITライセンスで公開しています。
ライセンスの範囲内で自由に使っていただいてかまいませんが、
使用の際は以下の著作権表示とライセンス表示が必須となります。

https://github.com/Haruma-K/uPalette/blob/master/LICENSE.md

使い方

色を作成する

uPaletteで管理する色は以下の手順で作成します。

  1. Window > uPalette
  2. uPaletteウィンドウ左上のCreateボタンを押下
  3. 色と名前を自由に設定する
  4. 削除は右クリックメニューから

f:id:halya_11:20210517002619g:plain
色を作成・削除

設定データはStreamingAssets/uPalette以下に保存されます。
プレイヤービルド時に必要なデータとなりますので削除しないようご注意ください。

色を反映する

作成した色は以下の手順で反映します。

  1. 反映したいGameObjectを選択
  2. Applyボタンを押下
  3. 色を反映するコンポーネント/プロパティ名を選択

f:id:halya_11:20210517003755g:plain
色を適用する

以上の手順で色とプロパティがリンクされます。
リンクを解除するにはInspectorからColorSetterコンポーネントをデタッチします。

また、デフォルトで反映できるクラス/プロパティは以下の通りです。

クラス名 プロパティ名
Graphic color
Outline effectColor
Selectable colors.normalColor
Selectable colors.selectedColor
Selectable colors.pressedColor
Selectable colors.disabledColor
Selectable colors.highlightedColor
InputField caretColor
InputField selectionColor

これ以外のプロパティに色を反映する方法については「独自のコンポーネントに色を適用する」を参照してください。

なおPrefabのインスタンスに色を反映した場合には、通常のPrefabワークフローと同様、Prefabには反映されていない状態となります。
Prefabに反映するには右クリックメニューなどからColor SetterをApplyしてください。

f:id:halya_11:20210517010717g:plain
Color SetterをApply

色を適用しているGameObjectをハイライトする

色を右クリック > Highlightを選択すると、その色が適用されているGameObjectがハイライト(選択)されます。

f:id:halya_11:20210517005013g:plain
ハイライト

独自のコンポーネントに色を反映する

ColorSetterクラスを継承したクラスを作成すると、独自のコンポーネントに色を反映できます。

using UnityEngine;
using UnityEngine.UI;

[AddComponentMenu("")]
[DisallowMultipleComponent]
[RequireComponent(typeof(Outline))]
[ColorSetter(typeof(Outline), "Color")] // ColorSetterアトリビュートを付ける
public class OutlineColorSetter : ColorSetter
{
    [SerializeField] [HideInInspector] private Outline _outline;

    private void Awake()
    {
        if (Application.isEditor)
        {
            _outline = GetComponent<Outline>();
        }
    }

    // Applyメソッドをオーバーライドして色を適用する
    protected override void Apply(Color color)
    {
        _outline.effectColor = color;
    }
}
スクリプトから操作する

色をスクリプトから操作するには以下のようにします。

using System.Linq;
using UnityEngine;
using uPalette.Editor.Core;
using uPalette.Runtime.Core;

public class Example
{
    private void Main()
    {
        var app = UPaletteApplication.RequestInstance();

        try
        {
            var store = app.UPaletteStore; // アプリケーションの状態

            // エントリを取得して変更を加える
            var entry = store.Entries.First();
            entry.Name.Value = "Example";
            entry.SetColor(Color.red);

            // 変更を加えたらStoreにDirtyフラグを立てる(自動的に保存される)
            store.IsDirty.Value = true;
        }
        finally
        {
            UPaletteEditorApplication.ReleaseInstance();
        }
    }
}

技術的詳細

変更した色を反映するタイミングについて

Unityでは、各コンポーネントに設定されている色はそのまま値としてシリアライズされます。
したがって、uPaletteで色を変更したときにはこのシリアライズされた値を書き換えるべきです。

しかしこれでは、色を変更するだけで多くのSceneやPrefabに変更が加わってしまいます。
そこでuPaletteでは以下のルールに従って色を反映しています。

  • uPaletteの色は値ではなくIDとしてシリアライズ
  • Edit ModeではOnEnable時にこの色を反映・色の変更を監視する
  • Play ModeではStart()のタイミングで色を反映する

また、Edit ModeでSceneを開いたときに変更が加わらないよう、
シリアライズされたIDの色を反映するときにはDirtyフラグを立てない実装にしています。

デモ

デモシーンは以下の手順で再生できます。

  1. リポジトリをクローンする
  2. 以下のシーンを開いて再生

リポジトリ

github.com