Hi, I have been trying to figure out this mechanic for my platformer for days, and can’t quite seem to figure it out. I want to make a character mode where when an action is pressed, the character will move in a straight line in the last recorded direction of the stick. I want the stick to be disabled during this mode, so the player cannot change the direction without letting go of the action. I have a variable mapped to the analog stick vector, but I’m having trouble saving the velocity from the vector when the stick stops sending inputs. Here is my code as of now for this character mode. Currently when the action is pressed, I can move the character in all directions with the stick, but when I let go of the stick the player velocity goes to 0 and stops moving.
any help is much appreciated!
var input_direction := Input.get_vector("left", "right", "up", "down")
var last_direction = input_direction
#handles wave mode
if Input.is_action_pressed("wave") and not is_on_floor():
if input_direction:
rotation = input_direction.angle() + 1.55
velocity = last_direction * wave_speed
if input_direction.length() <= 0:
velocity = last_direction * wave_speed
I also have a rotation code that works as intended, it uses the input_direction.angle(). Velocity can’t take .angle, but that’s the direction I want the character to move.
Can you just add “and not Input.is_action_pressed(“wave”)” to whatever handles your analog input? Or nest your analog input in an if not Input.is_action_pressed(“wave”) :
I tried but its not very easy in this circumstance. Couldn’t make it work. I’m like a noob. I’m still not sure how to continue the velocity after the stick is disabled. I asked chatgpt, and it kept telling me to make two variables, one mapped to the stick, and one mapped to the to the first variable. Then it had an if statement to disable the stick. It still didn’t work.
It’s hard to help without a clearer idea of what your code structure looks like. Personally, I’d go with one of two options.
First is a state machine, which you can google all kinds of information on. It’s handy for a platformer, and in your case you’d implement a “wavedashing” state and work from there. Solid YT video on what I’m talking about https://www.youtube.com/watch?v=BNU8xNRk_oU
Second would be the following :
const WAVESPEED = 4
var waveDirection
func _on_input_event(viewport, event, shape_idx):
if event is InputEventJoypadMotion and Input.is_action_pressed("wave") == false:
# Code for handling analog joypad input goes here
pass
if event.is_action_just_pressed("wave"):
# Snapshots the analog stick's vector when 'wave' is first pressed
waveDirection = Input.get_vector("Left", "Right", "Up", "Down")
if event.is_action_pressed("wave"):
rotation = waveDirection.angle() + 1.55
velocity = waveDirection * WAVESPEED
if event.is_action_just_released("wave"):
waveDirection = null
# Code for handling what happens when the player releases 'wave'
Using AI i was able to keep the velocity when the input from the stick stopped with this code.
func wave_mode(delta):
var input_direction := Input.get_vector(“left”, “right”, “up”, “down”)
if Input.is_action_pressed("wave") and not is_on_floor():
if input_direction.length() > 0:
# Update last_direction when there is input
last_direction = input_direction.normalized()
rotation = input_direction.angle() + 1.55
else:
# If input_direction.length() <= 0, use the last direction
input_direction = last_direction
velocity = input_direction * wave_speed
Now to figure out how to disable the stick without messing anything up. I’m trying to use the just pressed concept you suggested. I’ll work on it more tomorrow.
Always good qustions. You are right I see how this would kill the rotation. I believe killing the velocity has to be relevant elsewhere, one thing to consider is as you move to a neutral position on the stick it will reach very close to, but not exactly zero. Perhaps in these small value cases length() returns >0 while normalized() returns (0,0,0).
Regardless I think these changes will be a good next step, using length_squared cuts out a square-root calculation; better to use this where possible for performance and potentitally more accurate values. And separating the and into two ifs so rotation is not cut off.
var stick_disabled = true
if Input.is_action_pressed("wave") and not is_on_floor():
if input_direction.length_squared() > 0.1:
if stick_disabled == false:
last_direction = input_direction.normalized()
rotation = input_direction.angle() + 1.55
else:
input_direction = last_direction
velocity = input_direction * wave_speed
How does the stick_disabled variable disable the stick inputs?
I tried both of your code snippets, the first one freezes the rotation and velocity to 0, and disables the stick. the second one freezes the velocity unless there is stick input, and the stick isn’t disabled.
Is there a way to stop receiving inputs from the stick via input mapping?
stick_disabled is just an example, you would have to set it to false when/where ever you want to disabled the stick. You could un-map the stick but that seems excessive.
I still can’t quite get it right. The Boolean variable either isn’t working or I’m not doing it right. Seems like it should be simpler than this to disable an input than this.
Finally figured it out! I got the boolean variable to work properly. Here is the code below for any future internet travelers. Thanks to all the people who helped out!
func wave_mode(delta):
if input_enabled == true:
input_direction = Input.get_vector("left", "right", "up", "down")
if Input.is_action_pressed("wave") and not is_on_floor():
if input_direction.length_squared() > 0.1:
# Update last_direction when there is input
last_direction = input_direction.normalized()
rotation = input_direction.angle() + 1.55
input_enabled = false
else:
# If input_direction.length() <= 0, use the last direction
input_direction = last_direction
velocity = input_direction * wave_speed
else:
last_direction = input_direction.normalized()
rotation = 0
input_enabled = true