Leafwing-Studios / leafwing-input-manager

A straightforward stateful input manager for the Bevy game engine.
Apache License 2.0
710 stars 108 forks source link

Accessible DeadZone input handling #398

Closed atlv24 closed 10 months ago

atlv24 commented 1 year ago

What problem does this solve?

DeadZoneShape is not accessibility friendly

What solution would you like?

This discussion is a good read: https://github.com/godotengine/godot-docs/issues/5378#issuecomment-965734470

my conclusions: there should be two primary modes: circle, and cross. Circle has no amount of axis snapping, because sometimes its not desirable, and cross has some amount of axis snapping. Both circle and cross do range shifting such that all possible inputs are reachable and continuous, (meaning, a small change in input vector causes at most a proportionally small change in output vector. all current deadzones in LWIM do not do this, because crossing the deadzone threshold snaps from 0 to whatever the value is outside the deadzone).

Single axis: if input.abs() < deadzone { None } else { Some(input.sign() * (input.abs() - deadzone)) } Circle: if input.magnitude() < deadzone { None } else { Some(input.normalized() * (input.magnitude() - deadzone)) } Cross: handled like single-axis for each axis individually

[Optional] How could this be implemented?

Allow deadzone shapes to mutate the passed-in input by returning an Option<Vec2> instead of a bool. This allows input to be continuous and have unreachable input range, by rescaling/shifting live areas to be zero input on deadzone edges as follows: 141191045-5b6520c5-980e-4df7-917c-d834a6c64a72

This should also be implemented for single axis deadzones, otherwise they will have small unreachable input ranges near zero

[Optional] What alternatives have you considered?

Related work

Lots of other deadzones that can be supported in the future: https://imgur.com/a/xSfcP (most interesting concepts are Back 4 Blood's unregistered diagonal wedges and Anarchy Reigns' two-threshold central deadzone where once you start moving, a smaller threshold must be returned to to stop moving)

atlv24 commented 1 year ago

We may even want to make DeadZoneShape be a user-impl-able trait to support custom deadzone logic cleanly tbh

alice-i-cecile commented 1 year ago

We may even want to make DeadZoneShape be a user-impl-able trait to support custom deadzone logic cleanly tbh

Honestly, I agree with this. It's not performance sensitive and it's very good to add flexibility.