Home > Enterprise >  Slow movement in built game - FixedUpdate vs Update
Slow movement in built game - FixedUpdate vs Update

Time:04-28

I noticed a major slow-down testing a built game, compared to how it works in the editor.

Player Movement:

public class PlayerScript : MonoBehaviour
{
    Vector3 objectSpeed;
    Rigidbody rigidBody;
    [SerializeField] float speed;
    [SerializeField] float maxSpeed;
    // Start is called before the first frame update
    void Start()
    {
        objectSpeed = gameObject.GetComponent<Rigidbody>().velocity;
        rigidBody = gameObject.GetComponent<Rigidbody>();
    }

    // Update is called once per frame
    void Update()
    {
                objectSpeed = rigidBody.velocity;
        if (Input.GetKey("w"))
        {
            objectSpeed.z  = speed;
        }
        if (Input.GetKey("s"))
        {
            objectSpeed.z -= speed;
        }
        if (Input.GetKey("a"))
        {
            objectSpeed.x -= speed;
        }
        if (Input.GetKey("d"))
        {
            objectSpeed.x  = speed;
        }
        objectSpeed.x = Mathf.Clamp(objectSpeed.x, -maxSpeed, maxSpeed);
        objectSpeed.z = Mathf.Clamp(objectSpeed.z, -maxSpeed, maxSpeed);
        rigidBody.velocity = objectSpeed;
    }
}

Player movement is noticeably slower in the build. After some searching, I found out about FixedUpdate() which is supposed to be used for physics. After moving this code there, player movement in build works as intended.

Strangely enough, enemy movement is working just fine from Update()

public class EnemyScript : MonoBehaviour
{
    public GameObject player;
    Rigidbody enemyRigidbody;
    float zombieSpeed;

    // Start is called before the first frame update
    void Start()
    {
        player = GameObject.Find("Player(Clone)");
        enemyRigidbody = gameObject.GetComponent<Rigidbody>();
    }

    // Update is called once per frame
    void Update()
    {
        Vector3 directionToPlayer = player.transform.position - transform.position;
        float distanceToPlayer = Mathf.Sqrt(
            Mathf.Pow(directionToPlayer.x, 2f)  
            Mathf.Pow(directionToPlayer.y, 2f)  
            Mathf.Pow(directionToPlayer.z, 2f));
        Vector3 movementVector = (1f / distanceToPlayer) * directionToPlayer * zombieSpeed;
        enemyRigidbody.velocity = movementVector;
    }
}

So what's the deal here? Is it something to do with having to deal with keyboard input for player's movement?

CodePudding user response:

TLDR;

FixedUpdate() runs based on the current Time.timeScale,
Update() always runs once per Frame.


FixedUpdate() always runs in-sync with the physics-engine, it does not always run once per-frame.
It can run several times per-frame or none at all, depending on the physics engine.

For optimization purposes, the Physics Engine runs in relative to the game's time-scale rather than the frame-rate.

If you need more accurate physics calculation when the game is slowed, decrease the Fixed TimeStep under Edit > Project Settings > Time.
Though it may cause performance issues as you are simply allowing the physics engine to do more calculations in a single second.

If you do need help with optimizing, Unity has a documentation about it.


Update() always runs once per-frame.

For more details, Unity has a TimeFrameManagement documentation.

  • Related