What is the best method to implement a dynamically activated walk mode?

I’m trying to implement an “always-ready-to-go” walk-mode which gets activated as soon as W/A/S/D key is pressed, and gets deactivated as soon as the key is released. This way, the samee key used for navigating in walk-mode will also dynamically engage and disengage the walk-mode. (As pressing shift+` to engage walk mode and then navigate, and then exiting walk mode to perform other operations breaks the flow)

For this I’ve done the following:

  1. Mapping the W/A/S/D key PRESS to view3d.walk()
  2. Mapping the W/A/S/D key RELEASE to confirm (i.e exit) walk mode

The problem I’m facing is:
Pressing and holding the W key results in a half-second delay between when walk mode is activated, and when the movement actually starts.
This results in having to wait for each walk mode interaction to initiate…

Alternatively, when the W key is pressed, immediately released, and then pressed again, this delay seems to be absent and the movement is engaged right-away.

I’m not sure whether this behavior is caused by some wait condition attached to pressing and holding a key, or if it’s a specific issue related to walk mode’s invoke function etc.

I’m looking to understand what’s causing this behavior and how it can be fixed, either by trying an entirely different approach or by poking around in the C code, if it can be fixed there… Any help is much appreciated.

I’d love to know too. I’ve tried to write an add-on that uses your gamepad as an always ready walkmode via a modal operator, but it didn’t really work.

Answering my own question.

I figured it out. Some background: If you set a keymap X to start a parent action and assign the same keymap to a modal operator associated with that parent action, when X is pressed and held, there will always be a delay between when the parent action is initiated and when the modal operator is called. This isn’t something specific to walk mode, but is a more universal behavior likely deliberately added for some important reason. So I stopped trying to change that.

INSTEAD, my solution requires you to get into build and change contents of source\blender\editors\space_view3d\view3d_walk. This may not be the best way to do it, but I’m a beginner and this got the job done and left me satisfied:

  1. Add a property to VIEW3D_OT_WALK to inform the operator which key was used to initiate it.
    For example, I assign the keymap W to view3d.walk() and also pass the property “walkInitiateKey”:‘WKEY’
    Likewise, the ‘A’ key is assigned to view3d.walk() and set to pass the property “walkInitiateKey”:‘AKEY’ and so on.
  2. I changed the walk_invoke() function to read the initiation key from the properties and pass the same to walkEvent() function.
  3. I modified the walkEvent() function to immediate initiate the required movement based on which initiation key was pressed.
  4. I modified the walkEvent() function to ‘confirm’ the walk and exit walk mode when all keys are released (i.e when walk->active_directions == 0)
  5. Some more changes were made to dynamically handle mouse movement in walk mode.

This sums up my process. With this, if ‘W’ key is pressed, walk mode is engaged and forward motion begins immediately. If W key is released, this movement stops. If you release all the keys pressed, walk mode closes, and then you can engage it again.

The only thing I want to want to fix now is: Pressing Q/E moves the view up/down along the Z axis. I want it to move the view up/down relative to the view. If somehow that can be fixed, I’ll have exactly what I need…

3 Likes