Godot Version
Godot 4.2
Question
Im making a 2d platform game but i don’t know how to make a swapping character mechanics during the game, character 1 and character 2 are two different scenes, character 1 is normal, he runs normal and jumps normal while character 2 runs faster and jumps higher, if you press a button, character 1 swaps with character 2 if you press a button again, character 2 swaps with character 1, can anyone help me with script?
Hi, try showing what progress you have made and expand on what pitfalls you have run into.
If you talking about gdscript here is:
extends CharacterBody2D
const SPEED = 300.0
const JUMP_VELOCITY = -500.0
@onready var animatedsprite = $AnimatedSprite2D
Reference to the other character
var other_character: CharacterBody2D
Get the gravity from the project settings to be synced with RigidBody nodes.
var gravity = ProjectSettings.get_setting(“physics/2d/default_gravity”)
func _ready():
add_to_group(“player”)
func _physics_process(delta):
# Add the gravity.
if not is_on_floor():
velocity.y += gravity * delta
# Handle jumping
if Input.is_action_just_pressed("ui_jump") and is_on_floor():
velocity.y = JUMP_VELOCITY
animatedsprite.play("jump")
# Handle movement
var direction = Input.get_axis("ui_left", "ui_right")
if direction:
velocity.x = direction * SPEED
animatedsprite.play("walk")
# Flip the sprite based on the direction
animatedsprite.flip_h = direction < 0
else:
velocity.x = move_toward(velocity.x, 0, SPEED)
animatedsprite.play("default")
move_and_slide()
I see your character controller, very nice.
I see that in the character controller theres a other_character
. I assume that’s the character you want to swap in?
Have you tried something like:
var parent = get_parent()
parent.remove_child(self)
parent.add_child(other_character)
I think the best simple approach you can do is treating your caracters as “actors”. So you add an “Actor” component to your CharacterBody2D thats provides the capability of moving (not controlling). The controlling part you can add it as a separate component. This is not mandatory but it gives you the capability of decoupling the moving feature from the controlling feature, that might be input, IA, alternative intput, etc…
So it would be something like:
actor_component.gd
class_name ActorComponent
extends Node
@export var speed := 130.0
@export var jump_velocity := -300.0
var _gravity = ProjectSettings.get_setting("physics/2d/default_gravity")
@onready var character: CharacterBody2D = get_parent()
func _physics_process(delta):
_fall(delta)
character.move_and_slide()
func move(new_direction: float):
character.velocity.x = new_direction * speed
func jump():
if character.is_on_floor():
character.velocity.y = jump_velocity
func _fall(delta):
if not character.is_on_floor():
character.velocity.y += _gravity * delta
Note it has to be direct child of CharacterBody2D unless you change the way of referencing the CharacterBody2D (line 9)
input_controller.gd
class_name InputController
extends Node
@export var actor: ActorComponent
@export var in_control := true
func _physics_process(_delta):
if in_control:
var direction = Input.get_axis("move_left", "move_right")
actor.move(direction)
func _input(event):
if in_control:
if event.is_action_pressed("jump"):
actor.jump()
In this case you add the Actor reference through the editor, so you can place it anywere.

The input controller has an “in_control” variable. If you have 2 characters and both characters has Actor and Input components you just have to update whos having “in_control” var to true.
Hope this helps!
Maybe having a boolean, “enabled” in the Character will be enough in your case,
but here is a way to do it using a Command Design Pattern:
1 Like
if Input.is_action_just_pressed("change"):
if state >= 2:
state = 1
$Armature.rotation = Vector3(0,0,0)
else:
state += 1
this what I did with my switching but mine uses the same character, but you could probably find a way to have it switch sprites
1.what about the button that makes character switch with another character?
2.the character I’m controlling is moving too fast