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

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);
      
          }
      
      
      }
      
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容