unity 判断位置在相机前还是后 unity判断两物体距离_叉积

Unity 进阶 之 判断基于物体所处位置(前后左右)/ 方法原理 /注意事项的简单整理

目录

Unity 进阶 之 判断基于物体所处位置(前后左右)/ 方法原理 /注意事项的简单整理

一、简单介绍

二、实现原理

三、注意事项

四、效果预览

五、实现步骤

六、关键代码

七、附录

点积

叉积


一、简单介绍

Unity中的一些知识点整理。

本节简单介绍在Unity开发中的,判断某个物体在某个物体的位置(相对的前后左右判断),便于根据位置进行一些其他的操作,如果你有新的方式也可以留言,多谢。

二、实现原理

1、在Unity中,使用点积进行前后的判断

   Vector3 dir = target.position - transform.position; //位置差,方向     

   Vector3.Dot(transform.forward, dir);

返回值为正时,目标在自己的前方,反之在自己的后方
 

2、在Unity中,使用叉积的 y 值进行左右判断

  Vector3.Cross(transform.forward, target.position).y

  返回值为正时,目标在自己的右方,反之在自己的左方
(为什么取y呢 ,因为 transform.forward实际上是 (0,0,1)*rotation, 也就是只有z有值,

cross出来,就只有 y是计算 x和z 的情况,x是计算  y的情况,z是0;因此 左右关系,是由x和z决定的。)

三、注意事项

1、一个相对另一个物体的判断,最好使用他们间的相对位置判断最后准确,这样可以避免判断的错误

2、实际应用中,合理的使用这种关系,和变换这种关系的使用,拓展出一些新功能的使用,大家结合实际开发使用即可

四、效果预览

unity 判断位置在相机前还是后 unity判断两物体距离_unity 判断位置在相机前还是后_02

五、实现步骤

1、打开 Unity ,新建空工程

unity 判断位置在相机前还是后 unity判断两物体距离_位置判断_03

2、在场景中,布局场景,用于演示

unity 判断位置在相机前还是后 unity判断两物体距离_叉积_04

3、创建脚本,一个用来封装判断函数,一个用来测试函数功能

unity 判断位置在相机前还是后 unity判断两物体距离_前后左右_05

 

4、把测试脚本挂载到场景中,并且对应赋值

unity 判断位置在相机前还是后 unity判断两物体距离_unity 判断位置在相机前还是后_06

5、运行场景,效果如上,随着 BaseTransform 转动 或者 Player 移动到不同位置,打印结果就会相应结果

unity 判断位置在相机前还是后 unity判断两物体距离_位置判断_07

六、关键代码

1、JudgeIsForwardRightBaseSomeOneTransfrom

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace XANUtils { 

    /// <summary>
    /// 判断前后左右的封装
    /// </summary>
	public class JudgeIsForwardRightBaseSomeOneTransfrom
	{
        /// <summary>
        /// 判断在基于位置的是否在前后
        /// </summary>
        /// <param name="baseTrans"></param>
        /// <param name="dir"></param>
        /// <returns>true:前;false:后</returns>
        public static bool IsForward(Transform baseTrans, Vector3 pos) {
            return GetIsForwardValue(baseTrans, pos) >= 0 ? true:false;
        }

        /// <summary>
        /// 判断在基于位置的是否在左右
        /// </summary>
        /// <param name="baseTrans"></param>
        /// <param name="dir"></param>
        /// <returns>true:右;false:左</returns>
        public static bool IsRight(Transform baseTrans, Vector3 pos)
        {
            return GetIsRightValue(baseTrans, pos) >= 0 ? true : false;
        }

        // 大于0,前
        // pos 为 0 ,结果会出错 (做好是相对位置)
        public static float GetIsForwardValue(Transform baseTrans, Vector3 pos)
        {
            return Vector3.Dot(baseTrans.forward, pos - baseTrans.position);
        }

        // 大于0,右边
        // pos 为 0 ,结果会出错(做好是相对位置)
        public static float GetIsRightValue(Transform baseTrans, Vector3 pos)
        {
            return Vector3.Cross(baseTrans.forward, pos - baseTrans.position).y;
        }
    }
}

2、TestJudgeIsForwardRightBaseSomeOneTransfrom

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XANUtils;

namespace TestSpace { 

	public class TestJudgeIsForwardRightBaseSomeOneTransfrom : MonoBehaviour
	{
		public Transform BaseTransform;
		public Transform NeedJudageTrans;


		// Update is called once per frame
		void Update()
		{
			if (BaseTransform != null && NeedJudageTrans != null)
			{
				bool isForward =  JudgeIsForwardRightBaseSomeOneTransfrom.IsForward(BaseTransform, NeedJudageTrans.position);
				bool isRight = JudgeIsForwardRightBaseSomeOneTransfrom.IsRight(BaseTransform, NeedJudageTrans.position);

				Debug.LogWarning(GetType() + "/Update()/" + (isForward ? "前" : "后"));
				Debug.LogWarning(GetType() + "/Update()/" + (isRight ? "右" : "左"));

			}
			else {
				Debug.LogError(GetType()+ "/Update()/ BaseTransform or NeedJudageTrans is null !! ");
			}
		}
	}
}

七、附录

点积

判断两个物体的位置 关系,是可以通过 这个 cos<a,b> 来判断,知道了这个余玄值,就可以知道 这个角度了。

 几何的定义: a·b=|a|*|b|*cos<a,b> 

对于n维度代数定义:

unity 判断位置在相机前还是后 unity判断两物体距离_unity 判断位置在相机前还是后_08

它在Unity中 调用是通过Vector3.Dot(),Unity中使用的也是代数公式

 public static float Dot(Vector3 lhs, Vector3 rhs)
    {
      return (float) ((double) lhs.x * (double) rhs.x + (double) lhs.y * (double) rhs.y + (double) lhs.z * (double) rhs.z);
    }

如何判断的方位:

使用 a 物体的transform.forward向量与 a 物体到 b 的方向做点击就可以得到这个余弦值了

a 到 b 的方向: otherObj.transform.position – transform.position

transform.forward 是玩家正面朝向 方向

大于0则面对,否则则背对着。当然这个计算也会有一点误差,但大致够用。

 因为求的角度用的是 单位向量,所以可以直接求得cos<a,b>

这个角度值 还可以用来判断是否在视野内,一般情况下人的视野是在124度内,游戏里一般是限制在90度左右,视距就直接是两点之间的距离了。

a·b= |a| *|b| * cos<a,b>   =>    a·b= |1|

cos<a,b>的 含义图:

unity 判断位置在相机前还是后 unity判断两物体距离_前后左右_09

作用:

  •     是光照模型的应用,漫反射,高光的计算,diffuse=0.5+0.5*dot(n,l) ,n是法线方向,l是光照方向, 高光saturate(pow(dot(n,h),_Gloss))其中,h是 (viewDir+worldLightDir)/2
  •     是判断方位,角度,视野
  •     是 几何意义可以是求b在 a的投影
  •     等等
     

叉积

是一种在向量空间中向量的二元运算。与点积不同,它的运算结果是一个向量而不是一个标量。并且两个向量的叉积与这两个向量和垂直。其应用也十分广泛,通常应用于物理学光学和计算机图形学中。

叉积的定义: c =a x b  其中a,b,c均为向量。即两个向量的叉积得到的还是向量! 

unity 判断位置在相机前还是后 unity判断两物体距离_前后左右_10

unity 判断位置在相机前还是后 unity判断两物体距离_位置判断_11

 

性质:

  • c⊥a,c⊥b,即向量c垂直与向量a,b所在的平面 。
  • 模长|c|=|a||b|sin<a,b>
  • 满足右手法则 。从这点我们有axb ≠ bxa,而axb = – bxa。所以我们可以使用叉积的正负值来判断向量a,b的相对位置,即向量b是处于向量a的顺时针方向还是逆时针方向。
     

参考博文:

unity 判断位置在相机前还是后 unity判断两物体距离_叉积_12