美文网首页
Unity基础【唐老狮】(一)3D数学基础,向量

Unity基础【唐老狮】(一)3D数学基础,向量

作者: Die时而动 | 来源:发表于2022-05-28 17:24 被阅读0次

    Unity基础

    概述&个人总结

    基础知识点

    3D数学-基础

    • 基础数学函数
    • 插值运算Lerp:根据系数输出中间值
      • 先快后慢接近最终值
      • 匀速到达最终值
      #region 知识点四 Mathf中的常用方法——一般不停计算
          //插值运算 - Lerp
      
          //Lerp函数公式
          //result = Mathf.Lerp(start, end, t);
      
          //t为插值系数,取值范围为 0~1
          //result = start + (end - start)*t
      
          //插值运算用法一
          //每帧改变start的值——变化速度先快后慢,位置无限接近,但是不会得到end位置
          start = Mathf.Lerp(start, 10, Time.deltaTime);
      
          //插值运算用法二
          //每帧改变t的值——变化速度匀速,位置每帧接近,当t>=1时,得到结果
          time += Time.deltaTime;
          result = Mathf.Lerp(start, 10, time);
          #endregion
      
    • 三角函数
      • 角度和弧度
        • Mathf.Rad2Deg
        • Mathf.Deg2Rad
      • 三角函数
      • 三角函数曲线
      • 反三角函数
        • Asin,Acos
      • 练习:物体曲线移动
    • 坐标系
      • 世界坐标系
      • 物体坐标系
      • 屏幕坐标系
      • 视口坐标系
      • 坐标转换
        • Camera.main
      #region 知识点一 世界坐标系
          //目前学习的和世界坐标系相关的
          //this.transform.position;
          //this.transform.rotation;
          //this.transform.eulerAngles;
          //this.transform.lossyScale;
          //修改他们 会是相对世界坐标系的变化
          #endregion
      
          #region 知识点二 物体坐标系
          //相对父对象的物体坐标系的位置 本地坐标 相对坐标
          //this.transform.localPosition;
          //this.transform.localEulerAngles;
          //this.transform.localRotation;
          //this.transform.localScale;
          //修改他们 会是相对父对象物体坐标系的变化
          #endregion
      
          #region 知识点三 屏幕坐标系
          //Input.mousePosition
          //Screen.width;
          //Screen.height;
          #endregion
      
          #region 知识点四 视口坐标系
          //摄像机上的 视口范围
          #endregion
      
          #region 坐标转换相关
          //世界转本地
          //this.transform.InverseTransformDirection
          //this.transform.InverseTransformPoint
          //this.transform.InverseTransformVector
      
          //本地转世界
          //this.transform.TransformDirection
          //this.transform.TransformPoint  
          //this.transform.TransformVector
      
          //世界转屏幕
          //Camera.main.WorldToScreenPoint
          //屏幕转世界
          //Camera.main.ScreenToWorldPoint
      
          //世界转视口
          //Camera.main.WorldToViewportPoint
          //视口转世界
          //Camera.main.ViewportToWorldPoint
      
          //视口转屏幕
          //Camera.main.ViewportToScreenPoint
          
          //屏幕转视口
          //Camera.main.ScreenToViewportPoint;
      

    3D数学-向量

    • 向量模长和单位向量
      • 向量基础
      • 向量模长magnitude
      • 单位向量normalized
      public class Lesson4 : MonoBehaviour
      

    {
    // Start is called before the first frame update
    void Start()
    {
    #region 知识点一 向量
    //三维向量 - Vector3
    //Vector3有两种几何意义
    //1.位置 —— 代表一个点
    print(this.transform.position);

        //2.方向 —— 代表一个方向
        print(this.transform.forward);
        print(this.transform.up);
    
        Vector3 v = new Vector3(1, 2, 3);
        Vector2 v2 = new Vector2(1, 2);
        #endregion
    
        #region 知识点二 两点决定一向量
        //A和B此时 几何意义 是两个点
        Vector3 A = new Vector3(1, 2, 3);
        Vector3 B = new Vector3(5, 1, 5);
        //求向量
        //此时 AB和 BA 他们的几何意义 是两个向量
        Vector3 AB = B - A;
        Vector3 BA = A - B;
        #endregion
    
        #region 知识点三 零向量和负向量
        print(Vector3.zero);
    
        print(Vector3.forward);
        print(-Vector3.forward);
        #endregion
    
        #region 知识点四 向量的模长
        //Vector3中提供了获取向量模长的成员属性
        //magnitude
        print(AB.magnitude);
        Vector3 C = new Vector3(5, 6, 7);
        print(C.magnitude);
    
        print(Vector3.Distance(A, B));
    
        #endregion
    
        #region 知识点五 单位向量
        //Vector3中提供了获取单位向量的成员属性
        //normalized
        print(AB.normalized);
        print(AB / AB.magnitude);
        #endregion
    }
    
    //总结
    //1.Vector3这边变量 可以表示一个点 也可以表示一个向量 具体表示什么 是根据我们的具体需求和逻辑决定
    //2.如何在Unity里面得到向量 重点减起点 就可以得到向量  点C也可以代表向量 代表的就是 OC向量 O是坐标系原点
    //3.得到了向量 就可以利用 Vector3中提供的 成员属性 得到模长和单位向量
    //4.模长相当于可以得到 两点之间的距离  单位向量 主要是用来进行移动计算的 它不会影响我们想要的移动效果
    ```
    
    • 向量加减乘除
      • 练习:使摄像机始终保持在物体后面一段距离
        • 注意摄像机移动放在LateUpdate()生命周期函数内
    • 向量点乘
      • 点乘公式:结果是标量
      • 点乘几何意义
        • 带符号投影的长度
      • 使用点乘
        • 判断对象方位
          • 投影为正在前方,投影为负在后方
        • 计算两个向量之间的夹角
          • 单位向量点乘结果为cos夹角
          • 用反三角函数得出弧度
          • 弧度换算角度
      • 代码
         #region 补充知识 调试画线
        //画线段 
        //前两个参数 分别是 起点 终点
        //Debug.DrawLine(this.transform.position, this.transform.position + this.transform.forward, Color.red);
        //画射线
        //前两个参数 分别是 起点 方向
        //Debug.DrawRay(this.transform.position, this.transform.forward, Color.white);
        #endregion
        
        #region 知识点一 通过点乘判断对象方位
        //Vector3 提供了计算点乘的方法
        Debug.DrawRay(this.transform.position, this.transform.forward, Color.red);
        Debug.DrawRay(this.transform.position, target.position - this.transform.position, Color.red);
        //得到两个向量的点乘结果
        //向量 a 点乘 AB 的结果
        float dotResult = Vector3.Dot(this.transform.forward, target.position - this.transform.position);
        if( dotResult >= 0 )
        {
            print("它在我前方");
        }
        else
        {
            print("它在我后方");
        }
        #endregion
        
        #region 知识点二 通过点乘推导公式算出夹角
        //步骤
        //1.用单位向量算出点乘结果
        dotResult = Vector3.Dot(this.transform.forward, (target.position - this.transform.position).normalized);
        //2.用反三角函数得出角度
        print("角度-" + Mathf.Acos(dotResult) * Mathf.Rad2Deg);
        
        //Vector3中提供了 得到两个向量之间夹角的方法 
        print("角度2-" + Vector3.Angle(this.transform.forward, target.position - this.transform.position));
        #endregion
        
      • 练习:检测前方45度角,5米距离内的物体
        • 手动根据算
        • 使用API
          • Vector3.Distance
          • Vector3.Angle
    • 向量叉乘
      • 叉乘公式
      • 叉乘几何意义
        • 垂直于平面的法向量
      • 使用叉乘
        • 判断两个向量之间的左右位置关系
          Vector3 C = Vector3.Cross(B.position, A.position);
          if (C.y > 0)
          {
              print("A在B的右侧");
          }
          else
          {
              print("A在B的左侧");
          }
      
      • 练习
        • 判断大致方位
        • 判断具体方位左20右30度距离5m
      public class DetectDirction : MonoBehaviour
      {
          //- 判断大致方位
          //- 判断具体方位及距离
          public Transform cube;
          private Vector3 myDir;
          private Vector3 cube2me;
          private float dot;
          private Vector3 cross;
          // Start is called before the first frame update
          void Start()
          {
              myDir = this.transform.forward;
          }
      
          // Update is called once per frame
          void Update()
          {
              cube2me = cube.transform.position - this.transform.position;
      
              //判断大致方位
              dot = Vector3.Dot(myDir, cube2me);
              cross = Vector3.Cross(myDir, cube2me);
              if (dot > 0 && cross.y > 0) 
              {
                  Debug.Log("在右上");
              }
              if (dot < 0 && cross.y < 0)
              {
                  Debug.Log("在左下");
              }
              if (dot > 0 && cross.y < 0)
              {
                  Debug.Log("在左上");
              }
              if (dot < 0 && cross.y > 0)
              {
                  Debug.Log("在右下");
              }
      
              //判断具体方位左20右30度距离5m
              float distance = Vector3.Distance(this.transform.position, cube.position);
              //float angle = Vector3.Angle(myDir, cube2me);
              float angle = Mathf.Acos(Vector3.Dot(this.transform.forward.normalized, cube2me.normalized)) * Mathf.Rad2Deg;
              Debug.Log("角度" + angle);
              if (distance < 5 && (angle < 20 && cross.y < 0) || (angle < 30 && cross.y > 0))
              {
                  Debug.Log("侦测到左20右30度距离5m的方块");
              }
          }
      }
      
    • 向量插值运算
      • 线性插值
        • 变速直线运动
        • 匀速直线运动
      • 球形插值
        • 变速弧线运动
        • 匀速弧线运动
      • 练习题
        • 设置摄像机变速跟随
        • 模拟太阳升降
          • 给一定角度,突出立体下哪一个平面
        public class CameraFollow : MonoBehaviour
        {
            //摄像机跟随
            public float zOffect = 4;
            public float yOffect = 7;
            public Transform target;
        
            //变速跟随
            private Vector3 targetCameraPos;
            public float moveSpeed = 1;
            //匀速跟随
            private float time = 0;
            private Vector3 startPos;
            //模拟太阳
            public Transform sun;
        
            // Start is called before the first frame update
            void Start()
            {
                //初始化摄像机位置
                this.transform.position = targetCameraPos = target.position - target.forward * zOffect + target.up * yOffect;
            }
        
            // Update is called once per frame
            void Update()
            {
                ////变速跟随
                ///targetCameraPos = target.position - target.forward * zOffect + target.up * yOffect;
                //this.transform.position = Vector3.Lerp(this.transform.position, targetCameraPos, Time.deltaTime * moveSpeed);
                //this.transform.LookAt(target);
        
                //匀速跟随
                if (targetCameraPos != target.position - target.forward * zOffect + target.up * yOffect)
                {
                    targetCameraPos = target.position - target.forward * zOffect + target.up * yOffect;
                    startPos = this.transform.position;
                    Debug.Log("终点改变");
                    time = 0;
                }
                time += Time.deltaTime;//默认一秒
                this.transform.position = Vector3.Lerp(startPos, targetCameraPos, time * moveSpeed);
                this.transform.LookAt(target);
        
                //模拟太阳
                sun.position = Vector3.Slerp(Vector3.right * 10, Vector3.left * 10 + Vector3.up * 0.1f, time * moveSpeed);
        
            }
        
        
        }
        

    相关文章

      网友评论

          本文标题:Unity基础【唐老狮】(一)3D数学基础,向量

          本文链接:https://www.haomeiwen.com/subject/edaiprtx.html