【Unity】トグルの仕組みを作る

Unityのトグルグループは、ユーザーが複数の選択肢の中から一つだけを選べるUIコンポーネントです。これはラジオボタンのように機能し、各トグルをToggle Groupコンポーネントに割り当てることで、一つのトグルがオンの場合、他はオフになります。これにより、排他的な選択が可能になり、UIの設計が簡潔かつ効果的に行えます。

トグルグループの作成サンプル

Canvasの準備

まず、UI要素を配置するためのCanvasが必要です。Hierarchyで右クリックし、「UI」→「Canvas」を選択してCanvasを作成します。

Toggle Group用のGameObjectを作成

Canvas内で、新しい空のGameObjectを作成します。これがToggle Groupを管理するコンテナとなります。
GameObjectに「Toggle Group」という名前を付けると、管理がしやすくなります。

Toggle Groupコンポーネントの追加

作成した空のGameObjectを選択し、Inspectorで「Add Component」ボタンをクリックします。
「UI」カテゴリから「Toggle Group」コンポーネントを検索して追加します。

トグルの配置を自動化したい場合(オプション)

作成した空の「Toggle Group」GameObjectを選択し、Inspectorで「Add Component」ボタンをクリックします。
「Layout」カテゴリから「GridLayoutGroup」コンポーネントを検索して追加します。
(以下の作成後のエディター状態のキャプチャには追加されています)

トグルの追加

Toggle GroupのGameObjectが選択された状態で、Hierarchyで右クリックし、「UI」→「Toggle」を選択してトグルを追加します。

各トグルのInspectorウィンドウで、"Group"フィールドに先ほど作成したToggle Groupコンポーネントが付いたGameObjectをドラッグ&ドロップします。

各トグルの設定

トグルの見た目や動作をカスタマイズします。ラベルやチェックマークのスタイルなどを変更できます。

スクリプトでの制御(オプション)

using UnityEngine;
using UnityEngine.UI;  // UI関連のコンポーネントを使用するために必要

public class ToggleAction : MonoBehaviour
{
    public Toggle toggle;  // このスクリプトがアタッチされているトグル

    void Start()
    {
        // Toggleの値が変わったときに呼ばれるリスナーを追加
        toggle.onValueChanged.AddListener(OnToggleChanged);
    }

    // Toggleの状態が変更されたときに呼ばれるメソッド
    void OnToggleChanged(bool isOn)
    {
        if (isOn)
        {
            // トグルがオンになったときの処理
            Debug.Log(toggle.name + " is turned on.");
        }
        else
        {
            // トグルがオフになったときの処理
            Debug.Log(toggle.name + " is turned off.");
        }
    }
}

スクリプトの使用方法

  1. スクリプトの保存:上記のスクリプトをToggleAction.csという名前でUnityプロジェクトのAssetsフォルダに保存します。
  2. スクリプトのアタッチ:Hierarchyでトグルを選択し、InspectorビューでToggleActionスクリプトをドラッグ&ドロップしてアタッチします。
  3. トグルの設定:スクリプトのtoggleフィールドに、そのトグル自体をドラッグ&ドロップして設定します。

以上で設定は完了です。これでトグルのオン/オフ状態が変わるたびに、それぞれ指定されたログがコンソールに表示されます。もしトグルごとに異なるアクションを設定したい場合は、各トグルに対してスクリプトをアタッチし、それぞれのトグルにカスタマイズされたアクションを書き加えることができます。

作成後のエディター状態

ToggleGroupゲームオブジェクトにアタッチするケースのイベントを活用したコード

上記のようにToggleゲームオブジェクトにアタッチするのではなく、1箇所のみのアタッチになります

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

public class ToggleGroupHandler : MonoBehaviour
{
    public ToggleGroup toggleGroup;  // InspectorからToggle Groupをアタッチ
    private List<Toggle> toggles = new List<Toggle>();

    void Start()
    {
        // Toggle Groupに含まれる全てのトグルを取得し、リスナーを追加
        foreach (Transform child in toggleGroup.transform)
        {
            Toggle toggle = child.GetComponent<Toggle>();
            if (toggle != null)
            {
                toggles.Add(toggle);
                toggle.onValueChanged.AddListener((isOn) => ToggleChanged(toggle, isOn));
            }
        }
    }

    // トグルの状態が変わった時に呼び出されるメソッド
    void ToggleChanged(Toggle changedToggle, bool isOn)
    {
        if (isOn)
        {
            Debug.Log(changedToggle.name + " is selected.");
            // ここでその他のアクションを実行
        }
    }
}

実行結果

おまけ

汎用的に使えるようにイベントは外部から登録できるようにした場合

外部のコンポーネントからUnityのUnityEventにメソッドを動的に登録することで、様々な挙動を柔軟に制御することができます。以下の例では、異なるスクリプトがToggleGroupHandlerに定義されたイベントにリスナーを追加する方法を示します。

ToggleGroupHandler スクリプト

まず、ToggleGroupHandlerスクリプトにUnityEventを含めます。これはトグルの状態が変更された時にトリガーされるイベントです。

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Events;

public class ToggleGroupHandler : MonoBehaviour
{
    public ToggleGroup toggleGroup;  // InspectorからToggle Groupをアタッチ
    public UnityEvent<Toggle> onToggleChanged = new UnityEvent<Toggle>();

    void Start()
    {
        foreach (Transform child in toggleGroup.transform)
        {
            Toggle toggle = child.GetComponent<Toggle>();
            if (toggle != null)
            {
                toggle.onValueChanged.AddListener((isOn) => {
                    if (isOn) onToggleChanged.Invoke(toggle);
                });
            }
        }
    }
}

外部からイベントを登録するスクリプト

次に、別のスクリプトからToggleGroupHandlerのイベントにメソッドを登録する例です。これは例えば、UIの状態に基づいてゲームの設定を更新する際に使用することができます。

using UnityEngine;

public class SettingsManager : MonoBehaviour
{
    public ToggleGroupHandler toggleGroupHandler;  // Inspectorからアタッチする

    void Start()
    {
        // トグルが変更された時に呼ばれるメソッドを登録
        toggleGroupHandler.onToggleChanged.AddListener(HandleToggleChange);
    }

    void HandleToggleChange(Toggle toggle)
    {
        Debug.Log("Toggle changed: " + toggle.name);
        // ここで、トグルの状態に基づいた設定やアクションを実行
    }

    void OnDestroy()
    {
        // 必要に応じてリスナーを削除
        if (toggleGroupHandler != null)
        {
            toggleGroupHandler.onToggleChanged.RemoveListener(HandleToggleChange);
        }
    }
}

使い方

  1. Unityエディタでの設定:
    • ToggleGroupHandlerをトグルグループが含まれるGameObjectにアタッチします。
    • SettingsManagerを適当なGameObjectにアタッチし、toggleGroupHandlerプロパティにToggleGroupHandlerがアタッチされたGameObjectをドラッグして設定します。
  2. プレイモードでのテスト:
    • Unityエディタのプレイモードを開始して、トグルの状態を変更すると、SettingsManagerHandleToggleChangeメソッドが呼び出され、トグルの名前がログに表示されます。

この方法により、システム間の依存を減らし、コンポーネント間でのコミュニケーションを効率的に行うことができます。また、イベントの登録と削除を適切に管理することで、メモリリークを防ぐことも重要です。

UI,Unity

Posted by hidepon