Unityでインディゲームを作る!

Unityでのゲーム制作を目指し、それに関わる話題についてのブログ

Unity 一度スタートさせたコルーチンを途中で止める方法(小さなエリアを追加的にロードする)[ StartCoroutine, StopCoroutine ]

 処理の間に時間を挟んだり、一定時間待機した後に処理を実行するなどしたい時に使うCoroutine(コルーチン)をその実行途中で止めるための方法について書きます。

 

StartCoroutine(DelayUnloadScene());

 という風に、StartCoroutineでコルーチンをスタートさせるわけですが、StartCorutineはCoroutineをリターンとして出力します。

 この参照をCoroutine変数に代入しておいて、そのコルーチンを止めたいタイミングで、そのcoroutineを入力したStopCoroutineを実行すれば、発動しているコルーチンが停止されます。

 

StopCoroutineTest_AreaTrigger

 今回の例として扱うのは、あるエリアをトリガーが囲っており、そこにプレイヤーが入ると、そのエリアのシーンが読み込まれる、という仕組みです。トリガー内に入ると、下の写真のようにエリア内にオブジェクト群が出現します。

StopCoroutineTest_LoadedScene

 そして、本題はコルーチンを使った、シーンのアンロードです。そのエリアをカバーするトリガーを離れてから10秒後にシーンがアンロードされる、というコルーチンを用意し、その実行中にまたプレイヤーがトリガー圏内に入ってきた場合、そのアンロードを止めたい、とします。

 

StopCoroutineTest_Script01

 その場合、OnExitTriggerでStartCoroutineを実行し、変数(ここではdelayUnloadRoutine)にそのcoroutineを保存しておきます。そこにまたPlayerが入ってきてOnEnterTriggerが呼び出され、まだコルーチンが有効だった場合はStopCoroutineを実行するという流れです。

StopCoroutineTest_Script02

 実際のスクリプトでは該当のシーンがロードされているかどうかで、シーンをロードするか、コルーチンを停止するかの判断をしています。

 コルーチン変数について自分が調べてみた所、実行されたコルーチンの参照がその後自動でnullになるわけではないようなので、こっちのやり方の方がいいのかもしれません。

StopCoroutineTest_UnloadScene_Console

 トリガーをプレイヤーが出て、10秒立つとシーンがアンロードされます。しかし、この途中でまたエリア内に入ると、このコルーチンは停止されます。

StopCoroutineTest_StopUnload_Console

 これにより、プレイヤーがエリア外に出て、またすぐに戻ってきた場合に無駄にロードやアンロードを繰り返さなくて済むようにしています。

 完全にプレイヤーが離れ切った所で、エリアをアンロードする、ということです。

StopCoroutineTest_EmptyArea

 今回はテストということで、開放的なエリアでしたが、壁や建物で囲って中を外から見れなくすれば、無駄なオブジェクトの読み込みをプレイヤーに気づかれず防ぐことが出来るな、と思いました。

 


 

 というわけで、スタートさせたコルーチンを途中で止める方法でした。今回扱ったエリアをシーンで区切って、プレイヤーが近づいたらロードする、という方法でメモリを圧迫せず、ローディング時間も少ないゲームにできると思うので、ここら辺も研究していきたい所です。