1.判断目标在自己的前后方位可以使用下面的方法:
Vector3.Dot(transform.forward, target.position)
返回值为正时,目标在自己的前方,反之在自己的后方
2.判断目标在机子的左右方位可以使用下面的方法:
Vector3.Cross(transform.forward, target.position).y
返回值为正时,目标在自己的右方,反之在自己的左方
3.在这里顺便解说下关于空间向量的点积和叉积:
A.点积
点积的计算方式为: a·b=|a|·|b|cos<a,b> 其中|a|和|b|表示向量的模,<a,b>表示两个向量的夹角。另外在 点积 中,<a,b>和<b,a> 夹角是不分顺序的。
所以通过点积,我们其实是可以计算两个向量的夹角的。
另外通过点积的计算我们可以简单粗略的判断当前物体是否朝向另外一个物体: 只需要计算当前物体的transform.forward向量与 otherObj.transform.position 的点积即可, 大于0则在前方,否则在后方。
B.叉积
叉积的定义: c =a x b 其中a,b,c均为向量。即两个向量的叉积得到的还是向量!
性质1: c⊥a,c⊥b,即向量c垂直与向量a,b所在的平面 。
性质2: 模长|c|=|a||b|sin<a,b>
性质3: 满足右手法则 。从这点我们有axb ≠ bxa,而axb = – bxa。所以我们可以使用叉积的正负值来判断向量a,b的相对位置,即向量b是处于向量a的顺时针方向还是逆时针方向
原文链接:https://blog.csdn.net/cen616899547/article/details/38336185
[csharp] view plain copy
//求角度 及前后左右方位
public void checkTargetDirForMe(Transform target)
{
//xuqiTest: target.position = new Vector3(3, 0, 5);
Vector3 dir = target.position - transform.position; //位置差,方向
//方式1 点乘
//点积的计算方式为: a·b =| a |·| b | cos < a,b > 其中 | a | 和 | b | 表示向量的模 。
float dot = Vector3.Dot(transform.forward, dir.normalized);//点乘判断前后:dot >0在前,<0在后
float dot1 = Vector3.Dot(transform.right, dir.normalized);//点乘判断左右: dot1>0在右,<0在左
float angle = Mathf.Acos(Vector3.Dot(transform.forward.normalized, dir.normalized)) * Mathf.Rad2Deg;//通过点乘求出夹角
//方式2 叉乘
//叉乘满足右手准则 公式:模长|c|=|a||b|sin<a,b>
Vector3 cross = Vector3.Cross(transform.forward, dir.normalized);//叉乘判断左右:cross.y>0在左,<0在右
Vector3 cross1 = Vector3.Cross(transform.right, dir.normalized); //叉乘判断前后:cross.y>0在前,<0在后
angle = Mathf.Asin(Vector3.Distance(Vector3.zero, Vector3.Cross(transform.forward.normalized, dir.normalized))) * Mathf.Rad2Deg;
}
Unity 点乘(Dot)、叉乘(Cross)判断移动方向、朝向等向量问题
项目中常会用到物体移动,追踪,判断两物体移动方向是否相同,两物体移动方向夹角,以及物体 A 朝 物体 B 顺时针方向还是逆时针方向移动。物体 A 在 物体 B 的前后左右方向。
下面通过点乘(Dot)、叉乘(Cross), 得到上面的需求结果。
代码如下
using UnityEngine;
using System.Collections;
public class VectorDotCross : MonoBehaviour {
// 关于点积
private void Dot()
{
/*
点积
点积的计算方式为: a·b=|a|·|b|cos<a,b> 其中|a|和|b|表示向量的模,
<a,b>表示两个向量的夹角。 通过点积判断当两个向量的方向向是否相同
(大致相同即两个向量的夹角在 90 度范围内)
两个向量的 点积 大于 0 则两个向量夹角小于 90 度, 否则 两个向量的
夹角大于 90 度,
*/
// 定义两个向量 a、b
Vector3 a = new Vector3(1, 1, 1);
Vector3 b = new Vector3(1, 5, 1);
// 计算 a、b 点积结果
float result = Vector3.Dot(a, b);
// 通过向量直接获取两个向量的夹角(默认为 角度), 此方法范围 [0 - 180]
float angle = Vector3.Angle(a, b);
// 下面获取夹角的方法,只是展示用法,太麻烦不必使用
// 通过向量点积获取向量夹角,需要注意,必须将向量转换为单位向量才行
// 计算 a、b 单位向量的点积
result = Vector3.Dot(a.normalized, b.normalized);
// 通过反余弦函数获取 向量 a、b 夹角(默认为 弧度)
float radians = Mathf.Acos(result);
// 将弧度转换为 角度
angle = radians * Mathf.Rad2Deg;
}
// 关于叉乘
private void Cross()
{
/*
叉积
叉积的定义: c = a x b 其中a,b,c均为向量。两个向量的叉积是向量, 向量的模为 |c|=|a||b|sin<a,b>
且 向量 c 垂直于 a、b, c 垂直于 a、b 组成的平面, a x b = - b x a;
*/
// 定义两个向量 a、b
Vector3 a = new Vector3(1, 1, 1);
Vector3 b = new Vector3(1, 5, 1);
//计算向量 a、b 的叉积,结果为 向量
Vector3 c = Vector3.Cross(a, b);
// 下面获取夹角的方法,只是展示用法,太麻烦不必使用
// 通过反正弦函数获取向量 a、b 夹角(默认为弧度)
float radians = Mathf.Asin(Vector3.Distance(Vector3.zero, Vector3.Cross(a.normalized, b.normalized)));
float angle = radians * Mathf.Rad2Deg;
// 判断顺时针、逆时针方向,是在 2D 平面内的,所以需指定一个平面,下面以X、Z轴组成的平面为例(忽略 Y 轴)
// 以 Y 轴为纵轴
// 在 X、Z 轴平面上,判断 b 在 a 的顺时针或者逆时针方向
if (c.y > 0)
{
// b 在 a 的顺时针方向
}
else if (c.y == 0)
{
// b 和 a 方向相同(平行)
}
else
{
// b 在 a 的逆时针方向
}
}
// 获取两个向量的夹角 Vector3.Angle 只能返回 [0, 180] 的值
// 如真实情况下向量 a 到 b 的夹角(80 度)则 b 到 a 的夹角是(-80)
// 通过 Dot、Cross 结合获取到 a 到 b, b 到 a 的不同夹角
private void GetAngle(Vector3 a, Vector3 b)
{
Vector3 c = Vector3.Cross(a, b);
float angle = Vector3.Angle(a, b);
// b 到 a 的夹角
float sign = Mathf.Sign(Vector3.Dot(c.normalized, Vector3.Cross(a.normalized, b.normalized)));
float signed_angle = angle * sign;
Debug.Log("b -> a :" + signed_angle);
// a 到 b 的夹角
sign = Mathf.Sign(Vector3.Dot(c.normalized, Vector3.Cross(b.normalized, a.normalized)));
signed_angle = angle * sign;
Debug.Log("a -> b :" + signed_angle);
}
}
转载:https://blog.csdn.net/bobo553443/article/details/80279698