ProjectileMovementのホーミング使用時の注意点
ProjectileMovement、つかってますか?
簡単に弾が出せますし、
ホーミングもターゲットをちょちょいとつけるだけでやってくれて
非常に便利だなあと思ってたんですが
そのホーミングにちょっと罠がありました。
ホーミング
例えば敵の弾をプレーヤーに向けてホーミングしたい場合、
弾にProjectileMovementをつけてホーミングを有効にします。
で、その後BPでターゲットにプレーヤーをつけます。
こんな感じ。
で、プレイすると良い感じにホーミングしてくれるんですが、
この形でホーミングをつけた敵の弾をDestroyすると、
内部的にホーミングが残ってしまうようです。
何がおきるか
残った場合、何がおきるかというと、
・プレーヤーが移動すると処理落ち
・プレーヤーを止めてしばらく待つと速度が戻る
という中々嫌な感じの影響が出ます。
Destroyしているので画面上に敵の弾はありませんが
プレーヤーが移動するとそこに向けてホーミングされるので処理落ち、
しばらく止まっていると直線に戻るので速度が戻る、ということだと思います。
原因
なーんでー?と思いながら調べてもわからず、ふと休憩した時に判明しました。
HomingTargetComponentは弱参照じゃないと駄目みたいです。
カーソルのせた時のコメントに助けられました……
対処としては、
WeakObjectを渡してしまえば解決するので
WeakObjectが取れるLineTrace系を利用すればよさそうです。
(すみません画像ミスありです。前後なのでForwardVectorに対して*10と*-10です)
対象の前後を取得してLineTraceForObjects等で確実に当てる形が
楽でいいかなと思いますが対象とLineTraceの間に何かが挟まってしまった場合
上手くいかないので、ObjectTypeを絞る等が必要です。
ちなみに普通の参照のまま対応できないかなーと
Destroy直前にTargetComponentをかえたり、ホーミングをオフにしたりと、
そもそもそれで対応できるなら多分Destroyでも解放されるよな、と
思いながら試した結果、特に変化はありませんでした。
素直にWeakObjectを入れてください。
問題になりにくい場合
参照が問題になるので、対象(この場合はプレーヤー)がDestroyされると
おそらく解放されます。
なので、
・レベル切り替えやプレーヤーのDestroyが適度にされる
・ホーミングの生成数がそもそもあまり多くない
といった場合は、問題が表面化まではいかないのかなと思います。
内部的には、たまってますが。
・「自分の攻撃」がホーミングで、あたった敵がDestroyされる
・ホーミングをDestroyしない
等は問題は発生しないと思いますので、
弾をプールする、等でも大丈夫かなと。
WeakObject
非プログラマでUE4を使っている方にはこれ結構説明が難しいと思うんですが
誤解を招く覚悟で言うと
いつメモリを解放するかの話で
・Weakは使わなくなったらメモリ解放されやすい
・してほしくない場合も多々あるのでわかれてる
くらいで今日のところはお願いします。
WeakObjectがBP上で使われている箇所があるとわかった以上、
別の箇所でも処理がたまっていそうな挙動があった場合は
これを疑ってみてもいいのかなと。