キャラの視界に入っているかどうかの判定を行うにはどうすればいいの?
やり方はいくつかあるけど、ベクトルの内積計算で判定できるわ。
キャラクターの視界に入ったかどうかを判定する方法の紹介です。
本記事の方法を実践すると、次のような範囲にターゲットが入っているかどうかを判定できるようになります。
実現方法は一通りではありませんが、本記事では汎用的で処理が軽いベクトルの内積を用いて判定する方法を紹介します。
この作品はユニティちゃんライセンス条項の元に提供されています
- Unity 2021.2.14f1
前提条件
次のように、キャラクターとターゲットがシーン上に配置されているものとします。
例では、ユニティちゃんの視界にターゲット(キューブ)があるかどうかを判定するものとして解説を進めます。
視線判定の計算式
次のように、ターゲット位置が円錐部分の領域に入っていたら、見えている判定とします。
オブジェクトの位置をP、長さ1に正規化された向きを\vec{d}、ターゲットの位置をQ、視野角を\theta、最大距離Dとします。
ターゲット位置Qが視界に入る条件は次式で表せます。
\frac{\vec{P Q}}{|\vec{P Q}|} \cdot \vec{d} > \cos{\frac{\theta}{2}}
かつ
0 < |\vec{P Q}| < D
ただし、|\vec{d}| = 1
サンプルスクリプト
指定されたターゲットが視線の範囲内に存在しているかどうかを判定するサンプルスクリプトです。
上記スクリプトを適当なゲームオブジェクトにアタッチし、各種パラメータをインスペクターから設定すると機能するようになります。
実行結果
スクリプトの解説
条件式に使うコサインと内積の計算は以下部分で行っています。
Mathf.Cos()メソッドに指定する角度は弧度法(ラジアン)のため、Mathf.Deg2Rad定数を掛けて単位変換しています。
2つのベクトルの内積は、Vector3.Dot()メソッドで計算できます。
参考:Mathf-Cos – Unity スクリプトリファレンス
参考:Vector3-Dot – Unity スクリプトリファレンス
条件式の不等式の判定処理は次の部分で行っています。
2Dゲームにおける視界判定
次のような扇状の範囲にターゲットが存在しているか判定する方法も紹介します。
判定式は3D版のものをそのまま流用できます。2Dの場合はz軸成分を0にすることで実現できます。
サンプルスクリプト
2D版の視線判定のサンプルスクリプトです。xy平面上で判定するものとします。扱うベクトル型がVector2になった以外は3Dの場合と一緒です。
実行結果
さいごに
オブジェクトが視界に入っているかどうかの判定方法の1つとして、円錐状や扇状の範囲にターゲットが存在しているかどうかをチェックする方法を紹介しました。
今回はターゲットの1点の座標で判定していましたが、大きさを考慮する場合は複数の点のどれかが視界に入っているかどうかという判定処理に変更すれば実現可能です。