【Unity】処理を止める方法。一定時間待ってから処理を実行するスクリプト

【Unity】処理を止める方法。一定時間待ってから処理を実行するスクリプト

 Unityの一部の処理を一旦停止させたり、特定の処理だけを先に実行する方法について詳しく解説していきます。コルーチンを使うのですが、難しいことは考えなくて大丈夫です。とりあえずコピペで実装できるようにまとめてみました。この記事でスクリプトの停止・再開・実行順番の操作はマスターできます。

コルーチンとは?

 Unityのコルーチンは、非同期処理を簡単に実装するための機能です。通常、Unityのスクリプトはフレームワークによって同期的に実行されますが、コルーチンを使用することで非同期的に実行することができます。

 つまり、スクリプト全体の処理を動かしながら特定の処理を一定時間止めることができる関数のことです。

 例えば、敵が倒れるアニメーションを再生し、アニメーションが終わってから敵のオブジェクトを破壊する処理を作るとします。この時、処理を順番通りにスクリプトにして書くとアニメーションが終わる前に敵のオブジェクトを破壊してしまいます。

 そこで、アニメーションが終わるまで敵のオブジェクトを破壊せずに一時停止する必要が生まれます。スクリプト内の特定の処理だけを一時停止できるコルーチンの出番ですね。この時、全体のスクリプトが止まるわけではないので、一時停止中にスコアを加算したりプレイヤーを移動させたりできるわけですね。

コルーチンのメリット

時間指定で処理を実行できる

 コルーチンは、指定した時間の経過後に処理を再開できます。たとえば、ゲームのアニメーションやエフェクトなど、タイミングが重要な処理を実行する際に便利です。

フレームスキップを防ぐことができる

 コルーチンは、一定間隔で処理を実行することができます。これにより、フレームスキップが発生することを防ぐことができます。

 フレームスキップとは、ゲームがフレームレート(1秒間に表示される画面の枚数)を維持できずに、画面の更新をスキップしてしまう現象のことを指します。これにより、ゲームの動作がカクカクしたり、不自然にスローダウンしたりすることがあります。

 Unityでは、通常は1秒間に60フレーム(60FPS)を維持するように設計されています。しかし、重い処理が行われる場合や、多数のオブジェクトが同時に描画される場合など、処理が遅延するとフレームスキップが発生してしまいます。

 コルーチンを使用することで、処理を遅延させることができるため、フレームスキップを防ぐことができます。たとえば、1フレームごとに少しずつ処理を進めることで、処理負荷を分散し、フレームスキップを防止することができます。

非同期処理が簡単に実装できる

 コルーチンを使用することで、非同期処理を簡単に実装できます。たとえば、ウェブリクエストを送信して、その完了まで待機するような処理を簡単に実装できます。

コルーチンのデメリット

コードの読みやすさが低下する

 コルーチンを使用することで、処理の流れが複雑になるため、コードの読みやすさが低下することがあります。

デバッグが困難になる

 コルーチンを使用することで、処理のフローが予測しづらくなり、デバッグが困難になることがあります。

実行時の負荷が増大する

 コルーチンは、処理が非同期的に実行されるため、実行時の負荷が増大する可能性があります。

コルーチンの使用方法

コルーチンを定義する

  コルーチン名をDefeatとします。Defeatの意味は敵を倒したという意味ですね。ここはどんな名前でもいいので好きな名前を付けましょう。

IEnumerator Defeat() 
{
    //終わるまで待ってほしい処理を書く
    //例:敵が倒れるアニメーションを開始

    //2秒待つ
    yield return new WaitForSeconds(2);

    //再開してから実行したい処理を書く
    //例:敵オブジェクトを破壊
} 

 見慣れないコードが2つ出てきましたね。

 大まかにですが、『 IEnumerator コルーチン 名(){}』で コルーチン を定義し、『 yield return new WaitForSeconds(秒数) 』で指定の秒数だけ待機させることができます。

コルーチン を実行する

 コルーチン を開始するためには『StartCoroutine(” コルーチン 名”);』か『 StartCoroutine(コルーチン名()); 』と書く必要があります。どちらでも良いのでお好みでどうぞ。

void Update(){
  //もし敵を倒したのなら
  if(defeat_flag==true){
    //Defeatというコルーチンを開始
    //どちらか一方を書く。2つ書くと2回実行してしまうので注意

    //例1
    StartCoroutine("Defeat");

    //例2
    StartCoroutine(Defeat());
  }
}

 これで実行することができます。

まとめ

 数秒待機してから処理を行いたいのならコルーチンが最適。

コルーチンを定義する IEnumerator コルーチン名(){}
コルーチン内で数秒待機させる yield return new WaitForSeconds(秒数);
コルーチンを開始する StartCoroutine(“コルーチン名”);
StartCoroutine(コルーチン名());