0

Unityscript でWaitForSeconds関数を使用する方法を学んでおり、以前は成功していました。しかし今、私はスクリプトでそれを試しています。オブジェクトのヘルスが 0 に達したとき、オブジェクト (この場合はボックス) を画面外に移動し、設定された秒数後にランダムな位置に再表示します。画面上で、ヘルスをデフォルト値に戻します。私がこれまでに持っているものは次のとおりです。

function Update () 
{
    if(health <= 0)
    {
        RespawnWaitTime ();
        var position = Vector3(Random.Range(-6,6),Random.Range(-4.5,4.5),0); //this is the onscreen range   
        transform.position = position;
        health = 2;                 
    }
}

function RespawnWaitTime ()
{
    var offScreen = Vector3(10,10,0);
    transform.position = offScreen;
    yield WaitForSeconds(2);
}

ただし、2 秒もまったく待ちません。ボックスは、関数がそこになかったかのように、新しい位置にまっすぐ進みます。画面外の位置に移動すると思いますが、待たずにまっすぐ戻ってきます。コードの一部を次のように変更して、待機がまったく適用されているかどうかをテストしました。

function RespawnWaitTime ()
{
    var offScreen = Vector3(10,10,0);
    transform.position = offScreen;
    print("I'm over here!");
    yield WaitForSeconds(2);
    print("I'm coming back!");  
}

テキストの最初のビットがすぐに印刷され、2 秒後にテキストの 2 番目のビットが期待どおりに表示されます。では、待機がボックスにも適用されないのはなぜですか? ご協力いただきありがとうございます。

4

2 に答える 2

1

WaitForSeconds は非同期であると思われるため、更新が RespawnWaitTime を呼び出すと、RespawnWaitTime はすぐに返されます。次のコードを試して、WaitForSeconds の動作を確認していただけますか?

function Update () {
        print("1 in update before calling respandwaittime");
        RespawnWaitTime ();
        print("3 in update after calling respandwaittime");
}

function RespawnWaitTime (){
    print("2 in in respainwaittime before calling waitforseconds");
    yield WaitForSeconds(2);
    print("4 in in respainwaittime after calling waitforseconds");
}

出力は 1,2,3,4 (予想どおり) だったので、次のように再プログラムできます。

function Update () {
    if(health <= 0){
        recover();
        return;
    }
}

function recover(){
    var offScreen = Vector3(10,10,0);
    transform.position = offScreen;
    yield WaitForSeconds(2);
    //this is the onscreen range   
    var position = Vector3(Random.Range(-6,6),Random.Range(-4.5,4.5),0); 
    transform.position = position;
    health = 2;                 
}
于 2013-03-05T06:28:31.380 に答える
0

「yield RespawnWaitTime();」を使用する必要があります。- それ以外の場合、それを呼び出した関数は、コルーチンの実行と同時に実行を続けます。

コルーチンを明け渡すと、コルーチンが終了するまで、それを呼び出したコードの実行が一時停止されます。コルーチンが終了すると、yield ステートメントに続く行から元のコードが再開されます。

ただし、yield ステートメントを Update() 内に配置できないため、次のような中間関数を呼び出す必要があります。

function Update () 
{
    if(health <= 0)
    {
        Respawn ();              
    }
}

function Respawn ()
{
    yield RespawnWaitTime ();
    var position = Vector3(Random.Range(-6,6),Random.Range(-4.5,4.5),0);
    transform.position = position;
    health = 2;
}

function RespawnWaitTime () : IEnumerator
{
    var offScreen = Vector3(10,10,0);
    transform.position = offScreen;
    yield WaitForSeconds(2);
}

":IEnumerator" も RespawnWaitTime() に追加したことに注意してください。そうしないと、それを呼び出した yield ステートメントのエラーがコンソールに表示されます。私が理解しているように、コンパイルエラーが表示されていてもコードはおそらく機能しますが、私はチャンスを逃したくありません;-)

于 2015-03-01T14:16:14.430 に答える