Im trying to make a cannon, im making the cannonball move with Rigidbody.Addforce(Vector3.back * speed). i have been constantly messing with the speed variable and the mass for the cannonball, but i cant seem to find one that will make it fire the way i want to. They either gradually fall to the ground or just drop to the floor and roll away. How can i make it fire in an arch like an actual cannonball would?
I’m not sure what you’re actually doing right now, so to start with I’ll write what I think you might be doing, but definitely shouldn’t be!
First up, if you are calling ‘AddForce’ every frame, you certainly shouldn’t be in this case. A cannon ball is effectively launched with a single big force (when then cannon goes off) and is then allowed to move freely, slowing due to air resistance but accelerating downwards due to gravity.
Also, if you are calling ‘AddForce’ every frame (and if it was the right thing to do) you’d need to make sure it was being called from within a FixedUpdate function, not an Update function. I won’t go into too much detail as to why here, as it’s not relevant, but it’s worth reading up on that stuff!
So what you should be doing is:
- Starting off with a cannon ball that isn’t moving at a fixed position
- Either applying a big force (of force type impulse or acceleration - I’ll get to that) or just directly set its velocity in the direction you want it to go
Have a look at AddForce and you’ll see it takes a 2nd parameter - ForceMode. This can be Force, Impulse or Acceleration. Again, read up on these as they are important. For the sake of this question I’ll just say that ForceMode.Force (the default) is scaled by time step (and mass), and designed for continuous forces every frame (such as thrust). Impulse (scaled only by mass) and Acceleration are designed for ‘1-shot’ forces that shouldn’t be affected by the time step.
Of course, all AddForce does in modify the velocity, and since you’re starting with a stationary cannon ball, and know exactly how fast you want it to go, you could just as easily set its velocity!
//note: I'm assuming you already have a member or local variable called cannonBall, which is the game object representing it
//this should have a rigid body, that is not kinematic so it can move freely through the world
//pick the direction you want the ball to go - here I'm just pointing it up and to the right a bit
//you'll probably want to base it off the forwards vector of your cannon or something?
//I'm also normalizing it, as I want it of unit length for my future calculations
//if it was already normalized you wouldn't need to do this!
Vector3 dir = Vector3.Normalize(new Vector3(0, 1, 1));
//now we could accelerate the cannon ball in my direction in several ways
//option 1: apply an IMPULSE - this will accelerate the ball, but will go more slowly the heavier the ball is
//this assumes you have a variable called 'impulseSize' for how hard to push it
cannonBall.rigidBody.AddForce(dir * impulseSize, ForceMode.IMPULSE);
//option 2: apply an ACCELERATION - this will directly accelerate the ball by a fixed amount regardless of mass
//this assumes you have a variable called 'desiredSpeed' for how fast it should go
cannonBall.rigidBody.AddForce(dir * desiredSpeed, ForceMode.ACCELERATION);
//option3: directly set the velocity of the cannon ball. because it starts stationary, this is exactly
//the same as using the acceleration force mode
cannonBall.rigidBody.velocity = dir * desiredSpeed;
Once the cannon ball is moving, the physics should do the rest. Note that unless you’ve build your world roughly to scale (i.e. 1 would unit corresponds roughly to 1m), the default value for gravity will not seem like earth gravity. i.e. if you’d build your world tiny, earth gravity would seem very high.
Hope that helps