2017-09-29 6 views
0

UnityでCoroutineを使用しているときに奇妙な問題が発生しました。変更する前に、私のコードは次のとおりです。Unity:ArgumentException:値が期待した範囲内に収まらない

IEnumerator Destory() 
{ 
    yield return new WaitForSeconds(destoryDelay); 
    yield return StartCoroutine(Timer.Start(0.5f, false, gameManager.EnableBtnSummon)); 
    GameObject.Destroy(this.gameObject); 
} 

Time.Start()は自分自身によって書かれ、遅延呼び出しのために使用されるユーティリティです。 Time.Start()WaitForSeconds()が含まれるため、以下のように私は上記のコードを変更することを決め

public static IEnumerator Start(float duration, bool repeat, Action callback) 
{ 
    do 
    { 
     yield return new WaitForSeconds(duration);     
     if (callback != null) 
      callback(); 
    } while (repeat); 
} 

ので:

残念ながら
IEnumerator Destory() 
{ 
    //yield return new WaitForSeconds(destoryDelay); 
    yield return StartCoroutine(Timer.Start(destoryDelay+0.5f, false, gameManager.EnableBtnSummon)); 
    GameObject.Destroy(this.gameObject); 
} 

は、コンソールにはエラーをスロー:

ArgumentException: Value does not fall within the expected range.

gameManager.EnableBtnSummonを単にアクション処理でありますゲームロジック。デバッグ後、私はこの関数を実行する前にエラーが発生したことを確認します。しかし、私はより多くの手がかりについてそれを示します。

public void EnableBtnSummon() 
{ 
    //will not reach this! 
    print("Enable Button Summon"); 
    //if detecting monster, change relative sprite of monster medal 
    if (currentMonsterIndex != -1) 
    { 
     Image captureMonsterSprite = monsterMedalList.transform.GetChild(currentMonsterIndex).GetComponent<Image>(); 
     captureMonsterSprite.sprite = mosnterExplicitMedalList[currentMonsterIndex]; 

     Image gameOverMonsterSprite = gameOverMonsterList.transform.GetChild(currentMonsterIndex).GetComponent<Image>(); 
     gameOverMonsterSprite.sprite = mosnterExplicitMedalList[currentMonsterIndex]; 

     currentMonsterIndex = -1; 
     captureMonsterCount++; 
    } 

    if (captureMonsterCount == monsterIndexDictionary.Count) return; 

    var summonAnimator = btnSummon.GetComponent<Animator>(); 
    summonAnimator.SetBool("isSearch", false); 

    btnSummon.enabled = true; 
    btnExit.enabled = true; 

    fogParticleSystem.Play(); 
} 

私はそれを理解できません。 THX ...

+1

あなたの質問にコードを書式設定してみてください。また、このエラーはどこにありますか? 'gameManager'はどのように宣言されていますか? – Programmer

+0

引数を分離して問題の原因を調べることができればうれしいでしょう。それぞれをローカル変数として宣言し、 'Debug.Log'を呼び出して値を送信してから送信してください。 – MrDos

+0

コメントと修正をいただきありがとうございます。StackOverflowを初めて使用したので、あいまいになる可能性があります。 –

答えて

1

例外:

ArgumentException: Value does not fall within the expected range.

は、このコード行に起こっている:

yield return StartCoroutine(MoveTowards.Start(destoryDelay + 0.5f, false, gameManager.EnableBtnSummon)); 

これは質問のタイトルが言うようにStartCoroutineとは何の関係もありません。問題の原因はコルーチン関数MoveTowards.Startです。それに渡される3番目のパラメータ(Action callback)が問題です。

nullMoveTowards.Start関数の3番目のパラメータに渡すことが問題です。 gameManager.EnableBtnSummonをその3番目のパラメータに渡すので、これはgameManager変数がnullであることを意味します。

これは、コード行の前にDebug.Log(gameManager)を追加することで確認できます。出力は「コンソール」タブで「null」にする必要があります。

FIX:GameObjectあなたGameManagerスクリプトは "ManagerObj" は、その後gameManager変数を初期化するには、以下の簡単なコードを使用するように取り付けられている。

名:

gameManager変数を初期化します。

GameManager gameManager; 

void Awake() 
{ 
    gameManager = GameObject.Find("ManagerObj").GetComponent<GameManager>(); 
} 

注:

Unityがすでに存在していると、何か他のものにあなたのStart機能の名前を変更し、 "スタート" と "アウェイク" という名前の関数に建てられました。名前を別のものに変更する必要がありますが、これは問題ではありません。

+0

あなたはそうです、この問題は修正されました!私は 'Start()'で 'gameManager'を初期化していましたので、Coroutine' Destroy() 'が起動すると初期化されません。そのため、最初の 'WaitForSeconds'が削除されたときに例外が発生しました。代わりに、 'Awake()'の 'gameManager'を初期化する方が良いです。 –

+0

私はお手伝いできました。 'Destroy'という名前のUnity関数があるので、' Destroy'関数の名前を変更する必要があります。 – Programmer

関連する問題