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

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

新規登録して質問してみよう
ただいま回答率
85.50%
Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Q&A

解決済

1回答

1132閲覧

Unity3D、インデックスが範囲外というエラーについて

KarasuLoid

総合スコア1

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

0グッド

0クリップ

投稿2022/09/15 16:29

現在行っていること、行き詰った原因

Unity3Dで音ゲーを制作しております。
曲の再生、ノーツの生成、判定等うまくいったのですが
再生終了時最後のノーツをたたくタイミングで次のようなエラーが出てしまいます

ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index System.Collections.Generic.List`1[T].get_Item (System.Int32 index) (at <6073cf49ed704e958b8a66d540dea948>:0) Judge.Update () (at Assets/Script/Judge.cs:61) //翻訳版// ArgumentOutOfRangeException: インデックスが範囲外でした。 負ではなく、コレクションのサイズより小さくなければなりません。 パラメータ名:インデックス System.Collections.Generic.List`1[T].get_Item (System.Int32 インデックス) (<6073cf49ed704e958b8a66d540dea948>:0) Judge.Update () (Assets/Script/Judge.cs:61)

次のものが発生しているソースコードです。
61行目でエラー発生が発生しています。

Judge

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class Judge : MonoBehaviour 6{ 7 //変数の宣言 8 [SerializeField] private GameObject[] MessageObj;//プレイヤーに判定を伝えるゲームオブジェクト 9 [SerializeField] NotesManager notesManager;//スクリプト「notesManager」を入れる変数 10 11 //ヒットサウンド 12 [SerializeField] private AudioSource hitsound; 13 14 [SerializeField] private AudioClip perfect; 15 [SerializeField] private AudioClip great; 16 [SerializeField] private AudioClip good; 17 18 void Update() 19 { 20 21 /*メモ 22 * Time.time : 再生開始から経過した時間 23 * NotesTime[?] : 判定線と重なるタイミング 24 */ 25 26 if(GManager.instance.Start) 27 { 28 if (Input.GetKeyDown(KeyCode.D))//〇キーが押されたとき 29 { 30 if (notesManager.LaneNum[0] == 0)//押されたボタンはレーンの番号とあっているか? 31 { 32 Judgement(GetABS(Time.time - (notesManager.NotesTime[0] + GManager.instance.StartTime))); 33 /* 34 本来ノーツをたたく場所と実際にたたいた場所がどれくらいずれているかを求め、 35 その絶対値をJudgement関数に送る 36 */ 37 } 38 } 39 if (Input.GetKeyDown(KeyCode.F)) 40 { 41 if (notesManager.LaneNum[0] == 1) 42 { 43 Judgement(GetABS(Time.time - (notesManager.NotesTime[0] + GManager.instance.StartTime))); 44 } 45 } 46 if (Input.GetKeyDown(KeyCode.J)) 47 { 48 if (notesManager.LaneNum[0] == 2) 49 { 50 Judgement(GetABS(Time.time - (notesManager.NotesTime[0] + GManager.instance.StartTime))); 51 } 52 } 53 if (Input.GetKeyDown(KeyCode.K)) 54 { 55 if (notesManager.LaneNum[0] == 3) 56 { 57 Judgement(GetABS(Time.time - (notesManager.NotesTime[0] + GManager.instance.StartTime))); 58 } 59 } 60 //ノーツがたたけなかった場合Miss 61 if (Time.time > notesManager.NotesTime[0] + 0.2f + GManager.instance.StartTime) ←エラー発生個所 62 { 63 64 GManager.instance.miss++; 65 GManager.instance.combo = 0; 66 67 message(3); 68 deleteData(); 69 } 70 } 71 } 72 73 //ノーツをたたいた場所と本来たたくべき場所のずれを判定する 74 void Judgement(float timeLag) 75 { 76 //誤差が0.1秒以下Perfect 77 if (timeLag <= 0.10) 78 { 79 //hitsound.PlayOneShot(perfect); 80 81 GManager.instance.perfect++; 82 GManager.instance.combo++; 83 84 message(0); 85 deleteData(); 86 } 87 else 88 { 89 //誤差が0.15秒以下Great 90 if (timeLag <= 0.15) 91 { 92 //hitsound.PlayOneShot(great); 93 94 GManager.instance.great++; 95 GManager.instance.combo++; 96 97 message(1); 98 deleteData(); 99 } 100 else 101 { 102 //誤差が0.2秒以下Good 103 if (timeLag <= 0.20) 104 { 105 //hitsound.PlayOneShot(good); 106 107 GManager.instance.good++; 108 GManager.instance.combo++; 109 110 message(2); 111 deleteData(); 112 } 113 } 114 } 115 } 116 117 //関数:与えられた引数の絶対値を返す 118 float GetABS(float num) 119 { 120 if (num >= 0) 121 { 122 return num; 123 } 124 else 125 { 126 return -num; 127 } 128 } 129 130 //関数:たたいたノーツの情報をリストから削除 131 void deleteData() 132 { 133 notesManager.NotesTime.RemoveAt(0); 134 notesManager.LaneNum.RemoveAt(0); 135 notesManager.NoteType.RemoveAt(0); 136 } 137 138 //関数:判定を表示する 139 void message(int judge) 140 { 141 Instantiate(MessageObj[judge], new Vector3(notesManager.LaneNum[0] - 1.5f, 0.76f, 0.15f), Quaternion.Euler(45, 0, 0)); 142 } 143}

上記ソースに関係の深い、プロジェクトを構成しているソース

GManager

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class GManager : MonoBehaviour 6{ 7 public static GManager instance = null; 8 9 public int songID; 10 public float noteSpeed; 11 12 public bool Start; 13 public float StartTime; //Spaceが押された時間を記録 14 15 //スコア関連 16 public int combo = 0; 17 public int score = 0; 18 19 //ジャッジ記録 20 public int perfect = 0; 21 public int great = 0; 22 public int good = 0; 23 public int bad = 0; 24 public int miss = 0; 25 26 public void Awake() 27 { 28 //シーン内にこのオブジェクトが一つしかないようにする 29 if(instance == null) 30 { 31 instance = this; 32 DontDestroyOnLoad(this.gameObject); 33 } 34 else 35 { 36 Destroy(this.gameObject); 37 } 38 } 39 40 // Update is called once per frame 41 void Update() 42 { 43 44 } 45}

NotesManager

1using System; 2using System.Collections.Generic; 3using UnityEngine; 4 5//Jsonを読み込むためのクラス 6[Serializable] 7public class Data 8{ 9 public string name; 10 public int maxBlock; 11 public int BPM; 12 public int offset; 13 public Note[] notes; 14 15} 16[Serializable] 17public class Note 18{ 19 public int type; 20 public int num; 21 public int block; 22 public int LPB; 23} 24 25public class NotesManager : MonoBehaviour 26{ 27 public int noteNum; //ノーツ数 28 private string songName; //曲名 29 30 public List<int> LaneNum = new List<int>(); //どこに落ちてくるか 31 public List<int> NoteType = new List<int>(); //ノーツの種類 32 public List<float> NotesTime = new List<float>(); //判定戦と重なるタイミング 33 public List<GameObject> NotesObj = new List<GameObject>(); //オブジェクト 34 35 [SerializeField] private float NotesSpeed; //ノーツスピード 36 [SerializeField] GameObject noteObj; //ノーツオブジェクト 37 38 void OnEnable() 39 { 40 noteNum = 0; 41 songName = "ENGRAM"; //プレイする曲を呼び出す 42 Load(songName); 43 } 44 45 private void Load(string SongName) 46 { 47 //Jsonを読み込む 48 string inputString = Resources.Load<TextAsset>(SongName).ToString(); 49 Data inputJson = JsonUtility.FromJson<Data>(inputString); 50 51 //ノーツ数設定 52 noteNum = inputJson.notes.Length; 53 54 for (int i = 0; i < inputJson.notes.Length; i++) 55 { 56 //ノーツの流れてくる時間を計測 57 float interval = 60 / (inputJson.BPM * (float)inputJson.notes[i].LPB); 58 float beatSec = interval * (float)inputJson.notes[i].LPB; 59 float time = (beatSec * inputJson.notes[i].num / (float)inputJson.notes[i].LPB) + inputJson.offset * 0.01f; 60 61 //リストにタイミング、流れてくるレーン、何ノーツか、といった情報を入れていく 62 NotesTime.Add(time); 63 LaneNum.Add(inputJson.notes[i].block); 64 NoteType.Add(inputJson.notes[i].type); 65 66 //ノーツ生成位置計算 67 float z = NotesTime[i] * NotesSpeed; 68 NotesObj.Add(Instantiate(noteObj, new Vector3(inputJson.notes[i].block - 1.5f, 0.3f, z), Quaternion.identity)); 69 } 70 } 71}

試したこと

すでに空になったリストをさらに消そうとしているのかと思い
「Judge」ソースの「deletData」の削除命令部分をコメントにしてみたりなど。

自分一人では解決できそうになく、質問させていただきました。
どうか力を貸していただけるとありがたいです。

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

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

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

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

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

guest

回答1

0

ベストアンサー

最後のノーツを叩いた時点でNotestimeの要素がなくなってしまい、次のupdateのタイミングで存在しないインデックスを参照しようとしてしまうのではないのでしょうか。

例外を無視するとか、曲の長さより長い数をリストの最後に一個置いてみるとかどうですか

投稿2022/09/15 18:13

編集2022/09/15 18:29
Sobasenbei

総合スコア132

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問