- Home /
Frame Independent Movement with AddRelativeForce
My goal is to create a frame independent vehicle controller script that will turn/rotate and thrust my motor boat forward and backward.
My current code produces movement in rotation super slow and very piddly values (decimals). When the vertical axis is 1 I want the vehicle to increase velocity by 10(acceleration) all the way up to 40(maxVelocity).
Where am I going wrong?
public float maxVelocity = 40f;
public float acceleration = 10f;
public float turnAcceleration = 5f;
// Update is called once per frame
void Update () {
float moveInputAmount = Input.GetAxis ("Vertical");
float turnInputAmount = Input.GetAxis ("Horizontal");
// Rotation/Turning
// Apply turn
Vector3 turnForce = Vector3.up * turnInputAmount * this.turnAcceleration * Time.deltaTime;
rigidbody.AddRelativeTorque(turnForce);
// Moving forward backward
// Throttle the boat to the max velocity in both positive and negative direction
Vector3 thrustForce = Vector3.forward * moveInputAmount * this.acceleration * Time.deltaTime;
if(rigidbody.velocity.z < this.maxVelocity && rigidbody.velocity.z > -this.maxVelocity)
{
rigidbody.AddRelativeForce(thrustForce);
}
Debug.Log (thrustForce + " ~ " + turnForce);
Debug.Log ("Boat Velocity: " + rigidbody.velocity);
Debug.Log ("Boat Rotation: " + rigidbody.rotation);
}
@robertbu I guess what I don't understand is why acceleration has to be larger. Since deltaTime is based in seconds and I multiply it by '10' then it should speed up 10 per second, no? The function says add force so I assume it adds onto the already present force. I have messed with the Force$$anonymous$$ode Force and Acceleration but since my mass is 1, there is no change...
Answer by hatuf · Jul 23, 2013 at 07:33 AM
The best practice is to use FixedUpdate() instead of Update() when dealing with Rigidbodies or the physics engine. You can also remove the multiplication by deltatime or replace it with Time.fixedDeltaTime.
Is there anything else wrong or just that the movement isn't frame independent?
I have read that and I understand why but why should it matter aside from protecting people/me from writing code that is not frame independent. FixedUpdate() will only try to run at a specified pace but will not if you bog down and lag your computer. The combination of using FixedUpdate and fixedDeltaTime would be fine but the results should be the same and I want to figure out why not.
I deleted my comment, because you are right about how this "should" be behaving. You issue is the use of deltaTime. Lets assume that your game is running at a fixed 50 frames per second, by scaling the force by 50, you actually apply 0.2 newtons of force (or acceleration if you are using acceleration mode) on average over whatever time period you hold the key down. Over one second you should get a speed of around 0.2, which is what you are getting.
As @hatuf suggests, move your code into FixedUpdate() and remove the deltaTime, and you should get the values you expect. The move to FixedUpdate() is not necessary to get the values you expect, but as @hatuf suggests, "best practice."
@robertbu I have moved to FixedUpdate() and fixedTimeDelta but as expected with the same code I still get 0.2. Removing the multiplication of fixedTimeDelta it takes about 4 seconds to get to 9.7 and sticks there (not correct desired behavior). If I leave the fixedDeltaTime and multiply by 50 (timestep = .02) then I get the same 9.7 4 second result again. :'(