Unity入门学习(三)3D数学(3)之Vector3类的介绍

目录

一、什么是向量

二、向量的模长和单位向量

三、向量的加减乘除

四、向量的点乘

扇形视野检测

五、向量的叉乘

六、插值运算

 七、总结


一、什么是向量

几何意义
1、向量是具有方向和长度的数学对象,常用于表示位移、速度、力等方向性物理量。
2、点是位置,向量是方向+长度,两者在 Unity 中都可用 Vector3 表示,但语义不同。

代码中的 Vector3
Unity 的 Vector3 结构体表示三维向量,包含 x, y, z 三个分量。

例如:

Vector3 position = new Vector3(1, 2, 3);  // 表示点的位置
Vector3 direction = new Vector3(0, 1, 0); // 表示方向(例如:向上)
//A和B此时 几何意义是两个点
Vector3 A = new Vector3(1, 2, 3);
Vector3 B = new Vector3(4, 5, 6);
//求向量
Vector3 AB = B - A;
print(AB);
Vector3 BA = A - B;
print(BA);
//零向量和负向量
        Vector3 zero = Vector3.zero;
        Vector3 neg = -A;

二、向量的模长和单位向量

模长(Magnitude)
模长是向量的长度,计算公式:
|v| = sqrt(x² + y² + z²)

Vector3 v = new Vector3(3, 4, 0);
float length = v.magnitude; // 结果为5(勾股定理)

两个点之间的距离:

print(Vector3.Distance(A, B));

单位向量(Normalized)
方向相同但长度为1的向量,用于仅关注方向时。
归一化方法:

Vector3 normalizedV = v.normalized; // 返回新单位向量
v.Normalize(); // 将原向量归一化(直接修改v)

常用的单位向量 :

Vector3.zero      // (0, 0, 0) → 原点
Vector3.one       // (1, 1, 1) → 单位缩放
Vector3.forward   // (0, 0, 1) → Z轴正方向(物体前方)
Vector3.back      // (0, 0, -1)
Vector3.up        // (0, 1, 0) → Y轴正方向(物体上方)
Vector3.down      // (0, -1, 0)
Vector3.right     // (1, 0, 0) → X轴正方向(物体右侧)
Vector3.left      // (-1, 0, 0)

三、向量的加减乘除

向量的基本运算http://1.2 向量的基本运算(加减、数乘) - 白鲸的文章 - 知乎 https://zhuanlan.zhihu.com/p/615940607

加减法
几何意义:向量的合成与分解。矢量相加减,三角形法则或者平行四边形法则,加法就是减法。

Vector3 a = new Vector3(1, 2, 3);
Vector3 b = new Vector3(4, 5, 6);
Vector3 sum = a + b; // (5,7,9)
Vector3 diff = a - b; // (-3,-3,-3)

标量乘除
几何意义:缩放向量长度。

Vector3 v = new Vector3(1, 0, 0);
Vector3 doubled = v * 2; // (2,0,0) 长度变为2
Vector3 half = v / 2;    // (0.5,0,0)

四、向量的点乘

公式与几何意义
公式:a·b = |a||b|cosθ,结果为标量。

用途:
计算两向量夹角:θ = arccos(a·b / (|a||b|))
判断方向关系(同向/垂直/反向)。

1. a·b > 0(正数)
几何意义:两向量夹角为锐角(0° ≤ θ < 90°)。
方向关系:两向量大致同方向。

例如:

Vector3 forward = Vector3.forward; // (0,0,1)
Vector3 dir1 = new Vector3(0, 0, 0.5f); 
Vector3 dir2 = new Vector3(0, 0, -1f); 

float dot1 = Vector3.Dot(forward, dir1); // 0.5 > 0 → 同向
float dot2 = Vector3.Dot(forward, dir2); // -1 < 0 → 反向

2. a·b = 0
几何意义:两向量垂直(θ = 90°)。
应用场景:检测物体是否在侧面方向。

例如:

// 判断敌人是否在玩家正左侧/右侧
Vector3 playerRight = transform.right; // 玩家的右侧方向
Vector3 enemyDir = enemy.position - transform.position;
float dot = Vector3.Dot(playerRight, enemyDir);

if (Mathf.Approximately(dot, 0)) {//无限逼近0
    Debug.Log("敌人在正侧方!");
}

3. a·b < 0(负数)
几何意义:两向量夹角为钝角(90° < θ ≤ 180°)。
方向关系:两向量大致反方向。

例如:

Vector3 playerForward = transform.forward;
Vector3 enemyBehindDir = transform.position - enemy.position;

if (Vector3.Dot(playerForward, enemyBehindDir) < 0) {
    Debug.Log("敌人在后方!");
}

点加减向量等同于将点朝着向量的方向移动向量的长度那么远。

例如:

Vector3 a = new Vector3(1, 0, 0);
Vector3 b = new Vector3(0, 1, 0);
float dot = Vector3.Dot(a, b); // 0(垂直)

// 判断敌人是否在玩家前方
Vector3 playerForward = transform.forward;
Vector3 enemyDirection = enemy.position - player.position;
if (Vector3.Dot(playerForward, enemyDirection) > 0) {
    Debug.Log("敌人在前方!");
}

点乘与投影:轴偏移距离分析
点乘可以用来计算一个向量在另一个向量方向上的投影长度,从而判断“距某个轴向偏移了多远”。

公式
向量 a 在向量 b 方向上的投影长度为:
投影长度 = |a| * cosθ = (a·b) / |b|

// 计算物体在玩家正前方(z轴)的偏移距离
Vector3 playerForward = transform.forward; // 假设已归一化(长度=1)
Vector3 objectOffset = object.position - transform.position;

// 投影长度 = (objectOffset · playerForward) / |playerForward| 
// 因为 playerForward 是单位向量,分母为1,直接取点乘结果
float forwardDistance = Vector3.Dot(objectOffset, playerForward);

if (forwardDistance > 5) {
    Debug.Log("物体在玩家前方5米外");
} else if (forwardDistance < -3) {
    Debug.Log("物体在玩家后方3米外");
}
扇形视野检测
// 判断目标是否在玩家60度视野内
Vector3 toTarget = target.position - transform.position;
float dot = Vector3.Dot(transform.forward, toTarget.normalized);
float cosThreshold = Mathf.Cos(60 * Mathf.Deg2Rad); // 60度对应的cos值≈0.5

if (dot > cosThreshold) {
    Debug.Log("目标在视野内!");
}

五、向量的叉乘

公式与几何意义
公式:a × b 结果是一个新的向量,方向垂直于 a 和 b 所在平面,遵循右手法则。如图

用途:
计算平面法线(例如:地形法线)。
计算旋转轴(例如:绕轴旋转)。

例如判断叉乘后的向量和原先向量的相对位置:假设AB都是xz平面的线

        Vector3 C= Vector3.Cross(A.position, B.position);
        if (C.y > 0)
        {
            print("B在A的右侧");
        }
        else
        {
            print("B在A的左侧");
        }

六、插值运算

线性插值(Lerp)
作用:在两个向量之间按比例插值,实现平滑过渡。

数学原理
公式:
result=a+t×(b−a)
即直接沿直线从 a 到 b 按比例 t 插值。
特性:
t=0 时返回 a,t=1 时返回 b。
t 超出 [0,1] 时,结果会超出 a 到 b 的直线范围(如 t=2 会得到 b + (b-a))。

例如:

Vector3 start = Vector3.zero;
Vector3 end = new Vector3(10, 0, 0);
Vector3 result = Vector3.Lerp(start, end, 0.5f); // (5,0,0)

球形插值(Slerp)
作用:保持匀速的弧形插值,适合旋转或相机跟随。

输入参数:起点位置,目标位置,弧线移动过去

Vector3 from = transform.forward;
Vector3 to = target.position - transform.position;
Vector3 direction = Vector3.Slerp(from, to, Time.deltaTime * speed);
特性LerpSlerp
插值路径直线球面弧线
输入向量要求任意向量(无需归一化)必须为单位向量(归一化)
匀速性非匀速(线性距离变化)匀速(恒定角速度)
典型场景位置、颜色、缩放等非方向性数据方向、旋转等需要保持路径自然性的场景

 七、总结

 Unity Vector3 类的重要属性及 API 总结表

属性/API输入参数输出结果简单示例
Vector3.zero零向量 (0,0,0)Vector3 zero = Vector3.zero;
Vector3.one单位向量 (1,1,1)Vector3 one = Vector3.one;
Vector3.forward世界坐标系前向单位向量 (0,0,1)Vector3 dir = Vector3.forward;
Vector3.up世界坐标系上向单位向量 (0,1,0)Vector3 upDir = Vector3.up;
vector.magnitude向量的模长(长度)float len = new Vector3(3,4,0).magnitude; // 5
vector.normalized单位向量(不修改原向量)Vector3 norm = v.normalized;
vector.Normalize()将原向量归一化(直接修改)v.Normalize();
Vector3.Dot(a, b)两个 Vector3 向量点乘结果(标量)float dot = Vector3.Dot(a, b);
Vector3.Cross(a, b)两个 Vector3 向量叉乘结果(垂直向量)Vector3 cross = Vector3.Cross(a, b);
Vector3.Distance(a, b)两个 Vector3 点两点之间的直线距离float dist = Vector3.Distance(pointA, pointB);
Vector3.Lerp(a, b, t)起点 a,终点 b,比例 t线性插值后的向量Vector3 pos = Vector3.Lerp(start, end, 0.5f);
Vector3.Slerp(a, b, t)单位向量 a,单位向量 b,比例 t球面插值后的向量Vector3 dir = Vector3.Slerp(from, to, t);
运算符 + (a, b)两个 Vector3 向量向量相加结果Vector3 sum = a + b;
运算符 - (a, b)两个 Vector3 向量向量相减结果Vector3 diff = a - b;
运算符 * (v, scalar)向量 v,标量 scalar向量缩放后的结果Vector3 scaled = v * 2f;
运算符 / (v, scalar)向量 v,标量 scalar向量缩放后的结果Vector3 half = v / 2f;

就这样 再见

### Unity3D 学习路线图 #### 基础阶段 对于初学者来说,掌握C#编程语言的基础是非常重要的。因为Unity3D主要依赖于C#作为其脚本开发语言,在此过程中可以通过官方文档以及一些基础书籍来学习C#语法及其在Unity中的应用[^1]。 #### 中级阶段 当具备了一定的C#基础知识之后,可以深入研究如何优化游戏性能。这一步骤非常重要,尤其是在制作大型项目时。利用Unity内置的Profiler工具可以帮助开发者了解应用程序运行期间的各项资源消耗状况,进而定位潜在的性能瓶颈并实施针对性改进措施[^1]。 此外,关于场景管理方面,理解变换(Transform)组件的工作原理也十分必要。例如,如果需要动态调整对象的位置、旋转角度或者大小比例,则可能涉及到复杂的数学计算过程。此时可借助矩阵运算简化操作流程,并确保最终效果符合预期目标[^2]。 #### 高级阶段 进入高级领域前,建议阅读一系列经典教材以扩展视野和技术水平。这些资料涵盖了从着色器编写到实时渲染等多个方向的内容,能够帮助技术人员构建全面的知识体系: - **Shader入门精要**:适合初次接触图形学概念的人群; - **GPU阳春白雪与下里巴人**:提供了另一种视角看待硬件加速机制; - **3D Game Programming with DirectX**:虽然专注于DirectX API本身,但对于通用的游戏引擎架构设计同样具有指导意义; - **Real-Time Rendering**:被广泛认为是现代计算机图像处理领域的权威指南之一[^3]。 以上提到的所有知识点共同构成了完整的Unity3D技能树结构框架。 ```csharp // 示例代码展示简单的Transform修改方法 using UnityEngine; public class Example : MonoBehaviour { void Start() { Transform myTransform = transform; Vector3 newPosition = new Vector3(0, 5, 0); // 设置新位置 Quaternion newRotation = Quaternion.Euler(new Vector3(45, 90, 0)); // 定义新的旋转 Matrix4x4 localToWorldMatrix = myTransform.localToWorldMatrix; // 获取当前局部空间转换至全局空间的矩阵 Vector3 worldPositionOffset = localToWorldMatrix.MultiplyPoint(newPosition); myTransform.position += worldPositionOffset; // 更新实际位置 myTransform.rotation *= newRotation; // 应用额外旋转 } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FAREWELL00075

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值