Hi guys, this should be a simple one:
I have defined this direction vector:
(vector3) direction = targetVector - transform.position;
direction.Normalize();
Now, how would one add a random noise to this direction, expressed as min and max ANGLES?
Should I convert this vector to an angle in degrees, add the noise and then back to normalized vector?
Thank you for the assist!
8 Answers
8
To further illustrate what is meant to be done here, here is an example.
A bullet from a high speed, low accuracy machine gun is being fired. The base direction is 100% accurate, but in order to reflect the low accuracy of each projectile a randomization of their direction is needed.
Currently, the projectiles are moving using:
transform.position += direction * projetileSpeed;
What is needed in this case is a way to add a specific angular modifier to the direction vector.
Maybe to that targetVector, you could add in a small amount of X and Y, in order to make it slightly deviate?
For instance:
targetVector += transform.up * Random.Range(-randAmt, randAmt) + transform.right * Random.Range(-randAmt, randAmt);
With randAmt being a float value that you can set.
So i guess you want something like this, right. I just added the C# translation. You can simply do
dir = GetPointOnUnitSphereCap(dir, 10f);
This will add randomly up to 10° variation to the given direction.
Use this function:
direction += AddNoiseOnAngle (0, 30);
[...]
Vector3 AddNoiseOnAngle ( float min, float max) {
// Find random angle between min & max inclusive
float xNoise = Random.Range (min, max);
float yNoise = Random.Range (min, max);
float zNoise = Random.Range (min, max);
// Convert Angle to Vector3
Vector3 noise = new Vector3 (
Mathf.Sin (2 * Mathf.Pi * xNoise /360),
Mathf.Sin (2 * Mathf.Pi * yNoise /360),
Mathf.Sin (2 * Mathf.Pi * zNoise /360)
);
return noise;
}
This will return a Vector3 whos values are between -1 and 1 inclusive.
Thank you for the function. I implemented as follows:
(for some reason I could not use Mathf.Pi).
Vector3 AddNoiseOnAngle ( float min, float max) {
float xNoise = Random.Range (min, max);
float yNoise = Random.Range (min, max);
float zNoise = 0;
// Now get the angle between w.r.t. a vector 3 direction
Vector3 noise = new Vector3 (
Mathf.Sin (2f * 3.1415926f * xNoise / 360),
Mathf.Sin (2f * 3.1415926f * yNoise / 360),
0
);
return noise;
}
At a first glance this appears to work, but the output angles do not seem to be proportionally related to the noise factor added - adding 30 or 3000 yields pretty much the same result (and the deviation never appears to be greater than 45 degrees).
Unity contains Mathf.PerlinNoise.
Old thread, but it helped me get myself on the right track. I wanted to add a little random bloom to my aimpoint to simulate bullet spread. Here’s what I ended up with:
public int accuracy = 90;
private const int ACCURACY_FLOOR = 90;
...
// For me this is calculated from a raycast -- but you can use whatever your base aim direction is
Vector3 aimDir = <your true aim direction Vector3>;
// Use ACCURACY_FLOOR to put a lower bounds on accuracy
// 90% real accuracy is horrible so this is so we can use 0-100% accuracy instead of having to use 90-100
float bloom = 180f - (((accuracy / (100f - ACCURACY_FLOOR) + ACCURACY_FLOOR) / 100f) * 180f);
float bloomX = Random.Range(-bloom, bloom) / 180f;
float bloomY = Random.Range(-bloom, bloom) / 180f;
float bloomZ = Random.Range(-bloom, bloom) / 180f;
aimDir = new Vector3 ( Mathf.Clamp(aimDir.x + bloomX, -1, 1), Mathf.Clamp(aimDir.y + bloomY, -1, 1), Mathf.Clamp(aimDir.z + bloomZ, -1, 1));
aimDir = aimDir.normalized;
Now on my prefab I can set accuracy to any number 0-100, where 0 is 90% accurate and 100 is 100% accurate. The spread is also nice and uniformly random, it feels really good.
i'm not sure what you mean by "noise". Do you mean you want a random amount of inaccuracy applied to your direction?
– toddisarockstarTo further illustrate what is meant to be done here, here is an example. A bullet from a high speed, low accuracy machine gun is being fired. The base direction is 100% accurate, but in order to reflect the low accuracy of each projectile a randomization of their direction is needed. Currently, the projectiles are moving using: transform.position += direction * projetileSpeed; What is needed in this case is a way to add a specific angular modifier to the direction vector.
– JulianCallensWhoa, i think you guys are making this tougher that what he needs. if he has allready has his normalized direction why cant he simply do this: Vector3 mydirection = Vector3.right;//<--here is your normalized direction float inacuracy = 0.9f;//<--closer to 1 is more accurate mydirection = new Vector3 ( Random.Range (inacuracy,1f) * mydirection.x, Random.Range (inacuracy,1f) * mydirection.y, Random.Range (inacuracy,1f) * mydirection.z); mydirection=mydirection.normalized;
– toddisarockstar