- Home /
Time.deltaTime/Time.fixedDeltaTime are messing with gravity
I am moving a cube by changing the velocity of its rigidbody directly in fixed update, but it fell very slowly when in the air. I found out that it was caused by multiplying the intended velocity by Time.deltaTime in fixed update. I googled it, and apparently Time.fixedDeltaTime is supposed to be for fixed update, but when I tried it, that same problem occurred. When I don't use either, there are no problems. While not using Time.deltaTime or Time.fixedDeltaTime cause problems with different frame rates, and if so, how do I use them without affecting the speed of falling? Edit: Solved. I realize that I don't need to use Time.deltaTime or Time.fixedDeltaTime when changing the velocity directly.
public class PlayerCamManager : MonoBehaviour
{
public Camera playerCamera;
public GameObject playerCharacter;
public Transform camContainer;
public Transform camContainerTwo;
public Vector3 camStartingPos;
Rigidbody rb;
Vector3 camContainerTwoRotation;
Vector3 camContainerRotation;
Vector3 finalMovement;
public float moveSpeed;
public float lerpSpeed;
float xInput;
float zInput;
void Awake()
{
camContainer.SetParent(camContainerTwo);
camContainer.localPosition = new Vector3(0, 0, 0);
playerCamera.transform.SetParent(camContainer);
playerCamera.transform.localPosition = camStartingPos;
rb = playerCharacter.GetComponent<Rigidbody>();
}
void Update()
{
Vector3 input = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
float h = moveSpeed;
float a = playerCharacter.transform.rotation.eulerAngles.y;
a = a * Mathf.Deg2Rad;
if (input.x != 0)
{
if (input.x > 0)
{
float i = Mathf.LerpAngle(playerCharacter.transform.rotation.eulerAngles.y, camContainerTwo.rotation.eulerAngles.y + 90, lerpSpeed * Time.deltaTime);
playerCharacter.transform.eulerAngles = new Vector3(0, i, 0);
}
else
{
float i = Mathf.LerpAngle(playerCharacter.transform.rotation.eulerAngles.y, camContainerTwo.rotation.eulerAngles.y - 90, lerpSpeed * Time.deltaTime);
playerCharacter.transform.eulerAngles = new Vector3(0, i, 0);
}
float xInput = (h * Mathf.Sin(a));
float zInput = (h * Mathf.Cos(a));
Vector3 moveDirection = new Vector3(xInput, 0, zInput);
finalMovement = moveDirection;
return;
}
else if (input.z != 0)
{
float i = Mathf.LerpAngle(playerCharacter.transform.rotation.eulerAngles.y, camContainerTwo.rotation.eulerAngles.y, lerpSpeed * Time.deltaTime);
playerCharacter.transform.eulerAngles = new Vector3(0, i, 0);
float xInput = (h * Mathf.Sin(a));
float zInput = (h * Mathf.Cos(a));
Vector3 moveDirection = new Vector3(xInput, 0, zInput);
finalMovement = moveDirection * input.z;
return;
}
else
{
finalMovement = new Vector3(0, 0, 0);
}
}
void FixedUpdate()
{
finalMovement.y = rb.velocity.y;
rb.velocity = finalMovement * Time.fixedDeltaTime;
}
void LateUpdate()
{
camContainerTwo.position = playerCharacter.transform.position;
camContainerTwoRotation.y = camContainerTwoRotation.y + (Input.GetAxis("Mouse X") * Time.deltaTime * 180);
camContainerRotation.x = camContainerRotation.x - (Input.GetAxis("Mouse Y") * Time.deltaTime * 180);
if (camContainerRotation.x < -25)
{
camContainerRotation.x = -25;
}
else if (camContainerRotation.x > 55)
{
camContainerRotation.x = 55;
}
camContainerTwo.eulerAngles = camContainerTwoRotation;
camContainer.localEulerAngles = camContainerRotation;
playerCamera.transform.LookAt(camContainer.transform.position);
}
}
This is a unit problem. You're multiplying a velocity by time, which will give you a distance. You're then setting that distance again as a speed and repeating the process each frame.
What are you trying to accomplish btw? Reducing / Increasing fall speed?
I am simply trying to move the cube by altering its velocity directly. Based on what you said, I get the idea that I don't need to use Time.deltaTime or Time.fixedDeltaTime, because velocity is already calculated per time. This makes so much more sense. I am used to using either add force or transform.translate, which both need Time.deltaTime in order to keep a constant speed across different frame rates, which is why I thought the same here, but now I understand why changing the velocity is different. Whether you were trying to or not, you answered my question. Thanks.
Oh good to hear, noticing my tone was a little stiff so sorry about that. Gl with future efforts. :-D
You can also set the gravity in the project settings and you can also set gravity scale for each object on the rigidbody.
Answer by ColtPtrHun · Mar 26, 2020 at 03:07 PM
@Phoenix2233 I had the same problem, and just found a solution for that finally.. I use FixedUpdate() and Time.fixedDeltaTime as the multiplier.
The problem seems to be the rectangular integrator: vel += acc Time.fixedDeltaTime; pos += vel Time.fixedDeltaTime;
Instead, use trapezoidal integrator, which is more precise. You will need the previous values for this:
vel+= 0.5f accOld dT + 0.5f acc dT; pos += 0.5f velOld dT + 0.5f vel dT; accOld = acc; velOld = vel;
Using this, you should be able to change the FPS and the Fixed TimeStep to whatever you want.