class_name DoubleJumpAbility extends RunnerAbility const DECELERATION_FACTOR: float = 0.9 const INITIAL_COMPENSATION_FACTOR: float = 2.5 func begin(runner: Runner) -> void: if not runner.floor_normal.is_zero_approx(): runner.change_state(&'jump') else: runner.linear_velocity += ( runner.up_normal*runner.jump_strength*INITIAL_COMPENSATION_FACTOR ) func integrate_forces( runner: Runner, body_state: PhysicsDirectBodyState3D ) -> void: if runner.animation_player.current_animation != &'fall': body_state.linear_velocity = ( body_state.linear_velocity.slide(runner.up_normal) + body_state.linear_velocity.project(runner.up_normal)*( DECELERATION_FACTOR ) ) if not runner.floor_normal.is_zero_approx(): runner._play_land_sound_if_landing_hard_enough() runner.change_state(&'run') elif not runner.wall_normal.is_zero_approx(): runner.change_state(&'wall_slide') elif ( body_state.linear_velocity.normalized().dot(runner.up_normal) < 0.125 ): runner.animation_player.play(&'fall') elif runner.abnormal_gravity(body_state): runner.change_state(&'swim') func orientation(runner: Runner) -> Vector3: return runner.linear_velocity func animation_speed(_runner: Runner) -> float: return 1.0