9.3D数学-Vector3向量-向量插值运算
9.1 知识点
主要学习内容
线性插值
Lerp静态方法 在两点进行线性插值
Vector3.Lerp静态方法用于在两个点之间进行线性插值。
- 参数:起始点start、结束点end和插值系数t。
- 返回值:在起始点和结束点之间根据插值系数进行插值后的点。
- 先快后慢 每帧改变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);
球形插值
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