2017-04-03 2 views
0

ゲームオブジェクトを使ったクイックソートのビジュアライゼーションを作りたいと思います。問題は、メソッドをクイックソートメソッドの中に入れると、アニメーションが終了するのを待たずに済むことです。コードはすべての行を同時に実行します。Unityでコードの次の行に移動する前に、メソッドが終了するのを待つ方法はありますか?

私はメソッドを最初に実行し、次の行に進めたいと思っています。私はすでにIEnumerator関数を試しましたが、yield return StartCoroutine (myfunction())を使用するとシーケンスが再配置されます。クイックソートは再帰的な順序で行われます。最初はアニメーションは機能しますが、再帰が発生したときには、利回りリターンはもう機能しません。

IEnumerator swapElement(int e1, int e2) 
{ 
    swap = true;<br> 
    go1 = GameObject.Find ("Element" + e1);<br> 
    go2 = GameObject.Find ("Element" + e2); 

    go1xpos = go1.GetComponent<Transform>().transform.position.x; 
    go2xpos = go2.GetComponent<Transform>().transform.position.x; 
    go1ypos = go1.GetComponent<Transform>().transform.position.y; 

    x1ps = go1xpos; 
    x2ps = go2xpos; 


    go1.GetComponent<Transform>().transform.position = new Vector3 (x2ps, go1ypos); 
    go2.GetComponent<Transform>().transform.position = new Vector3 (x1ps, go1ypos); 
    yield return new WaitForSeconds (5); 

    Debug.Log ("INSIDE SWAP : LEFT : " + e1 + " RIGHT : " + e2); 

} 



ソート方法:

int l, r; 

int partition(int[] numbers, int left, int right) 
{ 

    int pivot = numbers [ (left + right)/2]; 

    while (true) 
    { 
     while (numbers [left] < pivot) left++; 
     while (numbers [right] > pivot) right--; 

     if (left < right) 
     { 
      int temp = numbers [right]; 
      numbers [right] = numbers [left]; 
      numbers [left] = temp; 

      //Debug.Log ("LEFT : " + left + " RIGHT : " + right); 

      swapElement (left, right); 

     } 
     else 
     { 
      return right; 
     } 

    } 

} 


void quickSort(int[] arr, int left, int right) 
{ 

    if (left < right) 
    { 
     int piv = partition (arr, left, right); 

     if (piv > 1) quickSort (arr, left, piv - 1); 
     if (piv + 1 < right) quickSort (arr, piv + 1, right); 
    } 

} 

は、私はすでにstartcoroutine(swap (left, right))を試してみましたが、運

はここに私のC#のコードです。

私はスワップメソッド内にアニメーションを置くことができますが、それでもそれでも同じです。これは同時に実行されます。

追加情報:
IEnumeratorを使用すると、再帰が機能しません。 voidであれば動作しますが、voidメソッドはアニメーションメソッドが終了するのを待っていません。それは同時に実行されます。

答えて

2

コルーチンのIEnumeratorを呼び出しスタックの先頭まで戻す必要があります。私はquicksort()をコルーチンに変換することから始めます。

IEnumerator quickSort(QuickSortArgs args) 
{ 

    if (left < right) 
    { 
     int piv = partition (args.arr, args.left, args.right); 
     yield return new WaitForSeconds (5); 
     if (piv > 1) yield return quickSort (args.arr, args.left, piv - 1); 
     if (piv + 1 < right) yield return quickSort (args.arr, piv + 1, args.right); 

    } 

} 

あなたはスワップでダウン待つしたい場合は、下にそれにコールスタック内の各呼び出しからのIEnumeratorを返す必要があるだろう。

スムーズにアニメーションを作成するには、これ以上のものが必要です。時間deltatimeを含める必要があり、独自のlerpを作成する代わりにVector3.Lerpを使用することができます。

IEnumerator swapElement(SwapElementArgs args) { 

    GameObject go1 = GameObject.Find ("Element" + args.ele1); 
    GameObject go2 = GameObject.Find ("Element" + args.ele2); 

    float go1_pos = go1.transform.position; 
    float go2_pos = go2.transform.position; 

    float t = 0f; 

    while(t < 1.0f){ 

     t += Time.deltaTime/args.speed; 
     var go1_newpos = Vector3.Lerp(go1_pos, go2_pos, t); 
     var go2_newpos = Vector3.Lerp(go2_pos, go1_pos, t); 

     go1.transform.position = go1_newpos; 
     go2.transform.position = go2.newpos; 

     yield return new WaitForSeconds(0.1); 

    } 

} 

次に、このコルーチンを呼び出すのではなく、ソートメソッドで開始します。

StartCoroutine("swapElement", new SwapElementArgs(){ele1=left, ele2=right, speed=1.0f}); 
+0

返信いただきありがとうございます。まずそれを試してみてください。後にフィードを悪く送ってください。 – mjavier

+0

彼らはまだ同じ時間に移動しています。私のアニメーションコードが質問に含まれています – mjavier

+0

WaitForSecondsをパーティション呼び出しの直後に移動するとどうなりますか?スムーズにアニメートするとは思っていませんが、予想通りのスワップは少なくとも行いますか? –

関連する問題