Random direction relative to current direction:
Assuming you already have an initial direction
vector prepared, as per DMGregory's comment on the OP:
- Generate a random float that will represent the angle to change the direction by. Since the angle should be constrained to a 90 degree arc "forward" of the initial direction, we restrain the range of the random value to be from
-45
to 45
:
var angle = Random.Range(-45f, 45f);
- Since you're working with 2D rather than 3D, the axis used for the rotation necessary for the new angle is already known: Z. Because of this, a cross-product calculation is unnecessary.
- Unity already implements rotation matrices, in the form of the
Quaternion
class. Since the rotation is done through the Z axis, we can generate the quaternion for the rotation using the Euler()
static method.
var quaternion = Quaternion.Euler(0, 0, angle);
- Finally, we multiply the
quaternion
by the original direction vector, to get a new, rotated vector:
var newDirection = quaternion * direction;
- Important note: To rotate a vector by a quaternion, it's important that the quaternion always comes first in the multiplication.
- Now that each step of the operation is clear, we can simplify it by making it inline:
direction = Quaternion.Euler(0, 0, Random.Range(-45f, 45f)) * direction;
Extra:
If you intend to "stack" these operations on top of each-other, it's important to note that the constraint will be relative to the current direction in the current step, and so, overall, the 90 degree cone might not be respected; in fact it's hypothetically possible to get a 90 degree turn (180 cone) with two operations, a full "U-turn" with 4, and a circle with 8.
To get consecutive operations to always generate new angles within the initial 90 degree cone, you need to make the constraint be determined relative to the current step's angle with respect to an "ideal" direction (the initial direction, in this case):
var point = Vector2.zero;
var idealDirection = Vector2.up;
var direction = idealDirection;
for(var i = 0; i < 10; i++){
var constraint = Vector2.SignedAngle(direction, idealDirection);
direction = Quaternion.Euler(0, 0, Random.Range(-45f + constraint, 45f +
constraint)) * direction;
var newPoint = point + direction;
Debug.DrawLine(point, newPoint, Color.yellow, 1f);
point = newPoint;
}
//Done this in cellphone, from memory, but hopefully creates something resembling a directional "lighting bolt".
//It should work, but if I made any mistakes due to lacking VS's intellisense, do tell!
//And regardless of that, the most important: Have fun!
Random.insideUnitCircle
. Appreciate it! \$\endgroup\$Quaternion
in my answer: Doing the rotation matrices "manually" is probably faster. \$\endgroup\$