- Home /
Randomly instantiate bullets within a certain angle based on look direction
I'd like to be able to instantiate a number of bullets from a single GameObject (enemy) within a certain angle.
Something like this would normally do the job:
transform.eulerAngles.y = Random.Range(00.0,45.0);
But I want to base the angles on the looking angle of the enemy from which the bullets instantiate from. I don't really know how to tackle this.
The scenario is that the enemy follows the player around and just before it dies it fires of a couple of bullets in the player's direction (not homing bullets) and, like described above, it'd be great if the angle of instantiation can be randomized while still firing in the general direction of the player. It's a 2D shooter, looking down from the y axis onto the x and z axis.
Here are the relevant bits of the current script for the bullet:
var speed : int = 5;
function Update () {
transform.Translate(Vector3(0,0,1 * speed * Time.deltaTime));
}
And for the enemy:
var fireRate : float = .5;
private var nextShot : float = 0.0;
function Shoot(){
if(Time.time >= nextShot){
for (var i=0;i<3;i++){
var newBullet : GameObject = Instantiate(enemyBullet, transform.position + transform.forward * 1, transform.rotation);
nextShot = Time.time + fireRate;
Physics.IgnoreCollision(newBullet.collider, collider);
}
}
}
It'd probably be easiest to implement this in the enemy script, right? How could I tackle this?
Thank you for your time!
Ps. Note that I'm not that experienced with Unity and JavaScript (as you probably already figured out, I'm just a hobbyist taking some spare time to do this). If you could take that into regards when suggesting a solution it´d be much appreciated!
Answer by Loius · Dec 18, 2012 at 05:47 PM
I've cheated my way through this a couple of times. This snippet generates a cone of fire, with more bullets landing nearer the center - players like that little side effect:
var direction : Vector3 = transform.forward + Random.insideUnitSphere * inaccuracy;
With inaccuracy being a float less than 1.0; zero inaccuracy means zero spread.
You can then say 'transform.rotation = Quaternion.LookRotation(direction)' to get your Z axis facing along that direction.
Thanks! Adding those lines to the shoot function did the job. A value of .4 worked for me on accuracy, if I would go any higher the bullets would vary on the y axis too much. With it being a 2D game this means that bullets would randomly dissapear, which actually might be useful as a feature later on :)
But, for the sake of knowing and making it work always, would you know a way to limit the returned random values from inside the UnitSphere to the z axis? Or exclude the y axis? Or perhaps another way to make it so that the bullets only move on the x and z axis? (the rigidbody position and rotation constraints don't affect this)
Ah, didn't realize it was 2D. After you calculate direction, just set its .y value to zero (or .x or .z, whichever is your depth axis). (Essentially that's saying "choose a random direction, but make sure that the direction has no change in {whichever axis}")
Your snippet doesn't handle high spread, has a very weird repartition of bullets, is overall bad practice. People might use a inaccuracy above or equal to 1f, which will rarely create an error.
Just use this solution: http://math.stackexchange.com/questions/56784/generate-a-random-direction-within-a-cone
public static Vector3 RandomInCone(float radius)
{
//(sqrt(1 - z^2) * cosϕ, sqrt(1 - z^2) * sinϕ, z)
float radradius = radius * $$anonymous$$athf.PI / 360;
float z = Random.Range($$anonymous$$athf.Cos(radradius), 1);
float t = Random.Range(0, $$anonymous$$athf.PI * 2);
return new Vector3($$anonymous$$athf.Sqrt(1 - z * z) * $$anonymous$$athf.Cos(t), $$anonymous$$athf.Sqrt(1 - z * z) * $$anonymous$$athf.Sin(t), z);
}
It is uniform, the radius can go up to 360 degrees of inaccuracy (behind your head), and it will never explode. You can control exactly the accuracy of the gun, and you won't have any problem ever.
Hi. I have a 2D game with this shoot method void Shoot() { Instantiate(bullet, firePoint.position, firePoint.rotation); return; } How do I implement your RandomInCone method to into my code ? Thanks.
This is for 3d rotation, it would be severely overkill to use this for a 2d game, where rotation can be stored as a single float.
Simply change your shoot function to take the rotation using the depth axis only, as a float, then add a random value between X and -X.
Your answer
Follow this Question
Related Questions
Shoot at an angle 2D 2 Answers
Ecosystem generator script generating everything in the same place 0 Answers
Shooting Script Instantiate Problems. Help? 0 Answers
Calling 2 specific random float numbers in random.range using array not working! 2 Answers
How Instantiate Object Inside of Object and Instantiate Parent Object On Looping. 0 Answers