Unityで行き詰ったので教えてください。
趣味でRPG作ってます。アイテムドロップ処理を考えてみましたが、どうもうまくいきません。
コルーチンAのwhile内でコルーチンBを待ち、コルーチンBではwhileでboolの判定をしています。
コルーチンBのwhileが抜ける際、フリーズします。
なぜでしょうか?
C#
1public static bool click = false; 2public static string[] strArray = new string[]{"text", "t", ""}; 3~~~ 4public static IEnumerator CoroutineA(MonoBehaviour monoBehaviour) 5{ 6 ~~~ 7 Debug.Log("敵を倒した"); //出力される 8 yield return monoBehaviour.StartCoroutine(CoroutineB()); 9 Debug.Log("check 0"); //出力される 10 11 str = ""; 12 while(str == "") 13 { 14 int i = Random.Range(0, strArray.Length); 15 str = strArray[i]; 16 if(str != "") 17 { 18 Debug.Log("str:あたり"); //出力される 19 yield return monoBehaviour.StartCoroutine(CoroutineB()); 20 Debug.Log("check 3"); //出力されない 21 break; 22 } 23 else 24 { 25 Debug.Log("str:はずれ"); 26 } 27 yield return null; 28 } 29} 30 31//メッセージスキップ待機 32public static IEnumerator CoroutineB() 33{ 34 click = false; 35 while(!click) 36 { 37 Debug.Log("check 1"); //出力される 38 yield return null; 39 } 40 Debug.Log("check 2"); //フリーズする 41 yield break; 42} 43 44//ボタンにアタッチしているメソッド(メッセージスキップボタン) 45public void ButtonClick() 46{ 47 click = true; 48} 49
試したこと
continueを使い、基本的にwhileを出るようにしましたが、フリーズしてしまいました。
C#
1~~~ 2 str = ""; 3 while(str == "") 4 { 5 int i = Random.Range(0, strArray.Length); 6 str = strArray[i]; 7 if(str != "") 8 { 9 Debug.Log("str:あたり"); //出力される 10 yield return monoBehaviour.StartCoroutine(CoroutineB()); 11 Debug.Log("check 3"); //出力されない 12 break; 13 } 14 else 15 { 16 Debug.Log("str:はずれ"); 17 if(条件:特殊アイテム装備){ continue; } 18 } 19 yield return null; 20 break; 21 } 22} 23 24//メッセージスキップ待機 25public static IEnumerator CoroutineB() 26{ 27 click = false; 28 while(!click) 29 { 30 Debug.Log("check 1"); //出力される 31 yield return null; 32 if(!click){ continue; } 33 break; 34 } 35 Debug.Log("check 2"); //フリーズする 36 yield break; 37} 38 39//ボタンにアタッチしているメソッド(メッセージスキップボタン) 40public void ButtonClick() 41{ 42 click = true; 43}
フリーズするコルーチンBを外しましたが、フリーズしてしまいました。
C#
1~~~ 2 str = ""; 3 while(str == "") 4 { 5 int i = Random.Range(0, strArray.Length); 6 str = strArray[i]; 7 if(str != "") 8 { 9 Debug.Log("str:あたり"); //出力されず、フリーズする 10 //yield return monoBehaviour.StartCoroutine(CoroutineB()); 11 Debug.Log("check 3"); //出力されない 12 break; 13 } 14 else 15 { 16 Debug.Log("str:はずれ"); 17 } 18 yield return null; 19 } 20} 21~~~
模擬的に別のwhileループを作りましたが、模擬ループでもループを出る際にフリーズしました。
C#
1~~~ 2 int w = 0; 3 while(true) 4 { 5 Debug.Log("check while: " + w); //1秒毎に出力され、"check while: 4" を出力後、フリーズする。 6 yield return new WaitForSeconds(1f); 7 w++; 8 if(w < 5){ continue; } 9 break; 10 } 11 12 str = ""; 13 while(str == "") 14 { 15 int i = Random.Range(0, strArray.Length); 16 str = strArray[i]; 17 if(str != "") 18 { 19 Debug.Log("str:あたり"); //出力されず、フリーズする 20 //yield return monoBehaviour.StartCoroutine(CoroutineB()); 21 Debug.Log("check 3"); //出力されない 22 break; 23 } 24 else 25 { 26 Debug.Log("str:はずれ"); 27 } 28 yield return null; 29 } 30} 31~~~
補足情報(FW/ツールのバージョンなど)
Unity 2019.1.0f2
質疑への回答
Q1.
CoroutineAを開始するときに渡しているmonoBehaviourに対して、どこかでDestroyを行っているスクリプトはないでしょうか?
A1.
確認しましたが、そのようなスクリプトはありませんでした。
エンカウント時に当該のmonoBehaviourを付与しているボタンを初期化のため破棄をしていますが、コルーチンAを開始するためのボタンであり、処理の途中で破棄するようにはしていません。
Q2.
「フリーズする」とはどのような状態のこと言うか。
A2.
Unityの強制終了が必要となるフリーズです。
"str:あたり"が1回出力され、その後、メッセージスキップボタンを押すまで"check 1"が出力され続けますが、ここまでは作った通り動いています。ボタンを押したとき、"check 2"は出力されず、Unityのプレイボタンを押そうとしても押せない状態に陥ります。

回答2件
あなたの回答
tips
プレビュー