Hello, im new to godot (started like 5 weeks ago) and wanted to make a 2d game. i watched some tutorials and tried making a State machine since most of the tutorials said it was best to make a state machine for the long run. now i followed this tutorial:

and after follong it for the first 20 - 30 minutes there was an error
Cannot find member "movement_input" in base "player".

here is the code

idle state:

extends Node
class_name Idle


func update(Delta):
if player.movement_input.x != Vector2.ZERO:
      pass

player.gd

this is where the line of movement_input is

extends CharacterBody2D
class_name player

const SPEED = 300.0
const JUMP_VELOCITY = -400.0

# Get the gravity from the project settings to be synced with RigidBody nodes.
var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")
var jump_input = false
var jump_input_actuation = false
var climb_input = false
var dash_input = false
var movement_input = Vector2.ZERO


var current_state = null
var prev_state = null

@onready var STATES = $State

func _ready():
	for state in STATES.get_children():
		state.STATES = STATES
		state.Player = self

func _physics_process(delta):
	player_input()
	change_state(current_state.update(delta))
	default_move(delta)

func default_move(delta):

	if not is_on_floor():
		velocity.y += gravity * delta

	if Input.is_action_just_pressed("jump") and is_on_floor():
		velocity.y = JUMP_VELOCITY

	var direction = Input.get_axis("Left", "Right")
	if direction:
		velocity.x = direction * SPEED
	else:
		velocity.x = move_toward(velocity.x, 0, SPEED)

	move_and_slide()


func change_state(Input_state):
	if Input_state != null:
		prev_state = current_state
		current_state = Input_state
		prev_state.exit_state()
		current_state.enter_state()

func player_input():
	movement_input = Vector2.ZERO
	if Input.is_action_pressed("right"):
		movement_input.x += 1
	
	if Input.is_action_pressed("left"):
		movement_input.x -= 1
	
	if Input.is_action_pressed("up"):
		movement_input.y -= 1
	
	if Input.is_action_pressed("down"):
		movement_input.y += 1
	
	if Input.is_action_pressed("jump"):
		jump_input = true
	else: 
		jump_input = false
	
	if Input.is_action_pressed("jump"):
		jump_input_actuation = true
	else: 
		jump_input_actuation = false
	
	if Input.is_action_pressed("climb"):
		climb_input = true
	else: 
		climb_input = false
	
	if Input.is_action_pressed("dash"):
		dash_input = true
	else: 
		dash_input = false

Tried renaming the movement_input to just movementinput didnt work either.
thanks for the help

    Riper In idle state you use name player" as it was an object, however it is a class name (as declared in played.gd) so when you use it like this, GDscript expectsmovement_input` to be a static property, which it isn't.

      xyz
      so i removed "class_name player" but now it says that player isnt declared in the current scope.
      so did i understand it wrong or was there another way to fix it?

      • xyz replied to this.

        Riper In idle, you need to make a variable (let's call it my_player) that references the node that has the player.gd script attached. Then my_player will act like an instance of the player.gd class and you'll be able to access its properties and call its method.

        You can get a reference to node by calling get_node() or using a literal path to node prefixed by $

        var my_player = get_node("path/to/node")
        if my_player .movement_input.x != 0:
              pass

        or

        var my_player = $"path/to/node"
        if my_player .movement_input.x != 0:
              pass

        To avoid constantly referring to paths, you can get the reference to node only once. It's typically done in node's _ready() callback:

        var my_player
        func _ready():
              my_player = $"path/to/node"

          xyz
          My Bad if i Understand incorrect but:
          Player aka. CharacterBody2D(i think it was called) counts as a node right?
          so if i do:
          var my_player = get_node $CharacterBody2D`
          And the script is Also in that CharacterBody2D so it gets referenced too right?
          thanks again for the help

          • xyz replied to this.

            Riper If the script is attached to the same node then you use self to reference that node:

            self.movement_input.x

            Or just nothing since self object is implied:

            movement_input.x

              xyz
              sorry its probably since im new but Can you Maybe explain a bit more in detail?

              • xyz replied to this.

                Riper What exactly is confusing you? It's like in any other object oriented language. You declare a class, instantiate an object of that class, and then access its properties using a variable containing reference to that object. In Godot, a node that script is attached to is considered an object (instance) of that script class.