简体   繁体   中英

Unity C# Time.deltaTime bug

I have a very simple move script attached to an object that allows me to move the object up, down, left or right with momentum. Last night I thought the script was working fine, no issues. I noticed some infinitely small movement of the object, but discarded it as the object simply being drawn each frame, or it "wobbling" due to the code.

However, today I got home, fired it up and the object immediately jumped up and to the right and moved very quickly. After some debugging and feeling like I was going crazy, as I hadn't changed anything, I noticed my laptop wasn't plugged in, thus reducing the power of the machine and cluing me in to what might be causing the bug.

I have tried playing with the code, adding and removing Time.Delta times to improve it, but can't seem to get the issue to go away. Removing all of the Time.deltaTimes make it far, far worse, while putting them everywhere fails to fix the problem.

While the time issue is what caused me to notice the problem, I suspect my real problem might be somewhere in my movement code, as even when I am not pressing a button the game still registers some speed on both the X and Y axis lending me to think it is possibly a problem with the if, else, else if statements.

Any help would be appreciated.

My code is below:

float speedHorz = 0;        //Horizontal starting speed.
float maxspHorz = 5;       //Horizontal Max speed.
float speedVert = 0;
float maxspVert = 5;

float acceleration = 8;    //How fast the object will reach maximum speed.
float deceleration = 12;    //How fast the object will return to 0.

void Update ()
{
    playerMove();
}

public void playerMove()
{
    //Up and Down, Acceleration
    if ((Input.GetKey("s")) && (speedVert < maxspVert))                       //If you press S and Verticl Speed is less than the max...
    {
        speedVert = speedVert - acceleration * Time.deltaTime;              //Lower speed by acceleration, move down...
    }

    else if ((Input.GetKey("w")) && (speedVert > -maxspVert))
    {
        speedVert = speedVert + acceleration * Time.deltaTime;
    }

    //Up and Down, Deceleration
    else
    {
        if (speedVert > deceleration * Time.deltaTime)
        {
            speedVert = speedVert - deceleration * Time.deltaTime;
        }

        else if (speedVert < deceleration * Time.deltaTime)
        {
            speedVert = speedVert + deceleration * Time.deltaTime;
        }

        else speedVert = 0 * Time.deltaTime;
    }

    //Left and Right, Acceleration
    if ((Input.GetKey("a")) && (speedHorz < maxspHorz))                   //If you are pressing the "a" key and speed is less than max speed...
    {
        //Move Left
        speedHorz = speedHorz - acceleration * Time.deltaTime;         //Accelerate negatively on the X axis, ie Move Left.

    }

    else if ((Input.GetKey("d")) && (speedHorz > -maxspHorz))
    {
        speedHorz = speedHorz + acceleration * Time.deltaTime;
    }

    //Left and Right, Deceleration
    else
    {
        if (speedHorz > deceleration * Time.deltaTime)
        {
            speedHorz = speedHorz - deceleration * Time.deltaTime;
        }

        else if (speedHorz < deceleration * Time.deltaTime)
        {
            speedHorz = speedHorz + deceleration * Time.deltaTime;
        }

        else speedHorz = 0 * Time.deltaTime;
    }

    transform.position = new Vector2(transform.position.x + speedHorz * Time.deltaTime, transform.position.y + speedVert * Time.deltaTime);

}

To me, the salient bit is that your player moves even when you haven't supplied input. Unless I have missed something, acceleration and deceleration never change in your supplied code snippet. Given that deceleration is constant and that you've not supplied input since starting the game, consider this part of your the snippet:

else if (speedHorz < deceleration * Time.deltaTime)
{
     speedHorz = speedHorz + deceleration * Time.deltaTime;
}

The first time you evaluate this condition speedHoriz is zero (your player begins at rest, yes?), deceleration is 12, and time.DeltaTime is probably not zero. That means your if condition evaluates to 0 < 12 * [positive number], which is true. speedHorz will then go from zero to something greater than zero, and your player will have a bit of speed even though you've not pushed any buttons.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM