パハットノート

※当サイトではGoogleアドセンス広告を利用しています

Unity ボタンで選択肢の表示と結果の取得





概要

RPGゲームなどによくある会話中の選択肢の表示と、選択結果による処理分岐をできるようにしました。
UIのButtonを使って実現しています。




ソースコード

  • コルーチンのCorGetInput()がメインの処理です。
  • そのため、選択するまで待機するという場合は、yield return selectButtons.CorGetInput();とすればOKです。
  • 追記:Start関数でリストkeysの大きさを変更するようにしていますが、正しく動作しないときがありました。原因は不明ですが、とりあえずエディタ上から直接操作すれば平気なはずです。


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

public class SelectButtons : MonoBehaviour
{
    [SerializeField] List<Button> buttons;
    [SerializeField] List<bool> keys;

    public int Selected
    {
        get
        {
            for (int i = 0; i < keys.Count; i++)
            {
                if (keys[i])
                    return i;
            }

            return -1;
        }
    }

    public IEnumerator CorGetInput()
    {
        //keysをすべてfalseにする
        for (int i = 0; i < keys.Count; i++)
        {
            keys[i] = false;
        }

        //ゲームオブジェクトを表示
        gameObject.SetActive(true);

        //いずれかのボタンが押されるまで待機
        yield return new WaitWhile(() => Selected == -1);

        //ゲームオブジェクトを非表示
        gameObject.SetActive(false);
    }

    // 各ボタンに処理を割り当て
    void Start()
    {
        //keysをbuttonsと同じ長さに
        keys = Enumerable.Repeat(false, buttons.Count).ToList();


        //各ボタンに処理を割り当てる
        for (int i = 0; i < buttons.Count; i++) 
        {
            //一旦別の変数に格納しないとエラー発生
            int a = i;

            //buttonを押すと該当するkeyをtrueに
            buttons[a].onClick.AddListener(() => keys[a] = true);
        }

        //オブジェクトを非表示にする
        gameObject.SetActive(false);
    }
}





実装手順

1. Canvasの追加

まず、Buttonを配置するためのCanvasを追加します。
追加の方法はいろいろありますが、右クリック「UI」⇒「Canvas」でやればいいでしょう。



2. 親オブジェクトの追加

同様に右クリック「UI」⇒「Image」で選択肢の背景を追加します。
オブジェクトの名前は「SelectBox」としました。


3. ボタンの追加

先ほどと同様に右クリック「UI」⇒「Button」でボタンを追加します。

選択肢の数だけボタンが欲しいので「Ctrl」+「D」で先ほどのボタンを複製します。
とりあえず、今回は4つに増やしました。

後は好みでテキストや背景などを付けて次のようにしました。
ここまでの手順でCanvas内は次のようになっています。


ゲーム画面での見た目はこんな感じです。



4. スクリプトのアタッチ

先ほどの「SelectButtons.cs」をImageオブジェクト「SelectBox」にアタッチします。
更に、「buttons」にButtonオブジェクトを追加します。



5. 実行用スクリプトのアタッチ

実行結果を確認するためのスクリプトを用意します。
MainCameraにでもアタッチしましょう。

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

public class Test : MonoBehaviour
{
    [SerializeField] SelectButtons selectButtons;

    private void Update()
    {
        //Kを押すとボタンを表示
        if (Input.GetKeyDown(KeyCode.K))
        {
            StartCoroutine(selectButtons.CorGetInput());
        }

       Debug.Log($"Selected = {selectButtons.Selected}");
    }
}





実行結果

実際に実行すると以下の様になります。
画像では分かりやすくするために、Debug.Logで表示しているところを赤字で表示しています。