環境
UE4.25.3
概要
画面内/カメラ内に特定のActorが入っているかどうかを判定したいケースは大変多いと思います。
今回はいずれも大雑把なものなので、正確に判定が必要な場合は別の実装方法を検討された方が良いかもしれません。
実運用に耐えうるかどうかはケースバイケースだと思いますが、何かしら役に立てば幸いです。
それぞれのcaseでメリット / デメリットがあります。
遮蔽物判定は別途、カメラからActorに対してRayを飛ばす等して判定するのが無難かなという気もします。
今回はせっかくなので前回作ったHPバーの表示 / 非表示で動作確認を行います。
papersloth.hatenablog.com
画面内判定の実装方法
case1 直近に描画されたかどうかで判定(正確さ : 更新頻度による)
Was Recently Rendered ノードを利用
メリット:遮蔽物を考慮してくれる
最も手軽に実装ができる
デメリット:遮蔽物を無視するオプションがない
更新頻度次第では処理負荷がかかるかも(要プロファイリング)
HPバーの表示 / 非表示で組んだノードはこれだけです。
この例ではこのActorが直近0.2秒以内に描画されたかどうかで判定を行っています。
case2 カメラの位置/向きとActorの位置を元に特定に閾値内かどうかで判定(正確さ : そこそこ大雑把)
gifの例では意図的に画面の端のほうで少し映っている時にも判定を抜けるようにしています。
この辺はゲームによりけりで要調整かなと思います。
Camera位置/向きとActorの位置を元にDotProductを利用
dotの結果は敵が正面にいる場合は1.0、真横では両サイドどちらでも0.0、真後ろにいる場合は-1.0
つまり、0以下の場合は真横よりも後ろにいるということもチェック出来る
メリット:描画判定をある程度調節ができる
画面内だけでなく、後ろにいるか等の判定もできる
デメリット:遮蔽物を考慮しない
case1 ほど正確ではない
また、閾値である程度の調整が効いて使いまわしもしやすいため
Blueprint Function Libraryなどにまとめておいてもよいでしょう。
case3 Screen座標変換時のノードで判定(正確さ : 最も大雑把)
Project, Project World to Screen, Convert World Location To Screen Locationノードを利用
画面外にいる場合でも判定が抜けているのが分かるかと思います。
大凡左右の半分以上から離れていないと画面内として判定されてしまいますね。
そのため、画面内かどうかというよりは敵が前面にいるかどうかくらいの判定に使うのが無難だと思います。
例えば、ロックオン対象の敵を最低限前面にいる敵に絞りたい場合とかでしょうか。
メリット:前面にいるかどうかの判定ができる
デメリット:画面内にいるかどうかの判定としては弱い
実装は至ってシンプルです。
Convert World Location To Screen Locationでも
Project World to Screentでも
(HUD only)ProjectのZ > 0でも
いずれも結果は同じになるかと思います。
まとめ
いずれも用途が別のものとしてケースバイケースで使うのが良いのではないかと思います。
何かしら参考になる部分があれば幸いです。
参考資料
今回紹介していない角度を用いた実装方法も紹介されています。
case1, case3の一部はこちらでも紹介されている方法です。
アクターがカメラに映っているかを判別したい - UE4 AnswerHub