2016-04-27 4 views
2

badGuyのゲームオブジェクトを右に移動させるコルーチンと左に移動するコルーチンを作成しました(下のコードを参照してください)。条件が偽であるときにコルーチンから別のコルーチンに変更する方法

IEnumerator moveBadGuyLeft (Transform fromPosition, Vector3 toPosition, float duration, int newIndex) { 

    while (emptyPos.Contains(badGuyPos[newIndex])) { //how to switch to moveBadGuyRight when this condition is false 

     emptyPos.Add(badGuyPos[newIndex + 1]); 
     filledPos.Remove(badGuyPos[newIndex + 1]); 
       float counter = 0; 
       Vector3 startPos = fromPosition.position; 

       while (counter < duration) 
       {      
        counter += Time.deltaTime; 
        fromPosition.position = Vector3.Lerp(startPos, toPosition, counter/duration); 
        yield return null; 

       } 

     emptyPos.Remove(badGuyPos[newIndex]); 
     filledPos.Add(badGuyPos[newIndex]); 

      if (newIndex > 0) { 
       newIndex--; 
       } 

     startPos = toPosition; 
     toPosition = new Vector3 (badGuyPos[newIndex], startPos.y, startPos.z); 

     int waitInterval = Random.Range(3, 5); 
     yield return new WaitForSeconds(waitInterval); 
      } 
} 


IEnumerator moveBadGuyRight (Transform fromPosition, Vector3 toPosition, float duration, int newIndex) { 
    while (emptyPos.Contains(badGuyPos[newIndex])) { //how to switch to moveBadGuyLeft when this condition is false 

     emptyPos.Add(badGuyPos[newIndex - 1]); 
     filledPos.Remove(badGuyPos[newIndex - 1]); 
       float counter = 0; 
       Vector3 startPos = fromPosition.position; 

       while (counter < duration) 
       {      
        counter += Time.deltaTime; 
        fromPosition.position = Vector3.Lerp(startPos, toPosition, counter/duration); 
        yield return null; 

       } 
     emptyPos.Remove(badGuyPos[newIndex]); 
     filledPos.Add(badGuyPos[newIndex]); 

     if (newIndex > 0) { 
      newIndex++; 
       } 

     startPos = toPosition; 
     toPosition = new Vector3 (badGuyPos[newIndex], startPos.y, startPos.z); 

     int waitInterval = Random.Range(3, 5); 
     yield return new WaitForSeconds(waitInterval); 
      } 
} 

私は、彼らはその後、彼らは左と右の間でトグル、そうで満たされた位置を満たすために、右までそれらを移動満たされた位置を満たすまで、私のBadGuyのオブジェクトが左に移動しようとしています。私は私の条件

while (emptyPos.Contains(badGuyPos[newIndex])) 

がfalseの場合、私は1つのコルーチンから他へ、またはその逆に変更する必要があることを知っています。どのように私はコルーチン間でこの変更を実装できますか?私は下のStartメソッドでコルーチン呼び出していますかを確認してください:

for (int i = 0; i < badGuys.Count; i++) { 
     if (badGuys [i].getBlockType() == BadGuySetup.BadGuyType.moving) { 
      int indexInBadGuyPos = badGuyPos.IndexOf(badGuys[i].getBadGuyGameObject().transform.position.x); 
      Vector3 targetPos = new Vector3(badGuyPos[indexInBadGuyPos - 1], badGuys[i]. getBadGuyGameObject().transform.position.y, 0.0f); 
      StartCoroutine(moveBadGuyLeft(badGuys [i]. getBadGuyGameObject().transform, targetPos, 1.0f, indexInBadGuyPos - 1)); 

    } 
} 

UPDATE

を私はmoveBadGuyLeftmoveBadGuyRightif (newIndex) > 0条件に次を追加しました:moveBadGuyLeft

  if (newIndex > 0) { 

        newIndex--; 

      if (!emptyPos.Contains(badGuyPos[newIndex])) { 
       isMovingLeft = false; 
       badGuyDestPos = new Vector3(badGuyPos[newIndex + 2], startPos.y, startPos.z); 
       badGuyNewIndex = newIndex + 2; 
       break; 
      } 
     } 

moveBadGuyRight

if (newIndex > 0) { 

        newIndex++; 

      if (!emptyPos.Contains(badGuyPos[newIndex])) { 
       isMovingLeft = false; 
       badGuyDestPos = new Vector3(badGuyPos[newIndex - 2], startPos.y, startPos.z); 
       badGuyNewIndex = newIndex - 2; 
       break; 
      } 
     } 

は、その後私は2つのコルーチンの間で変更することが想定されている別のコルーチンを作成しました:

for (int i = 0; i < badGuys.Count; i++) { 
    if (badGuys [i].getBlockType() == BadGuySetup.BadGuyType.moving) { 
     int indexInBadGuyPos = badGuyPos.IndexOf(badGuys[i].getBadGuyGameObject().transform.position.x); 
     Vector3 targetPos = new Vector3(badGuyPos[indexInBadGuyPos - 1], badGuys[i]. getBadGuyGameObject().transform.position.y, 0.0f); 

     badGuyDestPos = targetPos; 
     badGuyMoveDuration = 1.0f; 
     badGuyNewIndex = indexInBadGuyPos - 1; 
     StartCoroutine(movingBadGuys(badGuys [i]. getBadGuyGameObject().transform, badGuyDestPos, badGuyMoveDuration, badGuyNewIndex)); 

    } 
} 

しかし、これを:

IEnumerator movingBadGuys(Transform fromPosition, Vector3 toPosition, float duration, int newIndex) { 
    if(isMovingLeft){ 
     yield return StartCoroutine (moveBadGuyLeft(fromPosition, toPosition, duration, newIndex)); 
    } 
    else if(!isMovingLeft){ 
     yield return StartCoroutine (moveBadGuyRight(fromPosition, toPosition, duration, newIndex)); 
    } 
} 

最後に、私はbadguysをループし、それらを動かす更新します変更は機能していません。私は常に2つのbadGuysだけでテストしています。悪いGuysは常に左に移動し始め、左に1回移動して残りの空きポジションが残っていますが、左に移動します。

答えて

0

残念ながら、これはコルーチンを使う良い方法ではないと思います。より良いアプローチは、単一のコルーチン「moveBadGuy」を持って、BadGuyオブジェクトにmoveメソッドとある内部状態変数を持たせることです。例えば。

class BadGuy{ 
    bool moveLeft = false; 

    public void move(){ 
     if(moveLeft){ 
      //move the guy left 

     }else{ 
      //move right 

     } 
    }  
} 

次に、あなたのコルーチンは、単一のコルーチンを含む別の解決策は、moveLeft機能とmoveRight機能を持っているだろう

public IEnumerator moveBadGuy(BadGuy guyToMove){ 

    guyToMove.move(); 

} 

を行うことができます。例えば、私はしばらくの間に依存していけないことをお勧めします

public IEnumerator moveBadGuy(){ 

    if(shouldmoveleft){ 
     moveLeft(); 
    }else{ 
     moveRight(); 
    } 
} 

public void moveLeft(){ 
    //logic for moving left 
} 

public void moveRight(){ 
    //logic for moving right 
} 
0

は、何を行うことができ、この歩留まりリターンStartCoroutine(myFuncという())のような別のコルーチンを得courotuinesの能力を使用しています。

0

個人的には、[右|左]コルーチンが自分自身を停止する責任を負いません。

コルーチンは反復子ブロックなので、さらに抽象化して親コルーチンが実行を実行させることができます。ここで

は抽象例です:

IEnumerator AlternateOnCondition(Func<bool> evaluateCondition, 
           IEnumerator firstAction, 
           IEnumerator secondAction) 
{ 
    while(true) 
    { 
     if(evaluateCondition()) 
     { 
      if (firstAction.MoveNext()) 
       yield return firstAction.Current; 
     } 
     else 
     { 
      if (firstAction.MoveNext()) 
       yield return secondAction.Current; 
     } 
     yield return null; 
    } 
} 

は、これは当然のほんの一例ですが、それはあなたのコルーチンを入れ子にすることができる方法のアイデアを与える必要があります。

関連する問題