Godot Version
v4.2.stable.official [46dc27791]
Question
When the player flies, I’m trying to:
- Start with the jetpack intro anim
- Loop the main jetpack animation while jump button is held
- Play jetpack outro anim when jump button is released
This is done with the AnimationTree.
However, rather than loop the main jetpack animation, it cycles through the intro, loop, and outro before repeating the cycle.
I’m suspecting this is due to the code playing the animations being in a _physics_process() function. The problem is that I only need the code to travel to the jetpack intro once while also checking for the jump input constantly.
Here’s my AnimationTree:
Here’s my player code (even though most of the code isn’t relevant to my issue, I’m still including it for the bigger picture):
# Player camera is its own seperate scene.
extends CharacterBody2D
const SPEED = 600.0
const JUMP_VELOCITY = -40.0
@export_range(0.0, 1.0) var friction = 0.3
@export_range(0.0 , 1.0) var acceleration = 0.25
var directionX = 1
var bumped = false
var alive = true
var jumping = false
var grabbing = false
var launched = false
@export var state = 1
# Get the gravity from the project settings to be synced with RigidBody nodes.
var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")
# Nodes
@onready var ray_cast_left = $RayCastLeft
@onready var ray_cast_right = $RayCastRight
@onready var animated_sprite = $AnimatedSprite2D
@onready var animation_player = $AnimationPlayer
# Sounds
@onready var mach_sound = $MachSound
@onready var bump_sound = $BumpSound
@onready var death_scream_sound = $DeathScreamSound
@onready var explosion_sound = $ExplosionSound
@onready var electric_sound = $ElectricSound
@onready var hurt_sound = $HurtSound
# Anim state machine
var run_speed = 80.0
@onready var state_machine = $AnimationTree["parameters/playback"]
# Signals
signal damage_taken()
signal boing_boing()
func bump(dir_x, ray_cast, flip):
# Variables!
ray_cast.enabled = false
mach_sound.playing = false
bump_sound.playing = true
bumped = true
# Play bump
animated_sprite.play("bump")
await get_tree().create_timer(0.3).timeout
# Flip it around
directionX = dir_x
animated_sprite.flip_h = flip
animated_sprite.play("fly")
# More variables!
mach_sound.playing = true
bumped = false
# Enable raycast after 1 sec; DON'T PUT VARIABLES BELOW THIS!!!
await get_tree().create_timer(0.1).timeout
ray_cast.enabled = true
func death(kill_type):
print("lmao")
set_collision_mask_value(1, false)
# No longer a living Noise to make some Noise
alive = false
velocity.y = -400
launched = true
mach_sound.playing = false
state_machine.travel("death")
# Noise and Noise Torture - Now with sounds!
# 0 = default
if kill_type == 0:
hurt_sound.playing = true
death_scream_sound.playing = true
explosion_sound.playing = true
# 1 = death by outlet
elif kill_type == 1:
hurt_sound.playing = true
death_scream_sound.playing = true
electric_sound.playing = true
explosion_sound.playing = true
func jump():
jumping = true
grabbing = false
state_machine.travel("boxxed_jetpackintro")
velocity.y += JUMP_VELOCITY
func grab():
jumping = false
grabbing = true
state_machine.travel("boxxed_hitstart")
#var grab_speed = 1000 * animated_sprite.scale.x
#velocity.x = grab_speed
#velocity.y = 0
await get_tree().create_timer(1).timeout
grabbing = false
func _physics_process(delta):
if state == 0:
# Bump and turn stuff
if ray_cast_left.is_colliding() and alive:
bump(1, ray_cast_left, false)
elif ray_cast_right.is_colliding() and alive:
bump(-1, ray_cast_right, true)
# Add the gravity.
var directionY = Input.get_axis("move_up", "move_down")
if not bumped and alive:
velocity.y = directionY * (SPEED / 2)
#print("HEEHEE")
elif not alive and launched:
velocity.y += gravity * delta
#print(velocity.y)
elif alive and not launched:
velocity.y = 0
#print("LOL")
# Get the input direction and handle the movement/deceleration.
var directionX = Input.get_axis("move_left", "move_right")
if alive:
velocity.x = (directionX * SPEED) + (acceleration * 150)
else:
velocity.x = (-directionX * SPEED)
# Fly anim FPS
if abs(velocity.x) == SPEED:
animated_sprite.sprite_frames.set_animation_speed("fly", 24)
elif abs(velocity.x) > SPEED:
animated_sprite.sprite_frames.set_animation_speed("fly", 30)
elif abs(velocity.x) < SPEED:
animated_sprite.sprite_frames.set_animation_speed("fly", 18)
move_and_slide()
elif state == 1:
velocity.y += gravity * delta
var dir = 0
if grabbing:
dir = 0
else:
dir = Input.get_axis("move_left", "move_right")
if alive and not grabbing:
if dir != 0:
velocity.x = lerp(velocity.x, dir * SPEED, acceleration)
else:
velocity.x = lerp(velocity.x, 0.0, friction)
elif alive and grabbing:
velocity.x = 500 * animated_sprite.scale.x
else:
velocity.x = (-directionX * SPEED)
if alive:
# Handle animations.
if velocity.x != 0:
animated_sprite.scale.x = sign(velocity.x)
if not grabbing:
if abs(velocity.x) >= 10 and is_on_floor():
state_machine.travel("boxxed_walk")
elif not is_on_floor() and not Input.is_action_pressed("jump"):
state_machine.travel("boxxed_fall")
#elif not is_on_floor() and Input.is_action_pressed("jump"):
#state_machine.travel("boxxed_jetpackintro")
elif is_on_floor() and not Input.is_action_pressed("jump"):
state_machine.travel("boxxed_idle")
# Handle misc actions
if Input.is_action_pressed("jump"):
jump()
#velocity.y += JUMP_VELOCITY
if Input.is_action_pressed("grab"):
grab()
#grabbing = true
#state_machine.travel("boxxed_hitstart")
#var grab_speed = 1000 * animated_sprite.scale.x
#velocity.x = grab_speed
#velocity.y = 0
#await get_tree().create_timer(1).timeout
#grabbing = false
move_and_slide()