KevinTale
KevinTale

Reputation: 1858

Performance and optimisation while updating a property value in Update() with unity

I'm very new to Unity (im coming from the web industry) and I'm digging into Physics and unity lifecycle.

I'm wondering about performance and optimisation issue on a very basic topic which is updating a value at runtime.

Considering this snippet :

private void Update()
  {
    // updating movement value when user press WASD or arrow keys
    _movement = new Vector3(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"), 0);
  }

private void FixedUpdate()
  {
    Move(_movement, _speed);
  }

public void Move(Vector3 movement, float speed)
  {
    _rb.MovePosition(transform.position + (movement * speed * Time.deltaTime));
  }

As I understand it, Unity will update 60 times per second my _movement property, even though it hasnt changed. Isn't that a lack of optimisation? Is there a better way or is it totally fine? The same question would apply with If (Input.GetKeyDown( ... ) ) as I understand that 60 times per second it will check if the condition is true or not.

Is there some kind of Event system that could trigger the _movement or GetKeyDown without checking it constantly? If yes, is it a better practice?

Thanks!

Upvotes: 0

Views: 713

Answers (1)

Ruzihm
Ruzihm

Reputation: 20249

Polling for input in Update is standard.

In this specific case, you could just as well call Move in Update() and remove FixedUpdate() if you wanted, as _rb.MovePosition does interpolated movement regardless of the context it's called in:

private void Update()
{
    // updating movement value when user press WASD or arrow keys
    _movement = new Vector3(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"), 0);

    bool shouldMove = Mathf.Abs(_movement.x) > Mathf.Epsilon 
            || Mathf.Abs(_movement.y) > Mathf.Epsilon; 

    if (shouldMove) Move(_movement, _speed); 
}

public void Move(Vector3 movement, float speed)
{
    _rb.MovePosition(transform.position + (movement * speed * Time.deltaTime));
} 

The only reason you need to call something in FixedUpdate is if you have a reason for it to be called multiple times between renderings or updates to Input. In the specific case in the question, there is no such reason:

Consider the case where you call Move in Update. In a particularly laggy frame where the input * speed is abc and deltaTime is 0.2:

_rb.MovePosition(transform.position + abc * 0.2);
// transform.position is updated = starting position + abc * 0.2

And in the case where you call Move in FixedUpdate with that same laggy frame, where input * speed would stil be abc and fixedDeltaTime (or deltaTime) is 0.05:

_rb.MovePosition(transform.position + abc * 0.05);
// transform.position is updated = starting position + abc * 0.05
_rb.MovePosition(transform.position + abc * 0.05);
// transform.position is updated = starting position + abc * 0.1
_rb.MovePosition(transform.position + abc * 0.05);
// transform.position is updated = starting position + abc * 0.15
_rb.MovePosition(transform.position + abc * 0.05);
// transform.position is updated = starting position + abc * 0.2

Because the direction/magnitude that the _rb was being moved did not change between physics calculations, it is equivalent to putting it in Update and having it be called only once.

A counterexample where you would want to call Move in FixedUpdate would be a where a hazard causes controls to invert (i.e., some flag gets set) if _rb collides with it. Then, you would maybe want to check for that inversion flag having been set on each physics update.

Upvotes: 2

Related Questions