Unity基礎-數學向量
二、向量相關用法
概述
向量在Unity游戲開發中扮演著重要角色,用于表示位置、方向、速度等。Unity提供了Vector2、Vector3等結構體來處理向量運算。
1. 向量基礎操作
1.1 向量創建和訪問
// 創建向量
Vector3 position = new Vector3(1, 2, 3);
Vector2 position2D = new Vector2(1, 2);// 訪問向量分量
float x = position.x;
float y = position.y;
float z = position.z;
1.2 向量運算
// 向量加減
Vector3 v1 = new Vector3(1, 2, 3);
Vector3 v2 = new Vector3(4, 5, 6);
Vector3 sum = v1 + v2; // 結果:(5, 7, 9)
Vector3 diff = v2 - v1; // 結果:(3, 3, 3)// 向量數乘
Vector3 scaled = v1 * 2; // 結果:(2, 4, 6)
2. 向量重要方法
2.1 向量點乘(Dot Product)
// 點乘用于計算兩個向量的夾角
float dot = Vector3.Dot(v1, v2);// 實際應用:判斷物體相對位置
// 如果點乘結果 > 0,表示物體在前方
// 如果點乘結果 < 0,表示物體在后方
if(Vector3.Dot(transform.forward, target.position - transform.position) > 0)
{print("目標在前方");
}
2.2 向量叉乘(Cross Product)
// 叉乘用于獲取垂直于兩個向量的向量
Vector3 cross = Vector3.Cross(v1, v2);// 實際應用:判斷左右方向
// 如果叉乘結果的y分量 > 0,表示在右側
// 如果叉乘結果的y分量 < 0,表示在左側
if(Vector3.Cross(transform.forward, target.position - transform.position).y > 0)
{print("目標在右側");
}
2.3 向量夾角計算
// 方法1:使用點乘和反三角函數
float dot = Vector3.Dot(v1.normalized, v2.normalized);
float angle = Mathf.Acos(dot) * Mathf.Rad2Deg;// 方法2:直接使用Vector3.Angle
float angle = Vector3.Angle(v1, v2);
3. 向量插值
3.1 線性插值(Lerp)
// 在兩個向量之間進行線性插值
Vector3 result = Vector3.Lerp(start, end, t); // t的范圍是[0,1]
3.2 球形插值(Slerp)
// 在兩個向量之間進行球形插值,保持勻速旋轉
Vector3 result = Vector3.Slerp(start, end, t);
4. 向量常用屬性
Vector3 v = new Vector3(3, 4, 0);// 向量長度
float magnitude = v.magnitude; // 結果:5// 向量平方長度(性能更好)
float sqrMagnitude = v.sqrMagnitude; // 結果:25// 單位向量
Vector3 normalized = v.normalized; // 結果:(0.6, 0.8, 0)// 零向量
Vector3 zero = Vector3.zero; // 結果:(0, 0, 0)// 單位向量
Vector3 one = Vector3.one; // 結果:(1, 1, 1)
5. 實際應用示例
5.1 物體跟隨
// 使用Vector3.Lerp實現平滑跟隨
transform.position = Vector3.Lerp(transform.position, target.position, Time.deltaTime * speed);
5.2 方向檢測
// 檢測目標是否在視野范圍內
Vector3 directionToTarget = target.position - transform.position;
float angle = Vector3.Angle(transform.forward, directionToTarget);
if(angle < viewAngle && directionToTarget.magnitude < viewDistance)
{print("目標在視野范圍內");
}
5.3 巡邏檢測
// 檢測目標是否在特定區域內
if(Vector3.Dot(transform.forward, target.position - transform.position) > 0)
{if(Vector3.Cross(transform.forward, target.position - transform.position).y > 0){if(Vector3.Angle(transform.forward, target.position - transform.position) < 30 &&Vector3.Distance(transform.position, target.position) < 5){print("發現目標");}}
}
6. 調試工具
// 繪制線段
Debug.DrawLine(start, end, Color.red);// 繪制射線
Debug.DrawRay(origin, direction, Color.blue);
7. 使用建議
-
性能優化:
- 優先使用sqrMagnitude代替magnitude
- 避免頻繁創建新的Vector3實例
- 合理使用向量緩存
-
精度控制:
- 使用Mathf.Approximately比較浮點數
- 注意向量運算的精度損失
-
常見陷阱:
- 注意向量歸一化時的零向量情況
- 注意叉乘的方向性
- 注意角度計算的范圍限制