【Unity】ObjectPoolとUniRxのストリームで詰まった話
スポンサーリンク
シューティングゲームの自主開発をやっていて気づいた話。
これはPool型でBulletオブジェクトを生成しています。
ここで問題なのは、敵を倒した後のBulletがいつまでたっても削除されないと言うことです。
この問題、めちゃくちゃ初歩的な問題 でしたが、今後の教訓のために記事にしました。
原因
this.OnDestroyAsObservable() でこのオブジェクトが破棄された場合 ObjectPoolを破棄していました。
こちらは弾を発生させているEnemyクラスの中で発生しています。
この部分でバレット内部の終了処理を行なっていますが、上記のGifの通り、エネミー本体が削除されるとShotBulletのストリームは削除されないため、生成されたバレットは残り続けられてしまいます。
原点回避
今回の問題はエネミー内部でバレットの処理を管轄 しているのが問題でした。
オブジェクト指向通り、役割を分散させていないための不具合でした。
修正
まずはバレット全体を管理する「BulletManager.cs」を作成しました
・使用するObjectPoolを一元管理する
・登録関数でEnemyごとのバレット発射処理をストリームで取得する
そしてEnemyのフィールドにあった弾の管理処理をこちらに移行しました。
これによってEnemyが削除された後も弾自体の破棄処理が実行されます。
Enemy側の処理変更
弾の発射ストリームを作成しました。
自分の座標を渡して、バレットの発射始点を決定します。
0.15fごとに弾を発射します。
エネミーはバレット側に発射要望を送ります。
バレットは要請がきたら、状況に合わして対応していきます。
結果
ちょっとわかりづらいですが、Enemyが削除された後もBulletの破棄処理は実行されています。
オブジェクト指向の偉大さを噛みしめました。