【Unity】Editor再生せず、プルダウンメニューからボタンの色を変更する

2019/10/11DEVELOP, Unity

Inspecterからボタンタイプ毎に設定された色を即時反映させるスクリプトです。アプリ内のボタンの色は、決定ボタンだったり、キャンセルボタンだったりで統一されていた方が良いですし、必要箇所で毎回RGB値を入力していては漏れも発生するのでプルダウンメニューからTypeを選択するだけで変更できる様にしてみます。

ボタン色定義用のクラス

まずはボタン色を定義するクラスを用意します。

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public static class ButtonColor
{
    [System.Serializable]
    public enum Type
    {
        // 初期
        Default,
        // 決定
        Decide,
        // キャンセル
        Cancel,
    }
    private static readonly Dictionary<Type, Color> m_Dict = new Dictionary<Type, Color>()
    {
        {Type.Default,  Color.white},
        {Type.Decide,  Color.green},
        {Type.Cancel,  Color.red},
    };
    public static Color Get(Type _type)
    {
        return m_Dict[_type];
    }
}

ボタンのビュー用クラス

次に、ButtonコンポーネントにAddComponentするクラスを作成します。

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
#if UNITY_EDITOR
using UnityEditor;
#endif
public class ButtonView : MonoBehaviour
{
	[SerializeField, Header("ボタン背景")]
	private Image m_ButtonImage;
	
	public Image buttonImage
	{
		get { return m_ButtonImage; }
	}
	
	[SerializeField, Header("ボタンカラータイプ")]
	private ButtonColor.Type m_ButtonColorType;
	
	public ButtonColor.Type buttonColorType
	{
		get { return m_ButtonColorType; }
		set { m_ButtonColorType = value; }
	}
	
#if UNITY_EDITOR
	private void OnValidate()
	{
		if (Application.isPlaying)
		{
			return;
		}
		
		if (buttonImage != null)
		{
			buttonImage.color = ButtonColor.Get(buttonColorType);
		}
	}
}
#endif

ButtonViewクラスは、Inspecter上でAddComponentしたら、buttonImageに色変更するイメージをセットしておきます。OnValidateで色変更しています。

結果

ButtonColorTypeをプルダウンメニュー切り替える様になり、色が反映されます。

番外編 Property Backing Field Drawer アセットを使った方法

いくつかの書き方を省略できます。

Property Backing Field Drawer – Asset Store

こちらのツイートで知ることが出来ました。

ボタンのビュー用クラス(PropertyBackingField使用版)

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Candlelight;
public class ButtonView : MonoBehaviour
{
    [SerializeField, Header("ボタン背景")]
    private Image m_ButtonImage;
    public Image buttonImage
    {
        get { return m_ButtonImage; }
    }
    [SerializeField, PropertyBackingField, Header("ボタンカラータイプ")]
    private ButtonColor.Type m_buttonColorType;
    public ButtonColor.Type buttonColorType
    {
        get { return m_buttonColorType; }
        set
        {
            m_buttonColorType = value;
            buttonImage.color = ButtonColor.Get(m_buttonColorType);
        }
    }
}

OnValidateを書く必要が無くなり、UNITY_EDITOR定義も除去できます。素晴らしいアセットです。

Posted by kazupon