When you say offset do you mean like rotate that vector around position
?
If that’s the case in 2D, then you start with a 2D vector, in this case it’s just direction
.
And you rotate it by doing
static public Vector2 rotateVector(Vector2 v, float rad) {
var p = polar(rad);
return new( p.x * v.x - p.y * v.y, p.y * v.x + p.x * v.y );
}
Where polar
function returns new Vector2(MathF.Cos(rad), MathF.Sin(rad))
and the angle is in radians (hence rad
).
If you want degrees, you can easily convert degrees to radians by multiplying with {\pi} and dividing by {180^{\circ}}, which is effectively the same as multiplying with {\pi}/{180^{\circ}} (conveniently at your disposal via Mathf.Deg2Rad
constant), so you can call it like so
var rotated = rotateVector(direction, angleDegrees * Mathf.Deg2Rad);
In 3D, the problem is slightly harder, because rotation doesn’t mean much unless you can specify the axis of rotation. If you just want a rotation around a cardinal axis, you can make it yourself by doing either Quaternion.Euler(x, y, z)
(insert your values) or Quaternion.AngleAxis(angle, axis)
where axis
is simply a direction vector like Vector3.up
(or transform.up
). Unity API assumes angles are in degrees.
Then applying this rotation is as simple as
static public Vector3 rotateVector(Vector3 v, Vector3 axis, float rad)
=> Quaternion.AngleAxis(rad * Mathf.Rad2Deg, axis) * v;
or
static public Vector3 rotateVector(Vector3 v, Vector3 axis, float angleDegrees)
=> Quaternion.AngleAxis(angleDegrees, axis) * v;
This is because multiplying Quaternion with a Vector3 practically rotates that vector around the origin. So you need now to offset (aka translate) this vector by some position
if this was supposed to happen around that position
. Do note that this works only when quaternion is on the left side of the multiplication, as you cannot multiply vector with a quaternion, that has no mathematical meaning (mathematically the operation is non-commutative).
I can also show you how to build this from scratch (i.e. without using AngleAxis and quaternion-vector multiplication), but I will spare you from technicalities in case you wanted something else instead.
Again, always make sure that your directions (that includes normals, axes atc) are of unit length (length of 1; so called normalized) or else you’ll get weird results.
In the end, a more complete rotation extension function might look like this
/// <summary> Rotates a 3D point around an arbitrary axis (going through center). (In radians.) </summary>
static public Vector3 rotate(this Vector3 point, float rad, Vector3 axis, Vector3 center = default)
=> mad(angleAxis(rad, axis), point - center, center);
Here mad
stands for a compound multiply-add operation so this can be rewritten as
/// <summary> Rotates a 3D point around an arbitrary axis (going through center). (In degrees.) </summary>
static public Vector3 rotate(this Vector3 point, float degrees, Vector3 axis, Vector3 center = default)
=> ( Quaternion.AngleAxis(degrees, axis) * (point - center) ) + center;
This technically shifts the vector from the world space to a rotation space (centered around 0,0), applies the rotation, then shifts it back.
When rotating, it doesn’t matter how long the vector is (unless it’s beyond the optimal values for computing with 32-bit floating points, but that’s a different concern).