Reputation: 1858
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
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