🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C#

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

Unity

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

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

4回答

2795閲覧

実行した後、暫くしてインデックスが配列の境界外といった内容のエラーが表示される。

evolsnake

総合スコア15

C#

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

Unity

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

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2019/10/23 04:34

編集2019/10/23 04:36

シーン上のタグが付いたゲームオブジェクトを取得し、配列に入れた後、
変数にランダムにオブジェクトの座標を代入し、その座標のオブジェクトを削除するスクリプトを書きました。
実行して最初の内は問題無いのですが、
シーン上のオブジェクトの数が少なくなってくると下記のエラーが表示されます。
IndexOutOfRangeException: Index was outside the bounds of the array.
BallGun.PosT () (at Assets/main/Script/BallGun.cs:150)
コードはこちらになります。

C#

1 2 public void PosT() 3 { 4 if (H_m == false) 5 { 6 return; 7 } 8 9 TargetObject = GameObject.FindGameObjectsWithTag("Target"); 10 Debug.Log("Target数;" + TargetObject.Length); 11 if (TargetObject.Length == 0) 12 { 13 GameResult.clear = true; 14 15 script.GetComponent<GameResult>().Owari(); 16 } 17 else if (TargetObject == null) 18 { 19 Debug.Log("無い"); 20 } 21 int number = Random.Range(1, TargetObject.Length); 22 a_p = TargetObject[number].transform.position; 23 24 } 25

どうかお知恵をかしていただけないでしょうか?

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

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

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

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

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

guest

回答4

0

こんにちは。

ぱっと見ですが、Random.Range(1, TargetObject.Length); がおかしいです。

この定義では Range は 1 以上 Length 未満の値を返しますが、配列の index は 0 からです。
ここで、TargetObject.Length1 になった場合を考えると、
Random.Range(1, 1) == 1 となり、
TargetObject は 1 件、つまり [0] のみが存在するところに 1 でアクセスしており、IndexOutOfRangeException となります。

つまり、TargetObject が 2 件以上ある場合はエラーは発生しませんが、条件が常に 1 以上 Length 未満 なので、最初の一つ (index == 0) が決して選択されない状態になっています。

投稿2019/10/23 04:50

tamoto

総合スコア4243

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

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

0

ベストアンサー

C#の配列は最初の要素は1ではなく0です。

また、Random.Rangeには

max と min が等しければ、min が返されます。

と書かれています。

つまり、TargetObject.Lengthが1のとき、numberには1が保持されます。
このとき、TargetObject[0]にはアクセスできますが、TargetObject[1]にはアクセスできません。

掲示されたコードはTargetObject[1]にアクセスしているためIndexOutOfRangeExceptionの例外が発生しています。
乱数の最小値を1ではなく0を返すように修正してください。

diff

1- int number = Random.Range(1, TargetObject.Length); 2+ int number = Random.Range(0, TargetObject.Length);

投稿2019/10/23 04:48

編集2019/10/23 04:55
BluOxy

総合スコア2663

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

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

sakura_hana

2019/10/23 04:54 編集

この修正を加えた場合でも配列要素数が0の場合に「TargetObject[0]」にアクセスしようとするので、if分岐の追加が必要かと思います。
tamoto

2019/10/23 05:00 編集

要素数が 0 の場合の早期脱出が既に書かれているため問題ないと思います。直後に全く意味をなさない is null とかもありますが…… >>> と思ったら、特に中で脱出してませんでしたね。質問中で省略しているわけでは……どうなんでしょう。
BluOxy

2019/10/23 04:57

sakura_hanaさん、補足ありがとうございます。 > evolsnakeさん sakura_hanaさんの補足についてもIndexOutOfRangeExceptionを発生させないためのポイントになるので考慮してください。
sakura_hana

2019/10/23 05:04

> tamotoさん 変数代入してメソッド呼んでるだけなんで脱出してないですね。(OwariメソッドからPosTメソッドを終了させるのは多分出来ないはず、出来てもエラーか警告起こりそう) if(TargetObject == null) が全く無意味なのはその通りです。
sakura_hana

2019/10/23 05:05

(すいません被りました) if (TargetObject.Length == 0) 内の最後に return; 追加 int number = Random.Range(1, TargetObject.Length);の1を0に変更 で動くと思います。
BluOxy

2019/10/23 05:07

ですね。returnするなどして、TargetObject.Lengthが0のときに要素へアクセスしないようロジックを直せば良さそうです。
guest

0

Random-Range - Unity スクリプトリファレンス

max と min が等しければ、min が返されます。

これにより、次のコードで TargetObject.Length が 1 の時、number は 1 になります。

int number = Random.Range(1, TargetObject.Length);

しかし、TargetObject.Length が 1 の時 TargetObject[1] は存在しないので、次の行で例外が発生します。

a_p = TargetObject[number].transform.position;

投稿2019/10/23 04:53

Zuishin

総合スコア28669

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

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

0

C#

1 int number = Random.Range(0, TargetObject.Length-1); 2

Random.Rangeは第2引数の値までの数値を返します
配列のインデックスの最大値は配列の要素数-1なので、最大値がランダムで生成されたときに例外がおきてます
なのでランダム値生成は配列の要素数-1までにしなければなりません

投稿2019/10/23 04:55

shirokuma4690

総合スコア154

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

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

BluOxy

2019/10/23 05:00

リファレンスには > min (この値を含む) と max (この値を含まない) の範囲のランダムな整数を返します と書かれているので、Length-1の考慮は必要なさそうに思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問