コルーチンの実行順序が変わってしまう話

例えば自機に追従するようなレーザーを作りたい場合、レーザーの位置はこういう計算を行います。

自機の位置+nフレーム分移動した移動量

ところが、自機・レーザーの位置更新にコルーチンを使っていると、最初のフレームだけレーザーの位置がずれる、といった現象に悩まされます。

これはコルーチンの実行順序が「最初の1フレーム目」と「続く2フレーム目以降」で異なることが原因です。

コルーチンは最初の1フレーム目については(Awake や Start などで)StartCoroutine() が実行された瞬間に即発生しますが、2フレーム目以降は(おそらく)コルーチンの登録順に従います。

このため、実行順序が

1フレーム目のレーザー位置更新→自機の位置更新→2フレーム目以降のレーザー位置更新

1フレーム目レーザーは移動前の自機座標となるため、その他のレーザーと自機が移動した分だけ座標がずれる、というわけです。

対処法ですが、コルーチン発生の1フレーム目は弾を消しておくなどして、yield return null で空回しします。

2フレーム目以降に発生するのであれば、(自機のコルーチンが固定されている限り)コルーチン登録順となるため、ずれずにレーザーを発射できるようになります。

// 初回フレームだけプレイヤーコルーチンより早く実行される(そして表示がずれる)ので、見えなくして誤魔化す
Vector3 scale = gameObject.transform.localScale;
gameObject.transform.localScale = Vector3.zero;

yield return null;

// 表示復活
gameObject.transform.localScale = scale;

while (true)
{
     //★ レーザーの位置更新

    yield return null;
}

コルーチンなど使わず、1つの Update で実行順序を管理することで、より安心感のある設計にするのもいいです。(変数を外出ししたり、init - loop - exit の仕組みも管理するなど、面倒といえば面倒ですが…)

返信を残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA