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

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

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

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

button

HTMLで用いる<button>タグです。

Unity

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

Q&A

解決済

1回答

270閲覧

UnityでのC#を使ったボタン判定

beginner_01

総合スコア22

C#

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

button

HTMLで用いる<button>タグです。

Unity

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

0グッド

0クリップ

投稿2018/09/30 07:42

前提・実現したいこと

ボタンを押したら画像が変わりトランプの柄が表示されるようにしたい

for (var i = 0; i < 13; i++) { D_[i].onClick.AddListener(delegate { D[i].sprite = Deck[i]; }); }

を追加することでD0からD12(ダイヤの1からダイヤの13)までのトランプのボタンを作れると思ったのですが
うまくいきませんでした

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

Array index is out of range

該当のソースコード

using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using System; using System.Linq; public class Sinken : MonoBehaviour { public Sprite TBack; public Sprite[] TArray = new Sprite[52]; Image Back; UnityEngine.Sprite[] Deck = new UnityEngine.Sprite[52]; UnityEngine.UI.Image[] D = new UnityEngine.UI.Image[13]; UnityEngine.UI.Button[] D_ = new UnityEngine.UI.Button[13]; UnityEngine.UI.Image[] K = new UnityEngine.UI.Image[13]; UnityEngine.UI.Button[] K_ = new UnityEngine.UI.Button[13]; UnityEngine.UI.Image[] H = new UnityEngine.UI.Image[13]; UnityEngine.UI.Button[] H_ = new UnityEngine.UI.Button[13]; UnityEngine.UI.Image[] S = new UnityEngine.UI.Image[13]; UnityEngine.UI.Button[] S_ = new UnityEngine.UI.Button[13]; // Use this for initialization void Start() { for (var i = 0; i < 13; i++) { D[i] = GameObject.Find("D"+(i+1)).GetComponent<Image>(); D_[i] = GameObject.Find("D" + (i+1)).GetComponent<Button>(); K[i] = GameObject.Find("K" + (i+1)).GetComponent<Image>(); K_[i] = GameObject.Find("K" + (i+1)).GetComponent<Button>(); H[i] = GameObject.Find("H" + (i+1)).GetComponent<Image>(); H_[i] = GameObject.Find("H" + (i+1)).GetComponent<Button>(); S[i] = GameObject.Find("S" + (i+1)).GetComponent<Image>(); S_[i] = GameObject.Find("S" + (i+1)).GetComponent<Button>(); } for (var i = 0; i < TArray.Length; i++) { Deck[i] = TArray[i]; } for (var i = 0; i < 13; i++) { D_[i].onClick.AddListener(delegate { D[i].sprite = Deck[i]; }); } }

試したこと

forを消して

D_[0].onClick.AddListener(delegate { D[0].sprite = Deck[0]; });

のように0~12まで試したときはきちんと動いてくれました。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

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

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

guest

回答1

0

ベストアンサー

こんにちは。

質問のコードでは、匿名メソッド中で変数iのキャプチャが発生しているため、匿名メソッド内のiの値がfor文により書き換えられてしまっており、onClickの実行時にD[13]にアクセスしているためIndexOutOfRangeExceptionが発生します。
キャプチャはそう簡単に理解できる概念ではないため、説明するのが難しいですが、とりあえずは以下のように書き換えることでエラーを回避できるはずです。

csharp

1 for (var i = 0; i < 13; i++) 2 { 3 var x = i; // for文のスコープ内で変数を宣言 4 D_[x].onClick.AddListener(delegate 5 { 6 D[x].sprite = Deck[x]; // xを利用する 7 }); 8 }

キャプチャについて覚えるには、まずはここを読んで概要を理解すると良いです。
ローカル関数と匿名関数 - C# によるプログラミング入門 | ++C++; // 未確認飛行 C

投稿2018/09/30 12:41

tamoto

総合スコア4105

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

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

beginner_01

2018/10/01 12:57

解決しました!ありがとうございます キャプチャというのは初めてしりましたじっくり理解していきたいとおもいます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問