質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.23%

Unity 動的に生成したボタンに、それぞれ異なるボタン処理を行いたい

解決済

回答 1

投稿

  • 評価
  • クリップ 1
  • VIEW 4,031

Hutax

score 32

前提・実現したいこと

UnityのuGUIのボタンに関する質問なのですが、C#によって動的にボタンを作成するスクリプトを作成しました。(BtnMng.cs)
このスクリプトでは、MySQLに保存しているデータを引っ張ってきて、生成するボタンにTextとして貼り付けています。
実現したいことは、動的に生成したボタンにそれぞれ異なるボタン処理を行いたいです。

発生している問題・エラーメッセージ

動的に生成されたボタンにそれぞれ異なるクリックイベントをつけたいのですが、どのようなコードを追加すればよいのかわからず行き詰ってしまいました。

該当のソースコード

BtnMng.cs

using UnityEngine;
using System.Collections;
using MiniJSON;
using UnityEngine.UI;

public class BtnMng : MonoBehaviour
{
    [SerializeField]    RectTransform prefab = null;

    void Start()
    {
        StartCoroutine("GetJSON");
    }

        IEnumerator GetJSON()
    {
            // webサーバへアクセス
            WWW www = new WWW("http://localhost/~~~.php");

            // webサーバから何らかの返答があるまで停止
            yield return www;
            // もし、何らかのエラーがあったら
            if (!string.IsNullOrEmpty(www.error))
            {
                // エラー内容を表示
                Debug.LogError(string.Format("Fail Whale!\n{0}", www.error));
                yield break; // コルーチンを終了
            }
            // webサーバからの内容を文字列変数に格納
            string json = www.text;
            // JSONデータは最初は配列から始まるので、Deserialize(デコード)した直後にリストへキャスト          
            IList List = (IList)Json.Deserialize(json);

            // リストの内容はオブジェクトなので、辞書型の変数に一つ一つ代入しながら、処理
            foreach (IDictionary list in List)
            {
                string number = (string)list["num"];

            var item = GameObject.Instantiate(prefab) as RectTransform;
            item.SetParent(transform, false);

            var text = item.GetComponentInChildren<Text>();
            text.text = number.ToString() + "番";
        }
    }
}

試したこと

多くのサイトを参考にして
BtnMng.csの text.text = number.ToString() + "番"; の後に

button.onClick.AddListener(() =>
            {               
                print("aaa");
            });


を記載すると、すべてのボタンで、クリックするとaaaという文字がログに表示されるようになりましたが、それぞれのボタンで異なる処理をするには未だ至っておりません。

まだUnityを始めたばかりのため、至らない点多くあり、説明が不足している点があるかと思いますが、何卒ご協力お願いできないでしょうか。よろしくお願い致します。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

UnityのSendMessageはご存知ですか?
SendMessage
この機能は文字列を渡すと、その関数を実行してくれるという便利な機能です。(普通に呼び出すより幾分遅い処理ですが)
例えば、print("aaa")のところをSendMessage("aaa")に書き換えると、
void aaa() という関数を実行します(もちろん、作ってない場合はエラーになります)

この機能を利用すれば、渡す文字列を変えるだけで処理を分ける事が可能です。
Unity SendMessageでググればもっと実用的な使い方を説明しているサイトも山程出てきますのでお試しください。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/09/12 18:02

    追記(始めたばかりということなので、念のため)
    string number = "Function001";
    button.onClick.AddListener(() =>
    {
    print(number);
    });

    のようにAddListenerの上で定義している変数は特に何もしなくても
    AddListenerの中でも普通に使えます。

    キャンセル

  • 2016/09/12 20:43

    ishi9様
    ご回答ありがとうございます。
    教えていただきましたSendMessageを調べてみました。
    それを基に色々試しましたが、私の知識、理解が不十分であるため、
    分かりやすく教えていただいたにも関わらず、うまくいきませんでした。
    そこで以下のように、値を指定し、一致した時だけイベント処理をするという感じにしました。(これだとたくさんのif文が必要になってしまいますが…)
    string num1 = number.ToString();
    Button button = item.GetComponent<Button>();
    if (num1 == "1")
    {
    button.onClick.AddListener(() =>
    {
    print("aaaaaa");
    });
    }

    よろしければ、SendMessageを用いた場合は
    どのようなコードとなるのかご教授お願いできないでしょうか。

    お手を煩わすようなこととなってしまい大変申し訳ございません。

    キャンセル

  • 2016/09/13 10:57 編集

    すいません、今回のケースであればSendMessageは無理に使う必要は無さそうです。
    (無理に使うとかえって処理が複雑になります)

    ひとまず大量のif文が気になるということであればswitch文を検討してみてはいかがでしょうか?

    string num1 = number.ToString();
    Button button = item.GetComponent<Button>();
    switch (num1)
    {
      // ここから
      case "1":
      {
        button.onClick.AddListener(() =>
        {
          print("aaaaaa");
        });
      }
      break;
      // ここまでが1セット
      
      // 上記の1セットをコピペして num が "2"だった場合の処理を追加
      case "2":
      {
        button.onClick.AddListener(() =>
        {
          print("bbbbbb");
        });
      }
      break;
      // ここまでがnum が ”2" だった場合の処理

    } // switch文はここまで

    キャンセル

  • 2016/09/13 11:20

    ishi9様
    コメントありがとうございます。
    今回の場合はSendMessageは利用しない方が良いということですが、
    新たな知識としてSendMessageの使い方を学ぶことができたため、教えていただき感謝しております。
    丁寧に教えていただき、ありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.23%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる