この記事は、こちらの記事を参考にお互いが正面向き合ってる状態で、判定する内容になります。
内積、Vector3.Dot、normarizedについての説明は、参考記事内にあるため省略します。
【Unity(C#)】Rayではなく内積(Vector3.Dot)で視線判定を行う
記述が増えてしまう為、お互いの頭のゲームオブジェクトは今回Inspecterからアタッチしてます。
概ね頭のある場所は、キャラクターオブジェクト>Root>Hips>Spine_1>Spine_2>Neck>Headと言った感じの階層です。
取り敢えず、どんなもんか気になる人向けに先にコードを出します。
コード
using UnityEngine;
public class LookMatch : MonoBehaviour
{
[SerializeField]private GameObject playerHead; //プレイヤーの頭
[SerializeField]private GameObject targetHead; //対象となる相手の頭
[SerializeField]private float distance; //判定に必要な距離
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
//互いの距離が一定距離内だったら判定する。
float mag = (targetHead.transform.position - playerHead.transform.position).magnitude;
if (distance >= mag)
{
//ターゲットからこちらの方向へ正規化したベクトルを作成
Vector3 targetToCharaDirection = (playerHead.transform.position - targetHead.transform.position).normalized;
if (Vector3.Dot(targetToCharaDirection, playerHead.transform.forward.normalized) < -0.9 //正規化したベクトルの内積がプレイヤーの頭から一定以下
&& Vector3.Dot(targetToCharaDirection, targetHead.transform.forward.normalized) > 0.9 //正規化したベクトルの内積が相手の頭から一定以上
&& targetHead.transform.InverseTransformPoint(playerHead.transform.position).z >= 0) //対象にとって正面側にいるかどうか
{
//顔が向き合っている時の処理内容を記述
}else{
//顔が向き合ってない時の処理内容を記述
}
}else{
//距離が離れている時の処理を記述
}
}
}
デモ ~顔が合うと?マークを表示する~
以上の状態であると?マークが表示されるようになります。
InverseTransformPoint
Transform.InverseTransformPoint
ワールド空間からローカル空間へ position を変換します。
これにより、プレイヤーの頭が対象の頭にとってローカル空間にpositionが変換され
前方側(z >= 0 )にいる状態になります。
Vector3.Dot(targetToCharaDirection, targetHead.transform.forward.normalized) > 0.9 //正規化したベクトルの内積が相手の頭から一定以上
によりあまりいらない気もします。
magnitude
Vector3.magnitude
ベクトルの長さ(読み取り専用)
ベクトルの (x x+y y+z* z) の平方根の長さを返します。
今回の使い方としては、対象の頭の位置とプレイヤーの頭の位置を差し引いた時の距離の値が
distanceに設定した値より小さければ距離の判定を満たす形になっています。
そうしないと、数百m離れても判定する事に・・・