Unity ボタンが押せないようにする方法

Unity解説

ねえねえ、1回つかったボタンを押せなくしたいんだ!

大丈夫、簡単にできるよ!

Unity標準ボタンについているInteractableを使えば簡単にボタンを押せなくできます。しかしながら、少し作りこんだボタンを使っているときはうまくいかないことがあります。

本記事ではUnity標準ボタンを拡張するコンポーネントを追加してボタンを非活性にする方法を解説します。

※ただし、Unity標準ボタンはロングタップできないので今後のために使わないほうがよいです。すでにゲーム内でUnity標準ボタンを使っていて追加の仕様として非活性が必要になったケースについての解説となります。自作ボタンについては今後解説いたします。

まずは結論を簡単にご紹介します。

ボタンのWrapperを作る

ボタンのWrapperとは
  • 内部に標準ボタンを持つ拡張用コンポーネント
  • Unity標準ボタンにはない機能を実現する
  • ButtonのOnClickにセットして使う

見慣れない単語が出てきましたね。ラッパーと読みます。
他にもクリックしたときの色やTweenも同じようにラッパーを使います。
大丈夫、やることは簡単です。順番に解説いたします。

Unity標準ボタンのInteractable

まずはただのUnity標準ボタンのおさらいです。標準ボタンにはInteractableという属性があり、これはボタンが押せるか押せないかを設定できます。

標準ButtonのInteractable

これをボタン押したときにオフにすればよいのです。

オフにするのは追加のスクリプトも不要です。ボタンなので、ボタンを押したときの処理をセットすると思いますが、それに加えてボタン自身のInteractableをfalseにセットするよう設定します。

実行すると、1度押したら半透明になって押せなくすることができます。

InteractableがOnの状態とOffの状態

少し作りこんだボタンを押せなくする方法

標準ボタンであれば前述のとおりInteractableをOffにすればいいことは分かりました。では、少し凝ったボタンを押せなくするにはどうすればいいでしょうか。順を追って説明します。

画像を複数使ったボタンのInteractable をオフにすると・・・

少しだけ見栄えをよくしたボタンを考えてみましょう。標準ボタンを使用しているのは同じなのですが、画像を複数使っています。

これを先ほどと同じようにInteractableをオフにしてみます。すると、なんということでしょう、背景画像だけが薄くなりました。

複数画像ボタンでInteractableをオフ(左)

これは、Buttonが透明にできるImageが指定した1つだけだからです。ButtonのTarget Graphicです。

Target GraphicだけInteractableオフで透明になる

ボタンを拡張するWrapperを作る

では、全部を半透明にできるように拡張していきましょう。
ボタンのOnClickのときに画像全部とテキストを半透明にする処理を作ります。今回はButtonInvalidatorという名前にしました。

ButtonInvalidator .cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;

public class ButtonInvalidator : MonoBehaviour
{
    // 半透明にしたい画像全部
    Image[] images;

    // 半透明にしたいテキスト全部
    TextMeshProUGUI[] texts;

    // 非活性にしたいボタン本体
    Button button;

    // 非活性にしたときの半透明の度合
    private float alpha_on_invalid = 0.7f;

    private void Start()
    {
        images = gameObject.GetComponentsInChildren<Image>();
        texts = gameObject.GetComponentsInChildren<TextMeshProUGUI>();
        button = gameObject.GetComponent<Button>();
    }

    /// <summary>
    /// ボタンを非活性にします
    /// </summary>
    public void Inactivate()
    {
        foreach (var image in images)
        {
            image.color = new Color(
                image.color.r, 
                image.color.g, 
                image.color.b, 
                alpha_on_invalid);
        }

        foreach (var text in texts)
        {
            text.color = new Color(
                text.color.r, 
                text.color.g, 
                text.color.b, 
                alpha_on_invalid);
        }

        button.interactable = false;
    }
}

特に難しいことはないと思います。
半透明にしたいImageとTextを全部とってきてColorのアルファ(透明度)を変更しています。
そして、ボタン自体のinteractableをオフにすることで押せない状態にします。

1点注意があります。ボタン本体のDisabled Colorはアルファ値を255にしておいてください。
スクリプトで設定したアルファ値に掛け算されるみたいで、不当に透明度が上がります。

ボタンにWrapperを適用する

このButtonInvalidatorスクリプトを、ボタンと同じ階層にアタッチします。

ボタンのほうのOnClickにInactivateをセットします。

なお、画像にあるSomethingHapperner.TweenCube1は、ボタン押したときに実行したい本来の処理です。

これでセット完了です。実行すると、無事に複数画像のボタンも押せなくできました。

押せなくしたいボタン全部にスクリプトのアタッチとOnClickの設定をする

まだ作業は残っています。この仕様変更をすべてのボタンに適用しないといけません。

スクリプトの取り付けは、対象のボタンを全部選択してAdd Componentです。

OnClickは一括ではできませんので、1つ1つ手作業でセットしてください。一括でやると、全部が同じボタンを参照してしまいます。

OnClickを一括でやると意図しないボタンがセットされる

なお、少し理解は難しいですがスクリプトでOnClickへ自動的セットする方法もあります。
これならOnClickをセットせずともスクリプトに1行書くだけで追加仕様を反映できます。

ButtonInvalidator.cs

    private void Start()
    {
        // 半透明にする処理の準備
        images = gameObject.GetComponentsInChildren<Image>();
        texts = gameObject.GetComponentsInChildren<TextMeshProUGUI>();
        button = gameObject.GetComponent<Button>();

        // OnClickに半透明処理Inactivateメソッドを追加
        button.onClick.AddListener(Inactivate);
    }

ボタンのonClickイベントにイベントハンドラを追加しています。
テストプレイ再生中もインスペクタには出てきませんが、内部で機能は追加されています。

でも、OnClickをインスペクタからセットするのとスクリプトで追加するのが混在するとけっこうバグのリスクがあって不具合箇所の特定も非常に困難なので、あまりやらない方がいいかもしれません。
もしやるなら、インスペクタからのセットは廃止してスクリプトに統一したほうがいいです。

ボタンが押せないようにする方法まとめ

本記事では、はUnity標準ボタンを拡張するコンポーネントを追加してボタンを非活性にする方法を解説しました。

標準ボタンだけであればInteractableを操作、少し作りこんだボタンならWrapperを作って拡張をします。

ボタンのWrapperとは
  • 内部に標準ボタンを持つ拡張用コンポーネント
  • Unity標準ボタンにはない機能を実現する
  • ButtonのOnClickにセットして使う

ボタンの拡張はそれほど難しくありませんが、後から仕様を追加するとなると手戻りが大変です。
あらかじめ仕込んでおいてハッピーになりましょう。

かわいい我が子にオリジナルアプリを!

コメント

タイトルとURLをコピーしました