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

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

新規登録して質問してみよう
ただいま回答率
85.30%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

2回答

3639閲覧

【UniRx】ボタンにOnClickAsObservable().Subscribe() で処理を登録するとき、for文でまとめて登録しようとするとうまくいかない

honjoriki

総合スコア81

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2022/03/02 16:50

編集2022/03/02 16:52

発生する現象

ボタンにOnClickAsObservable().Subscribe()で処理を登録するとき、for文でまとめて登録しようとすると、うまくいかない現象が発生しています。
これに関して解決方法などありますでしょうか。

ソースコード

ボタンがあるUI用クラス

C#

1using UnityEngine; 2using UnityEngine.UI; 3using UniRx; 4using System; 5 6public class ButtonUI : MonoBehaviour 7{ 8 [SerializeField] private Button[] ChoiceButtons; 9 10 /// <summary> 11 /// 指定したインデックスのボタンをクリックしたときの動作を登録 12 /// </summary> 13 /// <param name="index"></param> 14 /// <param name="buttonAction"></param> 15 public void SetButtonClickAction(int index, Action buttonAction) 16 { 17 ChoiceButtons[index].OnClickAsObservable().Subscribe(_ => buttonAction()); 18 } 19}

ボタンを押したときの処理を登録するクラス

C#

1using UnityEngine; 2using System; 3 4public class ChoiceEvent 5{ 6 private ButtonUI ui; 7 8 /// <summary> 9 /// 選択肢イベントでボタンを押下したときの処理を追加 10 /// </summary> 11 private void SetButtonAction() 12 { 13 ui = GameObject.FindObjectOfType<ButtonUI>(); 14 // なぜかfor文を使用するとボタンのイベント登録がミスる 15 // 現状ボタンの数は4つなので、こう書けば一応動作はする模様 16 ui.SetButtonClickAction(0, () => 17 { 18 Debug.Log($"選択肢{0}を押下"); 19 }); 20 21 ui.SetButtonClickAction(1, () => 22 { 23 Debug.Log($"選択肢{1}を押下"); 24 }); 25 26 ui.SetButtonClickAction(2, () => 27 { 28 Debug.Log($"選択肢{2}を押下"); 29 }); 30 31 ui.SetButtonClickAction(3, () => 32 { 33 Debug.Log($"選択肢{3}を押下"); 34 }); 35 } 36} 37

Unity バージョン

  • 2021.2.11

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ozwk

2022/03/03 01:50

「うまくいかない」とはどうなるのでしょう?
guest

回答2

0

ベストアンサー

C#

1ui.SetButtonClickAction(i, () => 2 { 3 var x = i; 4 Debug.Log($"選択肢{x}を押下"); 5 });

投稿2022/03/03 01:51

ozwk

総合スコア13553

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

C#

1/// <summary> 2/// 選択肢イベントでボタンを押下したときの処理を追加 3/// </summary> 4private void SetButtonAction() 5{ 6 ui = GameObject.FindObjectOfType<ButtonUI>(); 7 for(int i = 0; i < 4; i++) 8 { 9 // iを一旦別の変数に格納すると、正常に動作する 10 var count = i; 11 ui.SetButtonClickAction(count, () => 12 { 13 Debug.Log($"選択肢{count}を押下"); 14 }); 15 } 16}

このように、indexを一旦別の変数に格納すると正常に動作する模様です。
参考:https://qiita.com/D4ik1/items/21db399d075e7269b0da

C# だけでなく、よく発生する事象とのことで、そういうものとして割り切るしかないようです。

投稿2022/03/03 03:43

honjoriki

総合スコア81

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

bboydaisuke

2022/03/03 04:05

それ、付いている回答と同じことを言ってますよ。なので「自己解決」じゃないのでは? > よく発生する事象 単純に文法を間違えてしまったということですよね。ラムダ式の仮引数名に、既に存在している変数名を割り当ててしまっていた、つまり変数宣言が重複していた、ということですよね。
honjoriki

2022/03/03 05:17

すいません、調べて記入しているうちに他の方も回答してくださっていたようです。
ozwk

2022/03/03 06:11

> 単純に文法を間違えてしまったということですよね。ラムダ式の仮引数名に、既に存在している変数名を割り当ててしまっていた、つまり変数宣言が重複していた、ということですよね。 違いますよ。4つのラムダ式がすべて同じ変数 i をキャプチャしていたため 4つすべてが同じ出力になってしまっていたのです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.30%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問