Switching control between characters (NEWBIE)

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By jkme
:warning: Old Version Published before Godot 3 was released.

I’m completely new to programming and have no prior education. My only experience is using VBA to make some macros at work to enhance productivity. I apologize for my lack of expertise.

I’m making a 2d platforming game in which switching between two available characters would be the main mechanic. How would I achieve this? Currently for the two characters I have two KinematicBody nodes, both children of the main game node. These two have distinct names & sprites but are otherwise identical in terms of the children I’ve given them (collision, raycast, and a basic script for behavior and movement).

The script is the same for both characters, but named differently so they can be independently selected. Currently since I can’t choose between the two scripts, they both move the same when Input is entered. How can I set one character to be the “default” at game start, then switch over when Input is received from the keyboard? As the two characters also have other actions they can undertake, would a FSM that includes all available options be a good place to start?

Thank you very much for any assistance.

:bust_in_silhouette: Reply From: Rabbit

This is a perfect example of where you should split responsibilities into the smallest bits that still make logical sense. I’m willing to bet that when you actually break things down, your two controllable characters aren’t that different from any other character in the game, other than the player can control them directly.

So what you want to do, is split off the player control code into a separate script, and write it so that it controls the parent of whatever node the script is attached to (so you add the scripted node as a child to a character).

MyCharacter
    --> Sprite
    --> CollisionShape
    --> PlayerController

I want to reiterate this because it’s a core design philosophy: break things down into the smallest possible chunks that still make sense and accomplish a complete task.

:bust_in_silhouette: Reply From: rolfpancake

Currently since I can’t choose between the two scripts, they both move the same when Input is entered

Despite from the valid point of design philosophy you can switch control with a simple variable.

Example
Locally in the character1 script:

onready var active = true  # <- The default behaviour

func _input(event):
  if active:
    if event.is_action_pressed(...):
      ...

Locally in the character2 script:

onready var active = false  # <- Only difference is here

func _input(event):
  if active:
    if event.is_action_pressed(...):
      ...

Globally in the root node:

func _input(event):
  if event.is_action_pressed("switch_player"):
    # Just an ugly boolean switch :D
    var temp_state = $player2.active
    $player2.active = $player1.active
    $player1.active = temp_state