いぬおさんのおもしろ数学実験室

おいしい紅茶でも飲みながら数学、物理、工学、プログラミング、そして読書を楽しみましょう

Unityでゲームオブジェクトが存在するか確認する方法

あまり見かけないなあ……と思った話です。ゲームオブジェクトがアクティブかどうか、ではありません。存在するかどうか、つまり削除されていないかどうかの確認です。

Unityで2Dシューティングを書いています。敵に0.1秒間隔くらいで弾を撃たせるのにコルーチンを使いました。コルーチンについては以下を。

www.omoshiro-suugaku.com

www.omoshiro-suugaku.com

0.1秒間隔で10発撃つには1秒かかります。1秒の間にその敵が撃ち落とされたり、プレイ画面外に出て削除されたりすることもあります。そうなると、コルーチンでその敵のゲームオブジェクトを操作するようになっている場合「そのゲームオブジェクトはない」みたいなエラーで止まってしまいます。ゲームオブジェクトが有効なのかどうか(存在しているのか削除済みなのか)判断する方法がないとまずいのです。

最初はif(go == null){……}みたいなコードを書いていましたが、どうもこれ、ダメみたいです。もちろん最初go = null と代入しておき、オブジェクトを生成してgoをセットする、とやればif(go == null){……}でオブジェクトの存在は分かります。しかし削除される可能性がある場合、これではまずそうだ、ということです。ネットを調べていて

if(go){……}

というのを見かけました。「エッ、こんなの、いいの?」という感じですが、これでエラーがピタリとなくなりました。スバラシイ!!!

 

コルーチンを使わなくても、同じような働きをするコードは書けます。Update()内に、時間の経過をチェックして必要な時間になったらしかるべき動作をするような関数を入れておけばよいことです。しかしコルーチンを使った方が簡潔になるケースは少なくない気がします。例えば初期化が必要なときなど、コルーチンの中に初期化のコードを入れておくことができ、コードをあちこちに分散させなくて済みます。しかしどうもこのコルーチン、バグの温床になるかも……とも思うのです。動作しているコルーチンはUpdate()を見ても分かりません。そしてコルーチンは複数走らせることも多いですから、そうしたときにお互いの干渉で出るバグだってありそうです。Update()に書いておけばどの関数がどの順で呼ばれるのかは決まりますし、コードを追うのもやりやすいです。でもコルーチンは互いに独立して走りますから、難しい面はあるかも。まあでも、とりあえず今はガンガン使ってみようと思います。