Unity入門

【Unity】ToggleGroupで選択状態を取得する方法とonValueChangedイベントの使い方

この記事について

この記事ではToggleGroupの状態取得とonValueChangedイベントについてスクリプト制御する方法について説明します。

この記事でわかること

  • ToggleGroupを使うと 複数Toggleから1つだけ選択できる
  • ActiveToggles()で現在選ばれているToggleを取得できる
  • 各ToggleのonValueChangedを使えば選択変更イベントを処理可能

ToggleGroupとは?

ToggleGroupについては以下の記事を参考にしてください。

ToggleGroupをスクリプトで制御

ToggleGroupをスクリプトで参照する準備

ヒエラルキーで右クリックをしてToggle×3、TextMeshPro、空のGameObjectを用意します。
・「右クリック」→「UI」→「Toggle」
・「右クリック」→「UI」→「Text – TextMeshPro」
・「右クリック」→「Create Empty」

次にスクリプトを作成して「Create Empty」にアタッチしてください。
また、「Add Component」から「Toggle Group」をアタッチしてください。

選択中のToggleを取得する方法

今回はToggleGroupの登録もまとめて行ってみました。(わざわざ1つずつアタッチが面倒なので…)
また、ToggleGroupでは1つしか選択できないのでToggle2以外はチェックを外しました。

using System.Linq;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

public class ToggleGroup_Test : MonoBehaviour
{
    [SerializeField] private ToggleGroup testToggleGroup;
    [SerializeField] private TMP_Text testText;
    [SerializeField] private Toggle[] testToggle;

    void Start()
    {
        // 自分にアタッチされている ToggleGroup を取得
        testToggleGroup = GetComponent<ToggleGroup>();
        // 子オブジェクトの TMP_Text を取得
        testText = GetComponentInChildren<TMP_Text>();
        // 子オブジェクトの Toggle をすべて取得
        testToggle = GetComponentsInChildren<Toggle>();

        // 取得した Toggle をすべて同じ ToggleGroup に登録
        foreach (Toggle t in testToggle)
        {
            t.group = testToggleGroup;
        }

        // 現在選択されている Toggle を取得
        Toggle activeToggle = testToggleGroup.ActiveToggles().FirstOrDefault();

        if (activeToggle != null)
        {
            // 選択中のトグル名を表示
            testText.text = activeToggle.name;
        }
    }
}

実行してみると、スクリプト通りToggle2がチェックされていることを取得できました。
※ActiveToggles() は現在ONになっているToggleを返します。

イベント「onValueChanged」で選択変更を検知する

今回は「onValueChanged」でToggleGroup内のToggleが変わった時に発生するイベントを使用しました。

using System.Linq;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

public class ToggleGroup_Test : MonoBehaviour
{
    [SerializeField] private ToggleGroup testToggleGroup;
    [SerializeField] private TMP_Text testText;
    [SerializeField] private Toggle[] testToggle;

    void Start()
    {
        // 自分にアタッチされている ToggleGroup を取得
        testToggleGroup = GetComponent<ToggleGroup>();
        // 子オブジェクトの TMP_Text を取得
        testText = GetComponentInChildren<TMP_Text>();
        // 子オブジェクトの Toggle をすべて取得
        testToggle = GetComponentsInChildren<Toggle>();

        // 取得した Toggle をすべて同じ ToggleGroup に登録
        foreach (Toggle t in testToggle)
        {
            t.group = testToggleGroup;
        }

        // 現在選択されている Toggle を取得
        Toggle activeToggle = testToggleGroup.ActiveToggles().FirstOrDefault();

        if (activeToggle != null)
        {
            // 選択中のトグル名を表示
            testText.text = activeToggle.name;
        }

        //イベント処理の追加
        foreach (Toggle t in testToggleGroup.GetComponentsInChildren<Toggle>())
        {
            t.onValueChanged.AddListener((isOn) =>
            {
                if (isOn)
                {
                    // 選択中のトグル名を表示
                    testText.text = t.name;
                }
            });
        }
    }
}

実行してみると、スクリプト通りに選択したToggleがTextに反映されました。

まとめ

  • ToggleGroupを使うと「1つだけ選択」のUIを簡単に作れる
  • ActiveToggles()で現在の選択を取得可能
  • onValueChangedで選択変更イベントを処理できる