9.Vector3向量插值运算

9.3D数学-Vector3向量-向量插值运算


9.1 知识点

主要学习内容

线性插值


Lerp静态方法 在两点进行线性插值

Vector3.Lerp静态方法用于在两个点之间进行线性插值。

  • 参数:起始点start、结束点end和插值系数t。
  • 返回值:在起始点和结束点之间根据插值系数进行插值后的点。
  1. 先快后慢 每帧改变start位置 位置无限接近 但不会得到end位置
// 可以理解为t不变 每次往方向向量加的值(end - start)一直会变小
A.position = Vector3.Lerp(A.position, target.position, Time.deltaTime);
  1. 匀速 每帧改变时间 当t>=1时 得到结果
// 可以理解为t每一帧累加相同值 start和(end - start)不变 所以是匀速运动
// 这种匀速移动 当time>=1时  我改变了 目标位置后  它会直接瞬移到我们的目标位置 因为t>=1时直接的得到结果
// 所以要做特殊处理 每次改变目标位置时 清空时间
if (nowTarget != target.position)
{
    nowTarget = target.position;
    time = 0;
    startPos = B.position;
}
time += Time.deltaTime;
B.position = Vector3.Lerp(startPos, nowTarget, time);

球形插值


Slerp静态方法 在两点进行球形插值

Vector3.Slerp静态方法用于在两个向量之间进行球形插值。

  • 参数:起始向量from、目标向量to和插值系数t。
  • 返回值:在起始向量和目标向量之间根据插值系数进行球形插值后的向量。
time2 += Time.deltaTime;
C.position = Vector3.Slerp(Vector3.right * 10, Vector3.forward * 10, time2 * 0.1f);
// 位置会从(10,0,0)按球形轨迹慢慢的变到(0,10,0)

总结


9.2 知识点代码

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

public class Lesson09_3D数学_Vector3向量_向量插值运算 : MonoBehaviour
{
    public Transform target;
    public Transform A;
    public Transform B;
    public Transform C;

    private Vector3 startPos;
    private float time;
    private float time2;

    private Vector3 nowTarget;
    
    void Start()
    {
        startPos = B.position;
    }
    
    void Update()
    {
        #region 知识点一 线性插值

        //Lerp静态方法 在两点进行线性插值
        //在两个点之间进行线性插值。
        //公式和Mathf中的线性插值一样
        //result = start + (end - start) * newThread
        //但是Vector3中的是三维坐标,Mathf是一维变量

        //先快后慢 每帧改变start位置 位置无限接近 但不会得到end位置
        //可以理解为t不变 每次往方向向量加的值(end - start)一直会变小
        A.position = Vector3.Lerp(A.position, target.position, Time.deltaTime);

        //匀速 每帧改变时间  当t>=1时 得到结果
        //可以理解为t每一帧累加相同值 start和(end - start)不变 所以是匀速运动
        //这种匀速移动 当time>=1时  我改变了 目标位置后  它会直接瞬移到我们的目标位置 因为t>=1时直接的得到结果
        //所以要做特殊处理 每次改变目标位置时 清空时间
        if (nowTarget != target.position)
        {
            nowTarget = target.position;
            time = 0;
            startPos = B.position;
        }
        time += Time.deltaTime;
        B.position = Vector3.Lerp(startPos, nowTarget, time);

        #endregion

        #region 知识点二 球形插值

        //Slerp静态方法 在两点进行球形插值
        //在两个向量之间进行球形插值。
        time2 += Time.deltaTime;
        C.position = Vector3.Slerp(Vector3.right * 10, Vector3.forward * 10 , time2 * 0.1f);
        //位置会从(10,0,0)按球形轨迹慢慢的变到(0,10,0)

        #endregion
    }
}

9.3 练习题

用线性插值相关知识,实现摄像机跟随(摄像机不设置为对象子物体),摄像机一直在物体的后方4米,向上偏7米的位置

这是Lesson06向量加减乘除练习题的做法,现在是想慢慢按照插值规则动

// 摄像机的位置 等于目标的位置 进行向量偏移
// 先朝目标对象的面朝向的反方向平移4米 再朝目标的头顶位置 平移7米
// 设置摄像机位置
this.transform.position = target.position + -target.forward * zOffect + target.up * yOffect;

先快后慢的移动

// 如果当前摄像机的目标位置不是目标对象的后方4米,向上偏7米 就设置目标位置
if (cameraTargetPos != target.position + -target.forward * zOffect + target.up * yOffect)
{
    cameraTargetPos = target.position + -target.forward * zOffect + target.up * yOffect;
}
// 摄像机的位置 等于目标的位置 进行向量偏移
// 先朝目标对象的面朝向的反方向平移4米 再朝目标的头顶位置 平移7米
this.transform.position = Vector3.Lerp(this.transform.position, cameraTargetPos, Time.deltaTime * moveSpeed);

匀速移动

// 如果当前摄像机的目标位置不是目标对象的后方4米,向上偏7米 就设置目标位置 记录摄像机当前开始位置 重置时间
if (cameraTargetPos != target.position + -target.forward * zOffect + target.up * yOffect)
{
    cameraTargetPos = target.position + -target.forward * zOffect + target.up * yOffect;
    startPos = this.transform.position;
    time = 0;
}
time += Time.deltaTime;
this.transform.position = Vector3.Lerp(startPos, cameraTargetPos, time * moveSpeed);

通过球形插值模拟太阳的升降变化

private void Update()
{
    time2 += Time.deltaTime;
    // sun.position = Vector3.Slerp(Vector3.right * 10, Vector3.left * 10, time2 * 0.1f);//假如直接写最终值会不知道从哪里转 可能会平这转
    sun.position = Vector3.Slerp(Vector3.right * 10, Vector3.left * 10 + Vector3.up * 0.1f, time2 * 0.1f);//要给最终值加一点向上的向量 才会往上转
}

9.4 练习题代码

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

//这个脚本将要挂载到摄像机上 实现摄像机跟随
public class Lesson09_练习题 : MonoBehaviour
{
    #region 练习题一
    //用线性插值相关知识,实现摄像机跟随(摄像机不设置为对象子物体),摄像机一直在物体的后方4米,向上偏7米的位置


    public float zOffect = 4;
    public float yOffect = 7;
    public Transform target;

    private Vector3 cameraTargetPos;
    public float moveSpeed;
    private Vector3 startPos;
    private float time;



    void LateUpdate()
    {
        //这是Lesson06向量加减乘除练习题的做法 是直接赋值结果 现在是想慢慢按照插值规则动
        ////摄像机的位置 等于目标的位置 进行向量偏移
        ////先朝目标对象的 面朝向的反方向平移4米 再朝目标的头顶位置 平移7米
        ////设置摄像机位置
        //this.transform.position = target.position + -target.forward * zOffect + target.up * yOffect;


        //先快后慢的移动
        ////如果当前摄像机的目标位置不是目标对象的后方4米,向上偏7米 就设置目标位置
        //if (cameraTargetPos != target.position + -target.forward * zOffect + target.up * yOffect)
        //{
        //    cameraTargetPos = target.position + -target.forward * zOffect + target.up * yOffect;
        //}
        ////摄像机的位置 等于目标的位置 进行向量偏移
        ////先朝目标对象的 面朝向的反方向平移4米 再朝目标的头顶位置 平移7米
        //this.transform.position = Vector3.Lerp(this.transform.position, cameraTargetPos, Time.deltaTime * moveSpeed);


        //匀速移动
        //如果当前摄像机的目标位置不是目标对象的后方4米,向上偏7米 就设置目标位置 记录摄像机当前开始位置 重置时间
        if (cameraTargetPos != target.position + -target.forward * zOffect + target.up * yOffect)
        {
            cameraTargetPos = target.position + -target.forward * zOffect + target.up * yOffect;
            startPos = this.transform.position;
            time = 0;
        }
        time += Time.deltaTime;
        this.transform.position = Vector3.Lerp(startPos, cameraTargetPos, time * moveSpeed);


        this.transform.LookAt(target);
    }

    #endregion

    #region 练习题二
    //通过球形插值模拟太阳的升降变化

    public Transform sun;
    private float time2;
    private void Update()
    {
        time2 += Time.deltaTime;
        //sun.position = Vector3.Slerp(Vector3.right * 10, Vector3.left * 10, time2 * 0.1f);//假如直接写最终值会不知道从哪里转 可能会平这转
        sun.position = Vector3.Slerp(Vector3.right * 10, Vector3.left * 10 + Vector3.up * 0.1f, time2 * 0.1f);//要给最终值加一点向上的向量 才会往上转
    }

    #endregion

}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏