如何修复不能在while循环中工作的产量?

时间:2014-09-14 08:46:36

标签: while-loop unity3d 2d

我没有控制台错误,但是所有这些错误同时实例化,所以它们都是一个单元,我希望它们的产生之间有一个延迟。 (他们是在路上行走的敌人)

#pragma strict

// Instantiate a rigidbody then set the velocity
var projectile : Transform;
var cnt : int = 0;

function Update () {
    if (buttonFeatures.started) {
            while (cnt < 4) {
        // Instantiate the projectile at the position and rotation of this transform
                    wait();
                    var clone : Transform;
                    clone = Instantiate(projectile, transform.position, transform.rotation);
                    cnt++;
    } 
  }
}

function wait(){
    yield WaitForSeconds (10);
}

2 个答案:

答案 0 :(得分:0)

您的问题是,您正尝试从yield尝试与Update()类似的内容,但无法完成。

您显然无法阻止Update() 10秒,但调用使用yield的方法会立即返回*并使用该方法启动coroutine,那么你看到的是:

  • 更新来电wait()
  • 更新不断等待wait()返回
  • wait()开始等待它自己作为协程开启
  • 更新继续循环,再次调用wait() 3次,而不是每次都等待。

要确认这一点,您可以更改wait()

function wait(){
    yield WaitForSeconds (10);
    Debug.Log("Done Waiting"); //You'll see 3 of these pop up in your console in 10 seconds later
}

这里有两个主要选项。用您的逻辑替换wait()

function Update () {
    if (buttonFeatures.started) {
        while (cnt < 4) {
            InstantiateProjectile(cnt*10)// Instantiate the projectile at the position and rotation of this transform in X seconds. This will return immediately
            cnt++;
        }
    } 
}

function InstantiateProjectile(delay : int){
    yield WaitForSeconds(delay);
    var clone : Transform;
    clone = Instantiate(projectile, transform.position, transform.rotation);
}

或者在Start()中开始一个合作例程:

function Start(){
  UpdateProjectiles();
}

function UpdateProjectiles (){
    while(true){
        if (buttonFeatures.started) {
                while (cnt < 4) {

                    yield WaitForSeconds (10); //This works because it's not in Update
                    var clone : Transform;
                    clone = Instantiate(projectile, transform.position, transform.rotation); // Instantiate the projectile at the position and rotation of this transform
                    cnt++;
                } 
         } 
     yield; //This causes this coroutine to behave the way Update would (running once a frame)
    }
}

第二个示例中的while(true)可能有点令人担忧,但由于Update(),其效果与使用yield没有什么不同。事实上,许多人使用他们的大多数传统&#34;协同例程中的Update()逻辑,因为它们允许更好地封装状态管理逻辑,并且非常适合定期任务。

注意:我并不想过多地歪曲你的代码并模糊它的含义,但你可能想重新考虑代码的某些部分:

  • 您有一个带有计数的while循环,很容易成为for循环。
  • 你有一个似乎正在替换对象的循环。 Instantiate可能是您可以拨打的最昂贵的电话之一,因为每次拨打电话,最终您都要支付GC清理对象的费用。

    你不想破坏大量的物品并打电话Instantiate用相同的物品替换它们,因为GC会开始减慢你的游戏速度以保持稳定。现在,正如你的代码所代表的那样,如果射弹开始在它们很快被摧毁的情况下产生,如果游戏完全冻结,我会感到惊讶。

    相反,更喜欢重用对象和对象池。有关于如何操作的教程,例如this one。在最基本的层面上,它可以像给你的射弹Reset方法一样简单。然后,您可以使用调用Destroy的方法替换Reset,并将其存储在StackList中,以便再次访问它们。但是你想要封装所有那些逻辑,所以请看一下这个教程的具体细节。

答案 1 :(得分:-1)

替换此行而不是进行函数调用:

yield返回new WaitForSeconds(10);