表示 3D的 向量和点。

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




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

    示例:


    Vector3.Dot 点乘

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

    示例:

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

    Vector3.Cross 叉乘

    示例:

    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. }

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

    示例:


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

    ?