- Home /
Setting the velocity of a projectile based on the angle of the cannon
Hello, I am trying to make a top-down 2d game, and it involves a cannon that shoots food particles, which are then supposed to bounce around the arena. I made the cannon instantiate the food particle, and I made a food object which will collide with my boundaries. However, I am stuck on setting the particle's velocity so that it continues in the direction the cannon is pointing. (The cannon rotates back and forth, so it is not the same vector all the time.) If I set the velocity to a constant vector and change the rotation, will it go in the direction of the rotation? or are the vectors relative to world space? Do I have to do trig in order to calculate the x and y values for the vector? I thought of doing a raycast, and making the food particle look at the endpoint of the raycast. Would that work? Thanks anybody who answers.
You could do the trig, or you could just AddForce in the direction your cannon is facing.
Well you would simply do something like this.
myBullet.transform.forward = cannon.transform.forward;
Then move it based on its forward position.
myBullet.rb.velocity = myBullet.transform.forward * bulletSpeed * Time.fixedDeltaTime;
So you're saying that as the cannon turns, its vector turns with it? Also, I don't see why I need a deltaTime.
No I mean on instantiation of the bullet, the bullet should be set to inherit the cannons facing direction.
Also, when moving an object with physics, you should always use deltaTime because frames are always inconsistent, deltaTime is the only accurate way to get consistent movement.
So I copied your first piece of code into my cannon script underneath the "instantiate the food particle" line, and I copied the second one into the food script in the update function. However, ins$$anonymous$$d of starting the particle at the cannon and immediately setting its direction to the cannon's current angle, it starts it at the origin and moves it with all the other food particles that get shot, in a clump as the cannon turns. What did I do wrong? Cannon instantiate code:
void Update () {
Rotate();
if ((Random.Range(1, 151) == 1))
{
Instantiate(food, cannon.GetComponent<Transform>());
food.transform.forward = cannon.transform.forward;
}
Food script
void Update ()
{
food.GetComponent<Rigidbody2D>().velocity = food.transform.forward * particleSpeed * Time.fixedDeltaTime;
}
You're childing the food to the cannon, so its forward direction is no longer relative to world space, ins$$anonymous$$d you are setting the local forward direction of the food to the world forward direction of the cannon.
Also, you should never run a GetComponent in an Update. You should create a projectile class for your food and do something like this.
public class Projectile : $$anonymous$$onoBehaviour
{
public Rigidbody2D body;
public float speed;
void Awake()
{
if (body == null)
{
body = GetComponent<Rigidbody2D>();
}
}
void FixedUpdate()
{
body.velocity = transform.forward * speed * Time.fixedDeltaTime;
}
}
Then your cannon can have the food prefab and do this.
public class Cannon : $$anonymous$$onoBehaviour
{
public Projectile food;
public float ForwardOffset;
public void FireCannon()
{
Projectile f = Instantiate(food, transform.position + transform.forward * ForwardOffset, transform.rotation);
f.transform.forward = transform.forward;
}
void Update () {
Rotate();
if ((Random.Range(1, 151) == 1))
{
FireCannon();
}
}
}
Did that, but it says, "The object you want to instantiate is null". I put the projectile script as another component on the cannon object if it makes any difference.
Answer by ifurkend · May 17, 2017 at 07:30 AM
Check if the simulation space of your cannon particle system main module. If it's "local" then it's the cause of your issue and can be fixed by changing to "world".
Answer by Amicus1 · May 19, 2017 at 02:01 PM
First, I probably should clarify that the cannon does not actually create a "particle system", the food particles are each separate gameobjects.
Second: I think I have finally figured it out. I have the cannon instantiate the food particle with the same rotation as the cannon had at the time of firing. Then I have in the Start() in the food script, a trig thing that turns the angle of the food particle into a Vector2, and on each update, do a AddForce() along that vector. Now I just have to stop the force once it collides with the wall, so that it can actually bounce around the arena
Thanks everybody again!