Programming Serendipity

プログラミングを中心に種々雑多に書き留めます

Unity上のボタンなどクリックで色が変えられるオブジェクトのパラメータを一括変更するスクリプト

おとといのスクリプトをもとに、ColorBlockについても同様のことができるようにしてみました。パラメータを指定してApplyボタンを押すとColorBlockを持ってる(=Selectableクラスを継承している:Button, Toggle, Slider, Scrollbar, DropDown, InputField)の通常色、ハイライト色、押した時の色、無効色、色補正、フェード時間が一発で変更できます。

using UnityEngine;
using UnityEditor;
using UnityEngine.UI;

class ScriptableColorBlock : ScriptableObject
{
    public Color normalColor = new Color32(221, 221, 221, 255);
    public Color hilightedColor = new Color32(255, 255, 255, 255);
    public Color pressedColor = new Color32(128, 128, 128, 255);
    public Color disabledColor = new Color32(160, 160, 160, 128);
    [Range(1f, 5f, order = 0)]
    public float colorMultiplier = 1;
    public float fadeDuration = 0.1f;
}

public class ColorBlockChanger : EditorWindow 
{
    static SerializedObject so;

    static SerializedProperty normalColorProperty;
    static SerializedProperty hilightedColorProperty;
    static SerializedProperty pressedColorProperty;
    static SerializedProperty disabledColorProperty;
    static SerializedProperty colorMultiplierProperty;
    static SerializedProperty fadeDurationProperty;

    [MenuItem("Tools/Change All ColorBlocks")]
    public static void ShowWindow()
    {
        EditorWindow a = EditorWindow.GetWindow(typeof(ColorBlockChanger), true, "Selectable Color Setter");
        var obj = ScriptableObject.CreateInstance<ScriptableColorBlock>();
        so = new UnityEditor.SerializedObject(obj);

        normalColorProperty    = so.FindProperty("normalColor");
        hilightedColorProperty  = so.FindProperty("hilightedColor");
        pressedColorProperty    = so.FindProperty("pressedColor");
        disabledColorProperty  = so.FindProperty("disabledColor");
        colorMultiplierProperty = so.FindProperty("colorMultiplier");
        fadeDurationProperty    = so.FindProperty("fadeDuration");

        Debug.Log("ColorBlock Changer ready.");
    }

    void OnGUI()
    {
        EditorStyles.label.wordWrap = true;

        EditorGUILayout.LabelField("it will changes colors of the all selectable objects (like button, toggle, drop down, etc.) in the hierarchy.");
        EditorGUILayout.PropertyField(normalColorProperty);    
        EditorGUILayout.PropertyField(hilightedColorProperty);
        EditorGUILayout.PropertyField(pressedColorProperty);
        EditorGUILayout.PropertyField(disabledColorProperty);
        EditorGUILayout.PropertyField(colorMultiplierProperty);
        EditorGUILayout.PropertyField(fadeDurationProperty);

        if (GUILayout.Button("Apply to All Selectable Objects"))
        {
            Debug.Log("trying to change all ColorBlock parameters as you specified");

            var textComponents = Resources.FindObjectsOfTypeAll(typeof(Selectable)) as Selectable[];
            foreach (var component in textComponents)
            {
                var colors = component.colors;
                colors.normalColor = normalColorProperty.colorValue;
                colors.highlightedColor = hilightedColorProperty.colorValue;
                colors.pressedColor = pressedColorProperty.colorValue;
                colors.disabledColor = disabledColorProperty.colorValue;
                colors.colorMultiplier = colorMultiplierProperty.floatValue;
                colors.fadeDuration = fadeDurationProperty.floatValue;
                component.colors = colors;
            }
        }
    }
}

行数が増えただけで、やってることの本質は前回と変わりません。

なぜかRange属性が反映されませんが。。。どうして?
あと、ScriptableColorBlockはどうせこのクラス内でしか使わないしと思って内部クラスにしようとしたらエラーになってしまった・・・グローバル名前空間直下じゃないとダメなのか?
という疑問はありますが、とりあえず意図通りに動いているので良しとします。