Archive 17/01/2023.

GetKeyPress() in physics update loop doesn’t always react

TheComet

It seems like the physics update is asynchronous to the normal update - that is, there’s no guarantee on the order in which FixedUpdate() and Update() will be called. Sometimes Update() could be called twice before FixedUpdate() is called and vice-versa.

This is a problem when using GetKeyPress() inside of FIxedUpdate(). It doesn’t always respond. Some example code:

class Foo : public Urho3D::LogicComponent { public: virtual void Update(float timeStep) override { if(input_->GetKeyPress(KEY_SPACE)) puts("key pressed in Update()"); } virtual void FixedUpdate(float timeStep) override { if(input_->GetKeyPress(KEY_SPACE)) puts("key pressed in FixedUpdate()"); } };

Output after pressing space a few times:

key pressed in FixedUpdate() key pressed in Update() key pressed in FixedUpdate() key pressed in Update() key pressed in FixedUpdate() key pressed in Update() key pressed in Update() key pressed in Update() key pressed in FixedUpdate() key pressed in Update() key pressed in Update() key pressed in FixedUpdate() key pressed in Update() key pressed in Update() key pressed in Update() key pressed in FixedUpdate() key pressed in Update() key pressed in Update() key pressed in Update() key pressed in FixedUpdate() key pressed in Update() key pressed in Update() key pressed in FixedUpdate() key pressed in Update() key pressed in FixedUpdate() key pressed in Update()

What’s the best way to approach this problem? I suppose you could argue that asking for keypresses in FixedUpdate() is wrong, but I have to put my physics code in FixedUpdate().

1vanK

FixedUpdate always calls with fixed rate (60 fps by default). You can independently detect keyressing

bool oldKeySpaceDown = false;

void FixedUpdate()
{
    if (KeyDown(KEY_SPACE) && !oldKeySpaceDown)
    {
        ReactKeySpacePress();
    }
    ...
    oldKeySpaceDown = KeyDown(KEY_SPACE);
}
TheComet

Thanks, that worked!

cadaver

GetKeyPress() can be reliably called only in Update() which is called once per engine frame. FixedUpdate() may be called multiple times or not at all on some frame, so the keypress state change may have already happened. The workaround by 1vanK is fine to use, though.