uGUI で動的にボタンを作る

ボタンを動的に作って縦並びにする

uGUI使って、ボタンは動的に生成し、縦並びにボタンを並べたい。
普通にVertical Layout Groupコンポーネントをつけたオブジェクトにボタンを突っ込んでいけばいいはずだ。
UIエレメントでもいつもどおり、複製したいボタンをPrefab化しておいて、Instantiate すれば良いだろう。

↓みたいな感じでとりあえず書いた。

1
2
3
4
5
6
7
8
9
10
11
// Vertical Layout Group コンポーネントをつけたGameObject
Transform list = transform.FindChild("List");
for(int i = 0; i < 5; i++) {
//プレハブからボタンを生成
GameObject listButton = Instantiate(listButtonPrefab) as GameObject;
//Vertical Layout Group の子にする
listButton.transform.SetParent(list);
//適当にボタンのラベルを変える
//※ Textコンポーネントを扱うには using UnityEngine.UI; が必要
listButton.transform.FindChild("Text").GetComponent<Text>().text = i.ToString();
}

結果、全然綺麗に並ばず。

綺麗に並ばないパターン

SetParentにworldPositionStays=false が必要

調べた結果、Creating UI elements from scripting
Transform.SetParent メソッドの worldPositionStays パラメータを false にしてねってことらしい。

というわけで、以下のように修正
listButton.transform.SetParent(list, false);

結果、綺麗に並んだ。
綺麗に並んだ結果

クリックイベントを追加する

ボタンだから押せないと意味が無い。
イベントは ButtonのOnClick.AddListenerにメソッドを登録すれば良い。とりあえず、何番目のボタンが押されたかログを出してみる。
スコープの関係で i を n に一度代入している(参考:匿名メソッドとデリゲート)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void Start () {
Transform list = transform.FindChild("List");
for(int i = 0; i < 5; i++) {
//プレハブからボタンを生成
GameObject listButton = Instantiate(listButtonPrefab) as GameObject;
//Vertical Layout Group の子にする
listButton.transform.SetParent(list,false);
listButton.transform.FindChild("Text").GetComponent<Text>().text = i.ToString();

//以下、追加---------
int n = i;
//引数に何番目のボタンかを渡す
listButton.GetComponent<Button>().onClick.AddListener(() => MyOnClick(n));
}
}

void MyOnClick(int index){
print(index);
}

確認バージョン

Unity 4.6

Unityカテゴリの記事
Color SpaceがLinearのときUIの透明度が正しくならない
History Inspectorの紹介
History Inspectorの紹介
敵AIとビジュアルスクリプティング
Chronosを使った感想
コンポーネントの順番をスクリプトから並び替える
Smart Inspectorの紹介
Kris' Favorite Assets が便利
キー操作でUIのナビゲーションをループさせる
TextMeshProのSprite Assetを更新する
UnityPhysicsDebugDraw2D が便利
色管理を考える
細かいTips
ビルドスクリプトを書く
AnimatorのCulling Modeでハマった話
Vectrosityを使ってUGUI上で線や円のアニメーションをする
スプレッドシートからjsonデータを読み込む
ビジュアルノベルアセットFungusにコマンドを追加してカスタマイズする
Skinned Mesh Renderer の Boundsについて
シーンごとにビルド結果の容量を出す
シーンビューにクオリティ設定のスライダーを出すエディタ拡張
ビルド結果のFile headersが大きい理由
フリーのビジュアルノベルアセットFungusを使ってRPGのイベントを作る
Move To View を改良する
フリーのビジュアルノベルアセットのFungusが便利
Visual Studio で保存時にフォーマットする
スプレッドシートからデータを読み込む
Easy Save2 で シリアライズされたクラスを保存する
ShaderでSpriteの色相をシフトする
Sprite、Texture の 色相をシフトする
uGUIのButtonをクリック時にハイライトのままになる
uGUIのCanvas Groupを使って透過処理をしたり、操作を制限する
自作のコンフィグ画面に必要なもの
uGUIでトグルなボタンを作る
Easy Save2 を使ってみる
csv読み込んで ローカライズ
LoadLevelAdditive で共通シーンを加算
画面全体に色をかける
Any State でどこからでも遷移できるようにする
iTween のStop ではまる
sprite の multiple で 境界がおかしくなる
2D画面に線を引く Line Renderer
Renderer の Materials を スクリプトから設定する
背景をスクロールさせる