Open Pyxus opened 1 year ago
I figured out how to do this and let me tell you this : It fall exactly into some forgotten crack in the system. By that I mean that the solution need to bypass some of the tools of FrayCombatStateMachine.
Conceptually, we are trying to determine if the button was pressed and released, or is it held. For the threshold I arbitrarily chose 0.35s. If the player release the button before 0.35s, it trigger a release, otherwise we simply ignore this signal and let the state machine check if the button is held.
There isn't a is_held
function in FrayInput, but it's easy to implement
## Returns [code]true[/code] if the [kbd]input[/kbd] is being held for [kdb]min_time_frame[/kdb] .
func is_held(input: StringName, min_time_frame: int = 500, device: int = DEVICE_KBM_JOY1) -> bool:
match _get_input_state(input, device):
var input_state:
return input_state.is_pressed && (Time.get_ticks_msec() - input_state.time_pressed) > min_time_frame
null:
return false
However, it was difficult to setup the combat state machine to interact correctly with the buffer_button. Basically you need to filter the input_detected. Here is my implementation :
FrayInput.input_detected.connect(func (_input_event : FrayInputEvent) :
if _input_event.input in ["R1","A",'X']: # Nothing special on those input
if(FrayInput.is_just_pressed(_input_event.input) or FrayInput.is_just_released(_input_event.input)):
csm.buffer_button(_input_event.input, _input_event.is_pressed())
elif _input_event.input == 'B' and not _input_event.is_pressed() and _input_event.get_time_held_sec() < 0.34:
csm.buffer_button(_input_event.input, false) # only send a release event if released before 0.34s
elif _input_event.input == 'B' and _input_event.is_just_pressed() :
csm.buffer_button(_input_event.input, true) # Only send pressed event.
,CONNECT_DEFERRED
)
# and in the CombatStateMachine
#...
# Dash using action button
.transition_button('idle','dash',{
input='B',prereqs=[_cond_on_floor],
is_triggered_on_release=true,
})
This is just a prototype since I just was able to make it work. I'll replace the code to send the the dash with a custom input ( probably 'b_tapped' ) in order to allow to use 'B' in other cases.
I hope I'm clear.
What was difficult to learn is the FrayInput.input_detected signal also is called on echo. I thought that it was only when an input is detected, basically no echo event.
As requested a example/tutorial on implementing contextual inputs should be created. An example of such input is the sprint/dodge button in souls games like Elden ring. When tapped the player enters a dodge state but if held the player enters a run state.