Speed inconsistent even when using time.dT + Fixed Update
Hello!
I'm making a 2D score based game and I find that sometimes the speed at which blocks move is inconsistent.
Example1 (correct speed): https://media.giphy.com/media/iF1wLlL8BhbClztoMj/giphy.gif Example2 (incorrect speed): https://media.giphy.com/media/LO2s3YRIglN9H2NeXY/giphy.gif
I find that using more memory elsewhere on my pc correlates to the faster speed but I'm using Time.deltaTime and FixedUpdate to call it.
At this point I'm thinking it must be just some stupid mistake I made somewhere along the line, but can't spot.
(I've cut out unrelated code - the following contains everything on physics)
Thanks for your help!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Block : MonoBehaviour
{
void Start()
{
gameManager.direction = gameManager.eastDir;
MoveBlock();
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Mouse0) && !instantiated && !gameManager.changeDir)
{
NextBlockSequence();
}
else if (Input.GetKeyDown(KeyCode.Mouse0) && !instantiated && gameManager.changeDir)
{
gameManager.direction = gameManager.southDir;
gameManager.changeDir = false;
}
if (extraHeight == 0)
{
gameManager.changeDir = false;
}
else if(extraHeight > 0)
{
gameManager.changeDir = true;
}
}
private void FixedUpdate()
{
if (rb.bodyType == RigidbodyType2D.Dynamic) //unmoving objects velocities are set to 0 and static body types
{
rb.velocity = gameManager.direction;
}
}
void MoveBlock()
{
gameManager.direction = gameManager.eastDir;
}
void StopBlock()
{
gameManager.direction = gameManager.stopDir;
gameObject.GetComponent<Rigidbody2D>().bodyType = RigidbodyType2D.Static;
}
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.collider.tag == "Block")
{
if (gameManager.currentBlock == gameObject)
{
NextBlockSequence();
transform.position = new Vector2(transform.position.x, transform.position.y + 0.035f);
}
extraHeight = 0;
}
else
{
gameManager.Lose();
}
}
public class GameManager : MonoBehaviour
{
public Vector2 direction;
public Vector2 eastDir;
public Vector2 southDir;
public Vector2 stopDir;
public bool changeDir = false;
//data
public int score;
public float speed = 100;
private void Start()
{
eastDir = new Vector2(speed * Time.deltaTime, 0);
southDir = Vector2.down * speed * Time.deltaTime;
stopDir = Vector2.zero;
}
Answer by Kennai · Jul 25, 2019 at 02:37 PM
Hi @LoadingDegree0!
First, do not use deltaTime with rigidbody. Because deltaTime depends on frame rate, and rigidbody uses fixedDeltaTime.
Second, do not use any delta stuff when you set rigidbody velocity.
If your object has speed 10 - set rigidbody velocity to 10 too (ofc I mean a vector with magnitude 10).
Third, your deltaTime depends on frame rate, so on fast machines it is small, on slow machines it is high - that's why your blocks has different speed.
Haha, okay, I rewarded you 10 points :D enjoy
Wow thanks! Your explanation was better than $$anonymous$$e, but thanks!
Answer by blinkafrootable · Jul 25, 2019 at 02:37 PM
I did read the comments but know that if you want to stick to using FixedUpdate for physics changes, use Time.fixedDeltaTIme instead of Time.deltaTime.
Time.deltaTime
is evaluated as Time.fixedDeltaTime
when called from FixedUpdate
, btw.
Answer by Bunny83 · Jul 25, 2019 at 05:49 PM
I just want to clear up some things here:
It's perfectly fine to use Time.detaTime inside FixedUpdate as it returns fixedDeltaTime when used from inside FixedUpdate.
Using deltaTime in Start makes absolutely no sense whatsoever as outside of FixedUpdate deltaTime will represent the actual delta time between the last and the current frame. This time can change depending on the current framerate. So storing deltaTime (or a value multiplied by deltaTime) in a variable just makes no sense.
You could have used fixedDeltaTime inside Start but I would strongly oppose such a usage. fixedDeltaTime doesn't change automatically since it actually dictates the speed at which FixedUpdate is called. However since it can be changed it just makes no sense to premultiply any values with it an caching them.
Like Kennai said the velocity of a rigidbody represents the actual velocity. So when setting the velocity using deltaTime makes no sense. The velocity is specified in units per second. The physics system will use the correct deltaTime internally when it applies the velocity to the position each physics frame. So when you assign a velocity of (0,0,5) the object will move 5 units per second unless other forces act on the rigidbody (like drag, gravity, some manual AddForce calls or collisions).
In general deltaTime needs to be used when you want to apply a change each frame. The main point you should remember is that deltaTime is just 1/framerate. That means if you accumulate / add up the value of deltaTime each frame you will end up with a value of 1 after 1 second. So if you want to incease something by "5" every second you can simply add 5 * Time.deltaTime each frame and it will accumulate to 5 after 1 second.
Your answer
Follow this Question
Related Questions
How to handle FixedUpdate() and Input 0 Answers
Fixed Timestep and Solver Iteration Count Relationship 1 Answer
Character suddenly stop moving. 0 Answers
Rigidbody rotate velocity 0 Answers
Best solution for 100% accurate jumps. 0 Answers