All Questions

Community

N
Gregory Nikol

Deccelerate is not working...

I've followed this video three times starting from the Chapter 2: Base Movement project and I have not been able to replicate the deccelerate shown in this video. Sprinting works fine but nothing seems to trigger the decceleration.

I did notice that after this code was implemented the debug menu did not seem to understand what the run state was any more often (but inconsistently) mistaking it with the air state. I've attached all scripts that were modified for this video below.

EDIT (12/9/19): The issue was in Run.gd in the physis_process function. When the move.velocity.length() was moved up a line to create if owner.is_on_floor() and move.velocity.length < 1.0 it created a glitch where it could never enter idle and trigger the decceleration. To fix it I just nested the back half of the and statement as it was before (although specifying the requirements for the else statement would likely work just as well.)

Air.gd:

extends State

export var acceleration_x: = 5000.0

func unhandled_input(event: InputEvent) -> void:
	var move: = get_parent()
	move.unhandled_input(event)

func physics_process(delta: float) -> void:
	var move: = get_parent()
	move.physics_process(delta)

	# Landing
	if owner.is_on_floor():
		var target_state: = "Move/Idle" if move.get_move_direction().x == 0 else "Move/Run"
		_state_machine.transition_to(target_state)

func enter(msg: Dictionary = {}) -> void:
	var move: = get_parent()
	move.enter(msg)
	
	move.acceleration.x = acceleration_x
	if "velocity" in msg:
		move.velocity = msg.velocity 
		move.max_speed.x = max(abs(msg.velocity.x), move.max_speed.x)
	if "impulse" in msg:
		move.velocity += calculate_jump_velocity(msg.impulse)

func exit() -> void:
	var move: = get_parent()
	move.acceleration = move.acceleration_default
	move.exit()

"""
Returns a new velocity with a vertical impulse applied to it
"""
func calculate_jump_velocity(impulse: float = 0.0) -> Vector2:
	var move: State = get_parent()
	return move.calculate_velocity(
		move.velocity,
		move.max_speed,
		Vector2(0.0, impulse),
		Vector2.ZERO,
		1.0,
		Vector2.UP
	)


Run.gd:

extends State

export var max_speed_sprint: = 900.0

func unhandled_input(event: InputEvent) -> void:
	var move: = get_parent()
	move.unhandled_input(event)

func physics_process(delta: float) -> void:
	var move: = get_parent()
	move.max_speed.x = max_speed_sprint if Input.is_action_pressed("sprint") else move.max_speed_default.x
	
	if owner.is_on_floor() and move.velocity.length() < 1.0:
		_state_machine.transition_to("Move/Idle")
	else:
		_state_machine.transition_to("Move/Air")
	move.physics_process(delta)

func enter(msg: Dictionary = {}) -> void:
	get_parent().enter(msg)

func exit() -> void:
	get_parent().exit()

Move.gd:

extends State

export var max_speed_default: = Vector2(500.0, 1500.0)
export var acceleration_default: = Vector2(100000, 3000.0)
export var decceleration_default: = Vector2(500.0, 3000.0)
export var jump_impulse: = 900.0

var acceleration: = acceleration_default
var decceleration: = decceleration_default
var max_speed: = max_speed_default
var velocity: = Vector2.ZERO

func unhandled_input(event: InputEvent) -> void:
	if owner.is_on_floor() and event.is_action_pressed("jump"):
		_state_machine.transition_to("Move/Air", { impulse = jump_impulse })

func physics_process(delta: float) -> void:
	velocity = calculate_velocity(velocity, max_speed, acceleration, decceleration, delta, get_move_direction())
	velocity = owner.move_and_slide(velocity, owner.FLOOR_NORMAL)
	Events.emit_signal("player_moved", owner)

static func calculate_velocity(
		old_velocity: Vector2,
		max_speed: Vector2,
		acceleration: Vector2,
		decceleration: Vector2,
		delta: float,
		move_direction: Vector2
	):
	var new_velocity: = old_velocity
	
	new_velocity.y += move_direction.y * acceleration.y * delta
	
	if move_direction.x:
		new_velocity.x += move_direction.x * acceleration.x * delta
	elif abs(new_velocity.x) > 0.1:
		new_velocity.x -= decceleration.x * delta * sign(new_velocity.x)
		new_velocity.x = new_velocity.x if sign(new_velocity.x) == sign(old_velocity.x) else 0
	
	new_velocity.x = clamp(new_velocity.x, -max_speed.x, max_speed.x)
	new_velocity.y = clamp(new_velocity.y, -max_speed.y, max_speed.y)
	
	return new_velocity

static func get_move_direction() -> Vector2:
	return Vector2(
		Input.get_action_strength("move_right") - Input.get_action_strength("move_left"),
		1.0
	)


  • Z
    Luis Zuno replied
    if owner.is_on_floor(): 
        if move.velocity.length() < 1.0 :
          _state_machine.transition_to("Move/Idle") 
        else:
          _state_machine.transition_to("Move/Air")