找回密码
 立即注册
查看: 325|回复: 0

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

[复制链接]
发表于 2022-5-28 17:13 | 显示全部楼层 |阅读模式
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.Rad2DegMathf.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.DistanceVector3.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开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-11-16 06:44 , Processed in 0.088342 second(s), 25 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表