[英]How to wait for a method to finish before moving on the next line of code in Unity?
I want to make an Visualization of quick sort using game objects. 我想使用游戏对象进行快速排序的可视化。 The problem is, when I put the method inside the quicksort method it doesn't wait for the animation to finish. 问题是,当我将方法放入quicksort方法中时,它不会等待动画完成。 The code executes all the lines at the same time. 该代码同时执行所有行。
I want to make the method execute first then proceed to the next line. 我想先执行该方法,然后进行下一行。 I already tried the IEnumerator function but the sequence is rearranged if I use yield return StartCoroutine ( myfunction() )
; 我已经尝试过IEnumerator函数,但是如果我使用yield return StartCoroutine ( myfunction() )
,则会重新排列序列; quick sort is in a recursive sequence. 快速排序是递归的。 At first the animation works but when the recursion happens, the yield return is not working any more. 首先,动画有效,但是当递归发生时,收益率收益不再起作用。
Here is my code in C#: 这是我在C#中的代码:
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);
}
Sort Method: 排序方式:
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);
}
}
I already tried startcoroutine( swap (left, right) )
, but no luck. 我已经尝试过startcoroutine( swap (left, right) )
,但是没有运气。
I can put the animation inside the swap method but even then it is still the same: It executes at the same time. 我可以将动画放入swap方法中,但即使那样它仍然是相同的:它同时执行。
additional information : 附加信息 :
if I use IEnumerator, the recursion is not working. 如果我使用IEnumerator,则递归不起作用。 but if in void, It is working however, the void is not waiting for the animation method to finish. 但是,如果处于void中,则它正在工作,则void不会等待动画方法完成。 it executes at the same time. 它同时执行。
You need to return the coroutine's IEnumerator all the way up to the top of the callstack. 您需要将协程的IEnumerator一直返回到调用栈的顶部。 I would start with turning quicksort() into a coroutine. 我将从将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);
}
}
If you want to wait down in the swaps, you would need to return the IEnumerator from each call in the callstack down to it. 如果要在交换中等待,则需要从调用堆栈中的每个调用返回IEnumerator。
To smoothly animate them, something more like this. 为了使它们流畅地动画,更像这样。 You need to include the time deltatime, and you can use Vector3.Lerp instead of making your own lerp. 您需要包括时间deltatime,并且可以使用Vector3.Lerp而不是自己制作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);
}
}
Then you would start this coroutine in the sort method instead of just calling it. 然后,您可以在sort方法中启动此协程,而不仅仅是调用它。
StartCoroutine("swapElement", new SwapElementArgs(){ele1=left, ele2=right, speed=1.0f});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.