Godot Version
Godot Engine v4.2.2.stable.official.15073afe3
Question
In my game, I have it so that when my player character jumps on buttons, it allows them to change characters. Previously this worked, but ever since adding multiple player characters as well as the join() and leave() functions, it just simply does not work. The attached video shows the character jumping on buttons and nothing happening, followed by a showcase of the leave() and join() functions.
Video
Scene Tree
Control Scene:
Player Scene:
Code
Control Script:
extends Control
var buttons = []
var button_name = ""
var pressed = []
@onready var grid = $GridContainer
@onready var select_man = $"select man"
@onready var area = select_man.get_node("Area2D")
@onready var area2 = select_man.get_node("Area2D2")
@onready var anim_player = $AnimationPlayer
func _ready():
buttons = grid.get_children()
area.area_entered.connect(button_press)
area2.area_entered.connect(button_press)
func _process(delta):
pass
func button_press(pressed_button):
button_name = pressed_button.get_parent().name.substr(0, pressed_button.get_parent().name.length() - 7)
select_man.previous_character = select_man.current_character
if button_name not in pressed:
pressed.append(button_name)
select_man.current_character = button_name
anim_player.play("%sPressed" % button_name)
else:
pressed.erase(button_name)
select_man.current_character = "selectMan"
anim_player.play("%sNormal" % button_name)
select_man.landed_on_button = true
character_change()
print("pressed ", button_name, " ", pressed)
func character_change():
match select_man.current_character:
"selectMan":
select_man.speed = 75
"cowboy":
select_man.speed = 75
"orbulon":
select_man.speed = 55
"joker":
select_man.speed = 100
"chimera":
select_man.speed = 40
Player Script:
extends CharacterBody2D
var direction := Vector2.ZERO
var speed = 75
var can_flip = true
var target_velocity = Vector2.ZERO
var smoothing = 7.5
var check = false
var current_character = "selectMan"
var previous_character = ""
var landed_on_button = false
var can_change = false
@export var id = 1
var gunshot = preload("res://scenes/selectManShot.tscn")
var orb = preload("res://scenes/selectManOrb.tscn")
var orb_instance: Node2D = null
@onready var sprite = $Sprite2D
@onready var long_sprite = $"Long Sprite"
@onready var anim_player = $AnimationPlayer
@onready var area = $Area2D
@onready var area2 = $Area2D2
@onready var area3 = $Area2D3
@onready var raycast = $RayCast2D
@onready var shot_spawn = $"Shot Spawn"
@onready var orb_spawn = $"Orb Spawn"
enum State { IDLE, RUNNING, JUMPING, CHALLENGING, INACTIVE, JOINING }
var state = State.INACTIVE
func _ready():
#Engine.time_scale = 0.5
pass
func _process(delta):
if (previous_character == "joker" or "chimera") and landed_on_button:
state = State.IDLE
can_flip = true
$Area2D/CollisionShape2D.disabled = true
$Area2D2/CollisionShape2D.disabled = true
landed_on_button = false
if previous_character == "orbulon" and landed_on_button:
if orb_instance != null:
orb_instance.queue_free()
func _physics_process(delta):
movement()
jump()
challenge()
join()
leave()
if state in [State.IDLE, State.RUNNING]:
velocity = direction * speed
move_and_slide()
elif state in [State.JUMPING, State.JOINING]:
velocity = velocity.lerp(target_velocity, smoothing * delta)
move_and_slide()
func movement():
if state in [State.IDLE, State.RUNNING]:
match current_character:
"selectMan":
speed = 75
"cowboy":
speed = 75
"orbulon":
speed = 55
"chimera":
speed = 40
smoothing = 7.5
if direction.length() > 0:
state = State.RUNNING
if current_character != "orbulon":
anim_player.play(current_character + "Run")
else:
anim_player.play("orbulonIdle")
else:
check = false
state = State.IDLE
anim_player.play(current_character + "Idle")
direction = Input.get_vector("p%sleft" % id, "p%sright" % id, "p%sup" % id, "p%sdown" % id).normalized()
speed = 75
can_flip = true
if can_flip:
if direction.x < 0:
sprite.flip_h = true
long_sprite.flip_h = true
area.position = Vector2(1, 0)
area2.position = Vector2(1, 0)
area3.position = Vector2(0.5, 0)
raycast.scale.x = -1
raycast.position = Vector2(9, 0)
shot_spawn.position = Vector2(1, 4)
orb_spawn.position = Vector2(0, -5)
elif direction.x > 0:
sprite.flip_h = false
long_sprite.flip_h = false
area.position = Vector2(0, 0)
area2.position = Vector2(0, 0)
area3.position = Vector2(-0.5, 0)
raycast.scale.x = 1
raycast.position = Vector2(-9, 0)
shot_spawn.position = Vector2(-1, 4)
orb_spawn.position = Vector2(-1, -5)
func jump():
if Input.is_action_pressed("p%sroll" % id) and state in [State.IDLE, State.RUNNING]:
check = false
match current_character:
"selectMan":
speed = 0
"cowboy":
speed = 150
"orbulon":
speed = 0
"joker":
speed = 0
"chimera":
speed = 0
state = State.JUMPING
can_flip = false
anim_player.play(current_character + "Jump")
match current_character:
"cowboy":
var gunshot_instance = gunshot.instantiate()
gunshot_instance.position = shot_spawn.global_position
gunshot_instance.z_index = -1
get_parent().add_child(gunshot_instance)
await gunshot_instance.get_node("AnimationPlayer").animation_finished
gunshot_instance.queue_free()
"orbulon":
orb_instance = orb.instantiate()
orb_instance.position = orb_spawn.global_position
if sprite.flip_h:
orb_instance.flip_dir = true
else:
orb_instance.flip_dir = false
get_parent().add_child(orb_instance)
await anim_player.animation_finished
if state != State.INACTIVE:
state = State.IDLE
if state == State.JUMPING:
direction = Input.get_vector("p%sleft" % id, "p%sright" % id, "p%sup" % id, "p%sdown" % id).normalized()
target_velocity = direction * speed
func anim_check():
if anim_player.current_animation == current_character + "Jump":
if check == false:
match current_character:
"selectMan":
speed = 50
"cowboy":
speed = 25
"joker":
speed = 100
"chimera":
speed = 125
smoothing = 2.5
check = true
elif check == true:
speed = 0
if current_character == "orbulon":
var orb_position = orb_instance.global_position
if sprite.flip_h:
global_position = orb_position - Vector2(0, -5)
else:
global_position = orb_position - Vector2(-1, -5)
check = false
if anim_player.current_animation == "jokerRun":
if check:
speed = 0
check = false
else:
speed = 100
check = true
func challenge():
if Input.is_action_just_pressed("p%sattackA" % id) and state in [State.IDLE, State.RUNNING] and current_character != "selectMan":
state = State.CHALLENGING
speed = 0
print("challenge")
anim_player.play(current_character + "Challenge")
await anim_player.animation_finished
anim_player.play(current_character + "ChallengeIdle")
if Input.is_action_just_pressed("p%sattackA" % id) and anim_player.current_animation == current_character + "ChallengeIdle":
anim_player.play(current_character + "ChallengeEnd")
await anim_player.animation_finished
state = State.IDLE
func join():
if Input.is_action_just_pressed("p%sattackA" % id) and state == State.INACTIVE:
state = State.JOINING
can_flip = false
var start_pos = Vector2(position)
var target_pos = Vector2(position.x, position.y)
var duration = 1.0
var t = 0.0
start_pos.y = -40.0
position = start_pos
anim_player.play("selectManJoin")
while t < 1.0:
t += get_process_delta_time() / duration
t = clamp(t, 0, 1)
direction = Input.get_vector("p%sleft" % id, "p%sright" % id, "p%sup" % id, "p%sdown" % id)
speed = 75
target_pos += direction * speed * get_process_delta_time()
position.x = lerp(position.x, target_pos.x, 0.2)
position.y = lerp(start_pos.y, target_pos.y, t*t*t)
await get_tree().process_frame
await anim_player.animation_finished
state = State.IDLE
func leave():
if Input.is_action_just_pressed("p%sattackB" % id) and state not in [State.INACTIVE, State.JOINING]:
state = State.INACTIVE
sprite.scale = Vector2.ONE
velocity = Vector2.ZERO
anim_player.play("%sPop" % current_character)

