How would I apply force to a bullet in 2D?

I wrote the code below in order to try to get a bullet to fire at a specific angle for my top-down shooter. However when I press space the bullet just spawns in front of the game object despite it having a bullet speed. I made sure that my bullet prefab has a rigidbody and I am calling to it in my script.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class FireAway : MonoBehaviour
{
private Vector3 mouse_pos;
private Vector3 object_pos;
private float angle;
private float bulletSpeed = 1;
public GameObject ammo;
private Rigidbody2D rb2D;

void Start()
{
rb2D = ammo.GetComponent<Rigidbody2D>();
}

// Update is called once per frame
void FixedUpdate()
{
// Point the cannon at the mouse.
mouse_pos = Input.mousePosition;
mouse_pos.z = 0.0f;
object_pos = Camera.main.WorldToScreenPoint(transform.position);
mouse_pos.x = mouse_pos.x - object_pos.x;
mouse_pos.y = mouse_pos.y - object_pos.y;
angle = Mathf.Atan2(mouse_pos.y, mouse_pos.x) * Mathf.Rad2Deg - 90;
Vector3 rotationVector = new Vector3(0, 0, angle);
transform.rotation = Quaternion.Euler(rotationVector);

if (Input.GetKeyDown("space"))
{

GameObject BulletPlayer = (GameObject)Instantiate(ammo,
transform.position, transform.rotation);
//bullet.transform.LookAt(mouse_pos);
}
}
}


Your problem is that you're spawning an instance of the ammo prefab, and then applying force to the prefab instead of to the instance you just spawned.

To avoid this, just have one variable for the prefab instead of two:

 public Rigidbody2D bulletPrefab;


Then instantiate it, and capture a reference to the instance's rigidbody:

 Rigidbody2D bulletInstance = Instantiate(bulletPrefab, position, orientation);

bulletInstance.velocity = bulletInstance.transform.forward * bulletSpeed;


I don't recommend using force for this if you just want to set a specific launch velocity. Force can be affected by mass and timestep, so it's simpler for a case like this to just set the velocity directly.

• I tried it and I got an error that says "The variable bulletPrefab of FireAway has not been assigned. And it says I probably need to assign it in the editor but I did assign it before playing the scene. – Mark Gregg Dec 3 '18 at 14:17
• – DMGregory Dec 3 '18 at 14:22

I don't use unity myself, so I can only give you general information here:

rb2D.AddForce(BulletPlayer.transform.forward * bulletSpeed);


In order to accelerate any object to from velocity (v0), to velocity (v1), you must apply a force of newtons(N), in a direction , over a time interval (t).

At the moment, all you are doing is applying a direction (unit vector, has length of 1), then multiplying by 1, which has no effect on the vector.

The magnitude of that impulse will then be reduced by the bullet's mass, further reducing the visible effect of the impulse.

In short, the bullet has velocity, but it's so slow you can't see it move.

a = (F * t)/M where M is mass of the bullet, a is the change in velocity (v1-v0)


Basically, F must increase for your bullet to fly.

• This answer would be correct if rb2D referred to the instance of the bullet we just spawned, but it doesn't — it's still pointing at the prefab, and we never apply a force to the newly-spawned instance at all. – DMGregory Dec 3 '18 at 13:45
• @DMGregory Fair enough. I'll leave the answer up as it's informative in it's own way. – Ian Young Dec 3 '18 at 16:07