Vector3 三维向量

结构体类型

表示 3D的 向量和点。

这个结构用于在 Unity 传递 3D 位置和方向。它包含向量运算的函数。

静态变量
up(0, 1, 0)
down(0, -1, 0)
forward(0, 0, 1)
back(0, 0, -1)
left(-1, 0, 0)
right(1, 0, 0)
zero(0, 0, 0)
one(1, 1, 1)

变量说明
magnitude返回向量的长度(只读)。
normalized返回该向量方向上的长度为1的向量(只读)。
sqrMagnitude返回这个向量的长度的平方(只读)。
this[int]使用[0], [1], [2]分别访问该向量的 x, y, z 元素。
x向量的 x 元素
y向量的 y 元素
z向量的 z 元素

静态方法说明
Angle返回两个向量之间的夹角。
ClampMagnitude返回的向量的长度,最大不超过 maxLength 所指示的长度。
Distance返回两个点之间的距离。
Cross计算两个向量的叉乘。
Dot计算两个向量的点乘。
MoveTowards当前的地点移向目标。
Max返回一个由两个向量的最大元素组成的向量。
Min返回一个由两个向量的最小元素组成的向量。
Lerp两个点之间的线性插值。
LerpUnclamped两个向量之间的线性插值。该插值t在小于0或大于1时的返回值不会被限制。
Normalize使向量的长度为1。
Project投影一个向量到另一个向量。
ProjectOnPlane投影向量到一个平面上(由垂直到该平面的法线定义)。
Reflect沿着法线反射向量。
SmoothDamp随着时间的推移,逐渐改变一个向量朝向预期的目标。
RotateTowards当前的向量转向目标。
OrthoNormalize使向量规范化并且彼此相互垂直。
Scale两个矢量组件对应相乘。
Slerp在两个向量之间球形插值。
SlerpUnclamped在两个向量之间球形插值。该插值t在小于0或大于1时的返回值不会被限制。

Vector3.ClampMagnitude

返回原向量的拷贝,并且它的模最大不超过maxLength所指示的长度。也就是说,限制向量长度到一个特定的长度。

示例:

  1. using UnityEngine;
  2. using System.Collections;
  3. public class ExampleClass : MonoBehaviour {
  4. public Vector3 centerPt;
  5. public float radius;
  6. void Update() {
  7. Vector3 movement = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
  8. Vector3 newPos = transform.position + movement;
  9. Vector3 offset = newPos - centerPt;
  10. transform.position = centerPt + Vector3.ClampMagnitude(offset, radius);
  11. }
  12. }

Vector3.Dot 点乘

两个向量的点乘积。点积是一个浮点型的值,两个向量的长度相乘,然后乘以它们之间夹角的余弦值。对于normalized向量,如果他们指向在完全相同的方向,Dot返回1。如果他们指向完全相反的方向,返回-1。对于其他的情况返回一个数(例如:如果是垂直的Dot返回0)。

示例:

  1. using UnityEngine;
  2. using System.Collections;
  3. public class ExampleClass : MonoBehaviour {
  4. public Transform other;
  5. void Update() {
  6. if (other) {
  7. Vector3 forward = transform.TransformDirection(Vector3.forward);
  8. Vector3 toOther = other.position - transform.position;
  9. if (Vector3.Dot(forward, toOther) < 0)
  10. print("The other transform is behind me!");
  11. }
  12. }
  13. }

Vector3.Cross 叉乘

两个向量的交叉乘积。两个向量的叉积乘积结果在垂直于两个输入向量的三分之一个向量。结果的大小等于两个输入相乘,然后乘以输入向量之间的角度的正弦值。你可以确定的方向的结果向量使用“左手法则”。

 2.4 Vector3  - 图1示例:

  1. using UnityEngine;
  2. using System.Collections;
  3. public class ExampleClass : MonoBehaviour {
  4. Vector3 GetNormal(Vector3 a, Vector3 b, Vector3 c) {
  5. Vector3 side1 = b - a;
  6. Vector3 side2 = c - a;
  7. return Vector3.Cross(side1, side2).normalized;
  8. }
  9. }

Vector3.Lerp 线性差值

两个向量之间的线性插值。按照分数t在from到to之间插值。这是最常用的寻找一点沿一条线的两个端点之间一些分数的方式(例如,在那些点之间逐渐移动一个对象)。这分数是在范围[ 0…1]。t是夹在 [0…1]之间,当t = 0时,返回from,当t = 1时,返回to。当t = 0.5 返回from和to的中间点。

示例:

  1. using UnityEngine;
  2. using System.Collections;
  3. public class ExampleClass : MonoBehaviour {
  4. public Transform startMarker;
  5. public Transform endMarker;
  6. public float speed = 1.0F;
  7. private float startTime;
  8. private float journeyLength;
  9. void Start() {
  10. startTime = Time.time;
  11. journeyLength = Vector3.Distance(startMarker.position, endMarker.position);
  12. }
  13. void Update() {
  14. float distCovered = (Time.time - startTime) * speed;
  15. float fracJourney = distCovered / journeyLength;
  16. transform.position = Vector3.Lerp(startMarker.position, endMarker.position, fracJourney);
  17. }
  18. }

Vector3.Slerp 球形差值

两个向量之间的弧形插值通过t数值在from和to之间插值。这与线性内插之间的不同(即, “线性插值” )是该向量被视为方向而不是空间中的点。返回的向量的方向是由角内插,其大小是from和to的幅度之间进行内插。

示例:

  1. using UnityEngine;
  2. using System.Collections;
  3. public class ExampleClass : MonoBehaviour {
  4. public Transform sunrise;
  5. public Transform sunset;
  6. public float journeyTime = 1.0F;
  7. private float startTime;
  8. void Start() {
  9. startTime = Time.time;
  10. }
  11. void Update() {
  12. Vector3 center = (sunrise.position + sunset.position) * 0.5F;
  13. center -= new Vector3(0, 1, 0);
  14. Vector3 riseRelCenter = sunrise.position - center;
  15. Vector3 setRelCenter = sunset.position - center;
  16. float fracComplete = (Time.time - startTime) / journeyTime;
  17. transform.position = Vector3.Slerp(riseRelCenter, setRelCenter, fracComplete);
  18. transform.position += center;
  19. }
  20. }

Vector3.MoveTowards

当前的地点移向目标。这个函数的返回值是一个点maxdistancedelta单位更接近于目标/点沿着当前的和目标之间的线。如果目标是比maxdistancedelta /然后返回值将等于目标接近(即移动不会超过目标)。maxdistancedelta负值可以用来从目标推开该向量。

示例:

  1. using UnityEngine;
  2. using System.Collections;
  3. public class ExampleClass : MonoBehaviour {
  4. public Transform target;
  5. public float speed;
  6. void Update() {
  7. float step = speed * Time.deltaTime;
  8. transform.position = Vector3.MoveTowards(transform.position, target.position, step);
  9. }
  10. }

Vector3.SmoothDamp

随着时间的推移,逐渐改变一个向量朝向预期的目标。向量由一些像弹簧阻尼器函数平滑,这将永远不会超过。最常见的用途是相机平滑跟随。

示例:

  1. using UnityEngine;
  2. using System.Collections;
  3. public class ExampleClass : MonoBehaviour {
  4. public Transform target;
  5. public float smoothTime = 0.3F;
  6. private Vector3 velocity = Vector3.zero;
  7. void Update() {
  8. Vector3 targetPosition = target.TransformPoint(new Vector3(0, 5, -10));
  9. transform.position = Vector3.SmoothDamp(transform.position, targetPosition, ref velocity, smoothTime);
  10. }
  11. }

Vector3.RotateTowards 转向

当前的向量转向目标。

这个函数类似于MoveTowards除了将向量被视为一个方向,而不是一个位置上。当前向量将被旋转朝向目标方向由maxRadiansDelta的角度,虽然会恰好落在目标,而不是超过。如果当前的大小和目标的是不同的,那么结果的幅度将被线性地旋转过程中进行插值。如果一个负值用于maxRadiansDelta ,向量会转离目标/直到它指向完全相反的方向,然后停止。

示例:

  1. using UnityEngine;
  2. using System.Collections;
  3. public class ExampleClass : MonoBehaviour {
  4. public Transform target;
  5. public float speed;
  6. void Update() {
  7. Vector3 targetDir = target.position - transform.position;
  8. float step = speed * Time.deltaTime;
  9. Vector3 newDir = Vector3.RotateTowards(transform.forward, targetDir, step, 0.0F);
  10. Debug.DrawRay(transform.position, newDir, Color.red);
  11. transform.rotation = Quaternion.LookRotation(newDir);
  12. }
  13. }

源码

  1. using System;
  2. using System.Runtime.InteropServices;
  3. using scm = System.ComponentModel;
  4. using uei = UnityEngine.Internal;
  5. namespace UnityEngine
  6. {
  7. // Representation of 3D vectors and points.
  8. [StructLayout(LayoutKind.Sequential)]
  9. public partial struct Vector3
  10. {
  11. public const float kEpsilon = 0.00001F;
  12. // X component of the vector.
  13. public float x;
  14. // Y component of the vector.
  15. public float y;
  16. // Z component of the vector.
  17. public float z;
  18. // Linearly interpolates between two vectors.
  19. public static Vector3 Lerp(Vector3 a, Vector3 b, float t)
  20. {
  21. t = Mathf.Clamp01(t);
  22. return new Vector3(
  23. a.x + (b.x - a.x) * t,
  24. a.y + (b.y - a.y) * t,
  25. a.z + (b.z - a.z) * t
  26. );
  27. }
  28. // Linearly interpolates between two vectors without clamping the interpolant
  29. public static Vector3 LerpUnclamped(Vector3 a, Vector3 b, float t)
  30. {
  31. return new Vector3(
  32. a.x + (b.x - a.x) * t,
  33. a.y + (b.y - a.y) * t,
  34. a.z + (b.z - a.z) * t
  35. );
  36. }
  37. // Moves a point /current/ in a straight line towards a /target/ point.
  38. public static Vector3 MoveTowards(Vector3 current, Vector3 target, float maxDistanceDelta)
  39. {
  40. Vector3 toVector = target - current;
  41. float dist = toVector.magnitude;
  42. if (dist <= maxDistanceDelta || dist < float.Epsilon)
  43. return target;
  44. return current + toVector / dist * maxDistanceDelta;
  45. }
  46. [uei.ExcludeFromDocs]
  47. public static Vector3 SmoothDamp(Vector3 current, Vector3 target, ref Vector3 currentVelocity, float smoothTime, float maxSpeed)
  48. {
  49. float deltaTime = Time.deltaTime;
  50. return SmoothDamp(current, target, ref currentVelocity, smoothTime, maxSpeed, deltaTime);
  51. }
  52. [uei.ExcludeFromDocs]
  53. public static Vector3 SmoothDamp(Vector3 current, Vector3 target, ref Vector3 currentVelocity, float smoothTime)
  54. {
  55. float deltaTime = Time.deltaTime;
  56. float maxSpeed = Mathf.Infinity;
  57. return SmoothDamp(current, target, ref currentVelocity, smoothTime, maxSpeed, deltaTime);
  58. }
  59. // Gradually changes a vector towards a desired goal over time.
  60. public static Vector3 SmoothDamp(Vector3 current, Vector3 target, ref Vector3 currentVelocity, float smoothTime, [uei.DefaultValue("Mathf.Infinity")] float maxSpeed, [uei.DefaultValue("Time.deltaTime")] float deltaTime)
  61. {
  62. smoothTime = Mathf.Max(0.0001F, smoothTime);
  63. float omega = 2F / smoothTime;
  64. float x = omega * deltaTime;
  65. float exp = 1F / (1F + x + 0.48F * x * x + 0.235F * x * x * x);
  66. Vector3 change = current - target;
  67. Vector3 originalTo = target;
  68. float maxChange = maxSpeed * smoothTime;
  69. change = Vector3.ClampMagnitude(change, maxChange);
  70. target = current - change;
  71. Vector3 temp = (currentVelocity + omega * change) * deltaTime;
  72. currentVelocity = (currentVelocity - omega * temp) * exp;
  73. Vector3 output = target + (change + temp) * exp;
  74. if (Vector3.Dot(originalTo - current, output - originalTo) > 0)
  75. {
  76. output = originalTo;
  77. currentVelocity = (output - originalTo) / deltaTime;
  78. }
  79. return output;
  80. }
  81. // Access the x, y, z components using [0], [1], [2] respectively.
  82. public float this[int index]
  83. {
  84. get
  85. {
  86. switch (index)
  87. {
  88. case 0: return x;
  89. case 1: return y;
  90. case 2: return z;
  91. default:
  92. throw new IndexOutOfRangeException("Invalid Vector3 index!");
  93. }
  94. }
  95. set
  96. {
  97. switch (index)
  98. {
  99. case 0: x = value; break;
  100. case 1: y = value; break;
  101. case 2: z = value; break;
  102. default:
  103. throw new IndexOutOfRangeException("Invalid Vector3 index!");
  104. }
  105. }
  106. }
  107. // Creates a new vector with given x, y, z components.
  108. public Vector3(float x, float y, float z) { this.x = x; this.y = y; this.z = z; }
  109. // Creates a new vector with given x, y components and sets /z/ to zero.
  110. public Vector3(float x, float y) { this.x = x; this.y = y; z = 0F; }
  111. // Set x, y and z components of an existing Vector3.
  112. public void Set(float newX, float newY, float newZ) { x = newX; y = newY; z = newZ; }
  113. // Multiplies two vectors component-wise.
  114. public static Vector3 Scale(Vector3 a, Vector3 b) { return new Vector3(a.x * b.x, a.y * b.y, a.z * b.z); }
  115. // Multiplies every component of this vector by the same component of /scale/.
  116. public void Scale(Vector3 scale) { x *= scale.x; y *= scale.y; z *= scale.z; }
  117. // Cross Product of two vectors.
  118. public static Vector3 Cross(Vector3 lhs, Vector3 rhs)
  119. {
  120. return new Vector3(
  121. lhs.y * rhs.z - lhs.z * rhs.y,
  122. lhs.z * rhs.x - lhs.x * rhs.z,
  123. lhs.x * rhs.y - lhs.y * rhs.x);
  124. }
  125. // used to allow Vector3s to be used as keys in hash tables
  126. public override int GetHashCode()
  127. {
  128. return x.GetHashCode() ^ (y.GetHashCode() << 2) ^ (z.GetHashCode() >> 2);
  129. }
  130. // also required for being able to use Vector3s as keys in hash tables
  131. public override bool Equals(object other)
  132. {
  133. if (!(other is Vector3)) return false;
  134. Vector3 rhs = (Vector3)other;
  135. return x.Equals(rhs.x) && y.Equals(rhs.y) && z.Equals(rhs.z);
  136. }
  137. // Reflects a vector off the plane defined by a normal.
  138. public static Vector3 Reflect(Vector3 inDirection, Vector3 inNormal)
  139. {
  140. return -2F * Dot(inNormal, inDirection) * inNormal + inDirection;
  141. }
  142. // *undoc* --- we have normalized property now
  143. public static Vector3 Normalize(Vector3 value)
  144. {
  145. float mag = Magnitude(value);
  146. if (mag > kEpsilon)
  147. return value / mag;
  148. else
  149. return zero;
  150. }
  151. // Makes this vector have a ::ref::magnitude of 1.
  152. public void Normalize()
  153. {
  154. float mag = Magnitude(this);
  155. if (mag > kEpsilon)
  156. this = this / mag;
  157. else
  158. this = zero;
  159. }
  160. // Returns this vector with a ::ref::magnitude of 1 (RO).
  161. public Vector3 normalized { get { return Vector3.Normalize(this); } }
  162. // Dot Product of two vectors.
  163. public static float Dot(Vector3 lhs, Vector3 rhs) { return lhs.x * rhs.x + lhs.y * rhs.y + lhs.z * rhs.z; }
  164. // Projects a vector onto another vector.
  165. public static Vector3 Project(Vector3 vector, Vector3 onNormal)
  166. {
  167. float sqrMag = Dot(onNormal, onNormal);
  168. if (sqrMag < Mathf.Epsilon)
  169. return zero;
  170. else
  171. return onNormal * Dot(vector, onNormal) / sqrMag;
  172. }
  173. // Projects a vector onto a plane defined by a normal orthogonal to the plane.
  174. public static Vector3 ProjectOnPlane(Vector3 vector, Vector3 planeNormal)
  175. {
  176. return vector - Project(vector, planeNormal);
  177. }
  178. // Returns the angle in degrees between /from/ and /to/. This is always the smallest
  179. public static float Angle(Vector3 from, Vector3 to)
  180. {
  181. return Mathf.Acos(Mathf.Clamp(Vector3.Dot(from.normalized, to.normalized), -1F, 1F)) * Mathf.Rad2Deg;
  182. }
  183. // The smaller of the two possible angles between the two vectors is returned, therefore the result will never be greater than 180 degrees or smaller than -180 degrees.
  184. // If you imagine the from and to vectors as lines on a piece of paper, both originating from the same point, then the /axis/ vector would point up out of the paper.
  185. // The measured angle between the two vectors would be positive in a clockwise direction and negative in an anti-clockwise direction.
  186. public static float SignedAngle(Vector3 from, Vector3 to, Vector3 axis)
  187. {
  188. Vector3 fromNorm = from.normalized, toNorm = to.normalized;
  189. float unsignedAngle = Mathf.Acos(Mathf.Clamp(Vector3.Dot(fromNorm, toNorm), -1F, 1F)) * Mathf.Rad2Deg;
  190. float sign = Mathf.Sign(Vector3.Dot(axis, Vector3.Cross(fromNorm, toNorm)));
  191. return unsignedAngle * sign;
  192. }
  193. // Returns the distance between /a/ and /b/.
  194. public static float Distance(Vector3 a, Vector3 b)
  195. {
  196. Vector3 vec = new Vector3(a.x - b.x, a.y - b.y, a.z - b.z);
  197. return Mathf.Sqrt(vec.x * vec.x + vec.y * vec.y + vec.z * vec.z);
  198. }
  199. // Returns a copy of /vector/ with its magnitude clamped to /maxLength/.
  200. public static Vector3 ClampMagnitude(Vector3 vector, float maxLength)
  201. {
  202. if (vector.sqrMagnitude > maxLength * maxLength)
  203. return vector.normalized * maxLength;
  204. return vector;
  205. }
  206. // *undoc* --- there's a property now
  207. public static float Magnitude(Vector3 vector) { return Mathf.Sqrt(vector.x * vector.x + vector.y * vector.y + vector.z * vector.z); }
  208. // Returns the length of this vector (RO).
  209. public float magnitude { get { return Mathf.Sqrt(x * x + y * y + z * z); } }
  210. // *undoc* --- there's a property now
  211. public static float SqrMagnitude(Vector3 vector) { return vector.x * vector.x + vector.y * vector.y + vector.z * vector.z; }
  212. // Returns the squared length of this vector (RO).
  213. public float sqrMagnitude { get { return x * x + y * y + z * z; } }
  214. // Returns a vector that is made from the smallest components of two vectors.
  215. public static Vector3 Min(Vector3 lhs, Vector3 rhs)
  216. {
  217. return new Vector3(Mathf.Min(lhs.x, rhs.x), Mathf.Min(lhs.y, rhs.y), Mathf.Min(lhs.z, rhs.z));
  218. }
  219. // Returns a vector that is made from the largest components of two vectors.
  220. public static Vector3 Max(Vector3 lhs, Vector3 rhs)
  221. {
  222. return new Vector3(Mathf.Max(lhs.x, rhs.x), Mathf.Max(lhs.y, rhs.y), Mathf.Max(lhs.z, rhs.z));
  223. }
  224. static readonly Vector3 zeroVector = new Vector3(0F, 0F, 0F);
  225. static readonly Vector3 oneVector = new Vector3(1F, 1F, 1F);
  226. static readonly Vector3 upVector = new Vector3(0F, 1F, 0F);
  227. static readonly Vector3 downVector = new Vector3(0F, -1F, 0F);
  228. static readonly Vector3 leftVector = new Vector3(-1F, 0F, 0F);
  229. static readonly Vector3 rightVector = new Vector3(1F, 0F, 0F);
  230. static readonly Vector3 forwardVector = new Vector3(0F, 0F, 1F);
  231. static readonly Vector3 backVector = new Vector3(0F, 0F, -1F);
  232. static readonly Vector3 positiveInfinityVector = new Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity);
  233. static readonly Vector3 negativeInfinityVector = new Vector3(float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity);
  234. // Shorthand for writing @@Vector3(0, 0, 0)@@
  235. public static Vector3 zero { get { return zeroVector; } }
  236. // Shorthand for writing @@Vector3(1, 1, 1)@@
  237. public static Vector3 one { get { return oneVector; } }
  238. // Shorthand for writing @@Vector3(0, 0, 1)@@
  239. public static Vector3 forward { get { return forwardVector; } }
  240. public static Vector3 back { get { return backVector; } }
  241. // Shorthand for writing @@Vector3(0, 1, 0)@@
  242. public static Vector3 up { get { return upVector; } }
  243. public static Vector3 down { get { return downVector; } }
  244. public static Vector3 left { get { return leftVector; } }
  245. // Shorthand for writing @@Vector3(1, 0, 0)@@
  246. public static Vector3 right { get { return rightVector; } }
  247. // Shorthand for writing @@Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity)@@
  248. public static Vector3 positiveInfinity { get { return positiveInfinityVector; } }
  249. // Shorthand for writing @@Vector3(float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity)@@
  250. public static Vector3 negativeInfinity { get { return negativeInfinityVector; } }
  251. // Adds two vectors.
  252. public static Vector3 operator+(Vector3 a, Vector3 b) { return new Vector3(a.x + b.x, a.y + b.y, a.z + b.z); }
  253. // Subtracts one vector from another.
  254. public static Vector3 operator-(Vector3 a, Vector3 b) { return new Vector3(a.x - b.x, a.y - b.y, a.z - b.z); }
  255. // Negates a vector.
  256. public static Vector3 operator-(Vector3 a) { return new Vector3(-a.x, -a.y, -a.z); }
  257. // Multiplies a vector by a number.
  258. public static Vector3 operator*(Vector3 a, float d) { return new Vector3(a.x * d, a.y * d, a.z * d); }
  259. // Multiplies a vector by a number.
  260. public static Vector3 operator*(float d, Vector3 a) { return new Vector3(a.x * d, a.y * d, a.z * d); }
  261. // Divides a vector by a number.
  262. public static Vector3 operator/(Vector3 a, float d) { return new Vector3(a.x / d, a.y / d, a.z / d); }
  263. // Returns true if the vectors are equal.
  264. public static bool operator==(Vector3 lhs, Vector3 rhs)
  265. {
  266. // Returns false in the presence of NaN values.
  267. return SqrMagnitude(lhs - rhs) < kEpsilon * kEpsilon;
  268. }
  269. // Returns true if vectors are different.
  270. public static bool operator!=(Vector3 lhs, Vector3 rhs)
  271. {
  272. // Returns true in the presence of NaN values.
  273. return !(lhs == rhs);
  274. }
  275. public override string ToString()
  276. {
  277. return UnityString.Format("({0:F1}, {1:F1}, {2:F1})", x, y, z);
  278. }
  279. public string ToString(string format)
  280. {
  281. return UnityString.Format("({0}, {1}, {2})", x.ToString(format), y.ToString(format), z.ToString(format));
  282. }
  283. [System.Obsolete("Use Vector3.forward instead.")]
  284. public static Vector3 fwd { get { return new Vector3(0F, 0F, 1F); } }
  285. [System.Obsolete("Use Vector3.Angle instead. AngleBetween uses radians instead of degrees and was deprecated for this reason")]
  286. public static float AngleBetween(Vector3 from, Vector3 to) { return Mathf.Acos(Mathf.Clamp(Vector3.Dot(from.normalized, to.normalized), -1F, 1F)); }
  287. [System.Obsolete("Use Vector3.ProjectOnPlane instead.")]
  288. public static Vector3 Exclude(Vector3 excludeThis, Vector3 fromThat) { return ProjectOnPlane(fromThat, excludeThis); }
  289. }
  290. }

?