気ままなUnityエンジニアブログ

新米Unityエンジニアが送る解説アウトプットブログです。Twitter : @UjinUnity

MENU

【Unity】ObjectPoolとUniRxのストリームで詰まった話

スポンサーリンク

シューティングゲームの自主開発をやっていて気づいた話。

f:id:Wojtek:20190616193103g:plain

これはPool型でBulletオブジェクトを生成しています。

ここで問題なのは、敵を倒した後のBulletがいつまでたっても削除されないと言うことです。

この問題、めちゃくちゃ初歩的な問題 でしたが、今後の教訓のために記事にしました。

 原因

 

f:id:Wojtek:20190616193612p:plain

this.OnDestroyAsObservable() でこのオブジェクトが破棄された場合 ObjectPoolを破棄していました。

f:id:Wojtek:20190616194728p:plain

こちらは弾を発生させているEnemyクラスの中で発生しています。

f:id:Wojtek:20190616195454p:plain

この部分でバレット内部の終了処理を行なっていますが、上記のGifの通り、エネミー本体が削除されるとShotBulletのストリームは削除されないため、生成されたバレットは残り続けられてしまいます。

 

原点回避

今回の問題はエネミー内部でバレットの処理を管轄 しているのが問題でした。

オブジェクト指向通り、役割を分散させていないための不具合でした。

 

修正

まずはバレット全体を管理する「BulletManager.cs」を作成しました

 

 

f:id:Wojtek:20190616201332p:plain

・使用するObjectPoolを一元管理する

・登録関数でEnemyごとのバレット発射処理をストリームで取得する

f:id:Wojtek:20190616201455p:plain

そしてEnemyのフィールドにあった弾の管理処理をこちらに移行しました。

これによってEnemyが削除された後も弾自体の破棄処理が実行されます。

 

Enemy側の処理変更

f:id:Wojtek:20190616201829p:plain

弾の発射ストリームを作成しました。

自分の座標を渡して、バレットの発射始点を決定します。

f:id:Wojtek:20190616201933p:plain

0.15fごとに弾を発射します。

エネミーはバレット側に発射要望を送ります。

バレットは要請がきたら、状況に合わして対応していきます。

 

結果

f:id:Wojtek:20190616202123g:plain

ちょっとわかりづらいですが、Enemyが削除された後もBulletの破棄処理は実行されています。

オブジェクト指向の偉大さを噛みしめました。