[Ask] [SOLVED] Object moving too fast in game view editor. Looks normal after build

So I have this problem where my player movement is too fast in the game view inside the editor.

So to start, at first I try to make my game in windows, tiny10 version. Works fine, even able to build the prototype. The weird part is, if the vsync doesn’t turned on (1000ish fps), the player move is too fast. If the vsync is on (100 fps), the player movement is normal. But that only appear in the editor, the build still works as I intended.

The movement already use the Time.deltaTime

Then, I want to make some sort of backend to store scores online. Going to use ElysiaJS, and will build that inside a docker. Surprise, docker desktop cannot get installed in this tiny10. So I move to my Kubuntu (dual booted).

Able to install Unity in my Kubuntu. Able to install other plugins. And able to open the editor. Now the problem appear again. The player movement is too fast again inside the game view editor. Even when the vsync turned on or off, the player movement is still too fast.

I try to build the game inside Kubuntu, tried to run the game, and the player movement works as I intended. Not too fast like in the editor.

Player movement inside the editor

Player movement inside the build

You’re not using Time.deltaTime when moving the object. It should be:

transform.position += new Vector3(current_speed,0 ,0) * Time.deltaTime;

Also, make sure VSync is enabled in the Game view.

Is there a difference between doing it

current_speed += accel;
transform.position += new Vector3(current_speed, 0, 0) * Time.deltaTime;

or

current_speed += accel * Time.deltaTime;
transform.position += new Vector3(current_speed, 0, 0);

Because I think, mathematically, it would do the same.

Or are you suggesting I do the Time.deltaTime twice like this?

current_speed += accel * Time.deltaTime;
transform.position += new Vector3(current_speed, 0, 0) * Time.deltaTime;

I would try the first code here, just to see if it any difference for now.

=================================================================
So about the vsync, still doesn’t do anything. Tried your suggestion here, still have the movement going too fast.

Yes, like that…

You can also replace your input handling with a single:

accel += force * Input.GetAxisRaw("Horizontal");

BTW - When posting code to demonstrate an issue you should always copy and paste the actual code text so then we’ll get line numbers which we can then comment on. It also means we can copy your code, edit it and then post it back to you.

Did that, far too slow, almost like not moving at all. Not what I intended.

You’ll need to increase the force value. :slight_smile:

The basic force in editor I use 10,
then I increase to 100, still not moving as I intended
tried increase to 1000, now the supposed “side gravity” of my mechanic doesn’t work properly.

I think it really some bug in the editor. The view game should reflect how fast the object move in the build, so that I can view the game without have to build the game each time there some slight change I did.

Oh yeah, I have the original prototype build you might want to try so you could understand better what proper speed I intend in my game. [Prototype of my game] (Release v0.1.0_alpha · azern32/takododge · GitHub), its for Windows.

You’re running into a bit of an issue here - all of these suggestions are wrong! The one where you multiply acceleration and translation with Time.deltaTime is less wrong than the other two, but it’s still not framerate independent.

When you have this code:

velocity += acceleration * deltaTime;
position += velocity * deltaTime

Think about what happens at different framerates. Say you have an acceleration of 30. This means that at 30 fps, your velocity changes by 1 each frame, and at 60 fps, your velocity changes by 0.5 each frame. Let’s see what happens with the position

// 30 fps: 
frame 0: time: 0,    speed 0, position 0
frame 1: time: 1/30, speed 1, position 1/30

// 60 fps:
frame 0: time: 0,    speed 0, position 0
frame 1: time: 1/60, speed 0.5, position 1/120
frame 2: time: 1/30, speed 1, position 1/40

So that’s actually very wrong! The speed is the same, but the position is very different.

There’s three approaches here to get a better result:
1: Use this formula:

position += velocity * timeStep + 0.5 * acceleration * timeStep * timeStep;
velocity += acceleration * timeStep;

It’s from Stack Overflow, and while I don’t quite know why it’s correct, I checked that the results seem solid:

using UnityEngine;

public class TestScript : MonoBehaviour {
    private void Start() {
        CalculateAtDeltaTime(1f / 60f);  // prints deltaTime 0.01666667 gives 5.168055 @ 1.016666
        CalculateAtDeltaTime(1f / 30f);  // prints deltaTime 0.03333334 gives 5 @ 1
        CalculateAtDeltaTime(1f / 15f);  // prints deltaTime 0.06666667 gives 5 @ 1
        CalculateAtDeltaTime(1f / 120f); // prints deltaTime 0.008333334 gives 5.083682 @ 1.008333
        CalculateAtDeltaTime(1f / 90f);  // prints deltaTime 0.01111111 gives 5.000001 @ 1.000001
    }

    private void CalculateAtDeltaTime(float deltaTime) {
        const float acceleration = 10f;
        var time = 0f;

        var position = 0f;
        var velocity = 0f;

        while (time < 1f) {
            position += (velocity * deltaTime) + (0.5f * acceleration * deltaTime * deltaTime);
            velocity += acceleration * deltaTime;

            time += deltaTime;
        }
        Debug.Log($"deltaTime {deltaTime} gives {position} @ {time}");
    }
}

2: use the approach Unity uses with a fixed deltatime. If you stick the “wrong” version in FixedUpdate:

velocity += acceleration * deltaTime;
position += velocity * deltaTime

It’ll work, because the function will be called at the same fixed virtual framerate, meaning that the lower the framerate, the more often the code runs. The problem with this is that if the framerate is much higher than the fixed timestep, you’ll see the stutter, so you’ll have to implement interpolation, and at that point you should really just go for:

3: Use a rigidbody and just do this in FixedUpdate:

rigidbody.AddForce(acceleration);

That really just solves everything for you. You’ll get the same result no matter the framerate, and if you turn on interpolation on the rigidbody it will look good at all framerates.

Quick question, is rigidbody.AddForce(acceleration) will just move the the object the same number of unit each frame?

Because if so, then I need to do accel += accel each frame. so each frame the accel increases.

Rigidbodies have an internal velocity - they’re a simulated physics object. AddForce just pushes them, so AddForce(acceleration) will give a constant acceleration without having to do anyhting extra. They also have options for drag if you want them to not accelerate forever.

So, the rigidbody way, I can’t really wrap my head around it and… it introduce more problem for me.

Because of that, I tried the second approach, if I’m not mistaken, I should move the transform into FixedUpdate() like this… perhaps(?)

void Update()
    {
        gravitySourcePos = gravitySource.transform.position;
        direction = transform.position.x >= gravitySourcePos.x ? 1 : -1;
        accel = 2 * direction;
        // direction *= 2;

        if (Input.GetKey(KeyCode.LeftArrow) || Input.GetKey(KeyCode.A))
        {
            accel -= force;
        }

        if (Input.GetKey(KeyCode.RightArrow) || Input.GetKey(KeyCode.D))
        {
            accel += force;
        }

        // current_speed += accel * Time.deltaTime / 2;
        // transform.position += new Vector3(current_speed, 0, 0);

        initscore += Time.deltaTime;
        if ((int)initscore == 1)
        {
            initscore = 0;
            logic.Add1Score();
        }
    }

    void FixedUpdate()
    {
        current_speed += accel * Time.deltaTime;
        transform.position += new Vector3(current_speed, 0, 0);
    }

It actually make the view in the editor move as I’d like to. But, as you said, the stutters. The stutters doesn’t shows in the editor but shows in the builds (or maybe just some placebo effect).

Will try to make a build with an fps counter just to make sure.