一、向量
1.标量
含义:有数值大小,没有方向
2.向量
含义:有数值大小,有方向的矢量
种类:一维,二维,三维

注意:向量在空间中有无数条,并且可以随意移动
3.向量的计算
A点:(Xa,Ya,Za) B点:(Xb,Yb,Zb)
从A指向B的向量为AB向量 :B-A = (Xb-Xa, Yb-Ya, Zb-Za)
从B指向A的向量为BA向量 :A-B = (Xa-Xb, Ya-Yb, Za-Zb)
计算方法:终点减起点
4.零向量
写法:(0,0,0)
注意:零向量是唯一一个大小为0的向量
5.负向量
写法:(x,y,z)的负向量为(-x,-y,-z)
注意:
(1)负向量和原向量大小相等
(2)负向量和原向量方向相反
6.向量的模长
含义:是向量的长度(向量的模长就是两个点的距离)
模长公式:模长= √x² + y² + z
7.单位向量
含义:模长为1的向量
注意:任意一个向量经过归一化就是单位向量
归一化公式:
(1)模长 = √x² + y² + z²
(2)单位向量 = (x/模长, y/模长, z/模长)
二、向量练习题
1.Unity中判断两点之间距离有几种方式?
(1)使用 Vector3.Distance () 方法
- 这是 Unity 提供的专门用于计算两点距离的 API
- 语法:
Vector3.Distance(点1的位置, 点2的位置) - 代码示例:
print(Vector3.Distance(A.position, B.position));
(2)计算两点向量差的模长(magnitude)
- 先计算两点之间的向量差(点 B - 点 A 或 点 A - 点 B)
- 再通过向量的 magnitude 属性获取该向量的长度(即两点距离)
2.计算向量(3,4,5)的模长(手写)

3.计算向量 (3,-4) 的单位向量(手写)

三、向量加减乘除
1.向量加法
(1)计算公式

(2)计算意义

【1】两个位置相加没有意义
【2】两个向量相加得到一个新向量
口诀: 向量相加,首尾相连
【3】位置加向量得到一个新位置
口诀: 位置和向量相加=平移位置
2.向量减法
(1)计算公式

(2)意义

【1】两个位置相减得到一个新向量
口诀:两点决定一向量 终点 - 起点
【2】两个向量相减得到一个新向量
口诀:向量相减,头连头,尾指尾 A - B = B头指A头
【3】位置减向量相当于 加负向量
口诀: 位置减向量 = 平移位置
【4】向量减位置没有任何意义
3.向量乘除法
(1)公式

(2)意义

四、向量基础运算练习题
1.题目
用向量相关知识,实现摄像机跟随(摄像机不设置为对象子物体)
摄像机一直在物体的后方4米,向上偏7米的位置
2.实现
(1)效果
摄像机跟随
(2)代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class test3CameraMove : MonoBehaviour
{
public float zOffect = 4;
public float yOffect = 7;
public Transform target;
void Start()
{
}
void LateUpdate()
{
this.transform.position = target.position + -target.forward * zOffect + target.up * yOffect;
this.transform.LookAt(target);
}
}
五、向量点乘
1.点乘计算公式

2.点乘的几何意义

3.点乘公式推导

4.代码演示
(1)补充函数
【1】画线段(前两个参数 分别是 起点 终点)
Debug.DrawLine(this.transform.position, this.transform.position + this.transform.forward, Color.red);
【2】画射线(前两个参数 分别是 起点 方向)
Debug.DrawRay(this.transform.position, this.transform.forward, Color.white);
(2)通过点乘判断对象方位
float dotResult = Vector3.Dot(this.transform.forward, target.position - this.transform.position);
if( dotResult >= 0 )
{
print("它在我前方");
}
else
{
print("它在我后方");
}
(3)通过点乘推导公式算出夹角
//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));
六、向量点乘练习题
1.题目
当一个物体B在物体A前方45度角范围内,并且离A只有5米距离
时,在控制台打印“发现入侵者”

2.实现
(1)演示
检测敌人
(2)代码实现
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class test4Check : MonoBehaviour
{
public Transform Target;
private void Update()
{
Debug.DrawLine(transform.position, Target.position, Color.red);
Debug.Log("角度" + Vector3.Angle(this.transform.forward, Target.transform.position - this.transform.position));
if (Vector3.Distance(this.transform.position, Target.transform.position) <= 5 &&
Vector3.Angle(this.transform.forward, Target.transform.position - this.transform.position) <= 22.5f)
{
print("发现入侵者");
}
}
}
七、向量叉乘
1.叉乘计算公式
向量 x 向量 = 向量
向量A (Xa,Ya,Za)
向量B (Xb,Yb,Zb)
A x B = (X,Y,Z)
X = YaZb - ZaYb
Y = ZaXb - XaZb
Z = XaYb - YaXb

2.叉乘的几何意义
A x B 得到的向量同时垂直A和B
A x B 向量垂直于A和B组成的平面
A x B = -(B x A)
1.得到一个平面的法向量
Vector3.Cross(A.position, B.position)
2.得到两个向量之间的左右位置关系
//假设向量 A和B 都在 XZ平面上
//向量A 叉乘 向量 B
//y大于0 证明 B在A右侧
//y小于0 证明 B在A左侧
Vector3 C = Vector3.Cross(A.position, B.position);
if( C.y > 0)
{
print("B在A的右侧");
}
else
{
print("B在A的左侧");
}
八、向量叉乘的习题
1.题目
(1)判断一个物体B位置再另一个物体A的位置的左上,左下 ,右上,右下哪个方位
(2)当一个物体B在物体A左前方20度角或右前方30度范围内,并且离A只有5米距离时, 在控制台打印“发现入侵者
2.实现
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FindEnemy2 : MonoBehaviour
{
public Transform A;
public Transform B;
// Start is called before the first frame update
void Start()
{
}
private float dotResult;
private Vector3 crossResult;
// Update is called once per frame
void Update()
{
//第一题
dotResult = Vector3.Dot(A.forward, B.position - A.position);
crossResult = Vector3.Cross(A.forward, B.position - A.position);
//判断前后
if (dotResult >= 0 )
{
//右侧
if(crossResult.y >= 0)
{
print("右前");
}
//左侧
else
{
print("左前");
}
}
else
{
//右侧
if (crossResult.y >= 0)
{
print("右后");
}
//左侧
else
{
print("左后");
}
}
//第二题
if( Vector3.Distance(A.position, B.position) <= 5 )
{
if( crossResult.y >= 0 && Vector3.Angle(A.forward, B.position - A.position) <= 30 ||
crossResult.y < 0 && Vector3.Angle(A.forward, B.position - A.position) <= 20)
{
print("发现入侵者");
}
}
}
}
九、向量插值运算
1.线性插值
(1)语法
Vector3.Lerp(start, end, t);
//1.先快后慢 每帧改变start位置 位置无限接近 但不会得到end位置
A.position = Vector3.Lerp(A.position, target.position, Time.deltaTime);
//2.匀速 每帧改变时间 当t>=1时 得到结果
//这种匀速移动 当time>=1时 我改变了 目标位置后 它会直接瞬移到我们的目标位置
if(nowTarget != target.position)
{
nowTarget = target.position;
time = 0;
startPos = B.position;
}
time += Time.deltaTime;
B.position = Vector3.Lerp(startPos, nowTarget, time);
#endregion
(2)意义
对两个点进行插值计算 t的取值范围为0~1
(3)公式
公式:result = start + (end - start) * t
(4)应用
1.每帧改变start的值(先快后慢)
2.每帧改变t的值(匀速)
2.球形插值
(1)语法
Vector3.Slerp(start, end, t);
C.position = Vector3.Slerp(Vector3.right * 10, Vector3.left * 10 + Vector3.up*0.1f, time*0.01f);
(2)意义
对两个向量进行插值计算 t的取值范围为0~1
(3)区别

十、向量插值练习题
1.题目

2.实现
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraMove : MonoBehaviour
{
public float zOffect = 4;
public float yOffect = 7;
public Transform target;
private Vector3 targetPos;
public float moveSpeed;
private Vector3 startPos;
private float time;
// Start is called before the first frame update
void Start()
{
}
void LateUpdate()
{
//先快后慢的移动
//if(targetPos != target.position + -target.forward * zOffect + target.up * yOffect)
//{
// targetPos = target.position + -target.forward * zOffect + target.up * yOffect;
//}
////摄像机的位置 等于目标的位置 进行向量偏移
////先朝目标对象的 面朝向的反方向平移4米 再朝目标的头顶位置 平移7米
//this.transform.position = Vector3.Lerp(this.transform.position, targetPos, Time.deltaTime*moveSpeed);
//匀速移动
if (targetPos != target.position + -target.forward * zOffect + target.up * yOffect)
{
targetPos = target.position + -target.forward * zOffect + target.up * yOffect;
startPos = this.transform.position;
time = 0;
}
time += Time.deltaTime;
this.transform.position = Vector3.Lerp(startPos, targetPos, time* moveSpeed);
this.transform.LookAt(target);
}
}
1708

被折叠的 条评论
为什么被折叠?



