Need Help on Problem for 'owner‘ variable in FiniteStateMachine Script

Godot Version

GODOT 4.2.2

Introduction:

Previously, I used this Youtube video on making a boss using the state machine,

https://www.youtube.com/watch?v=otHfaomtJh0&t=468s

I tried to use it as a reference to create a sandworm trap and an arrow trap using this Youtube video.

SandwormTrap Nodes:

For the sandworm trap I created, I used the characterbody2d as the main node for the sandworm trap and the remaining nodes are
image
Sprite2D and Sprite2D2 are for the animation changing when changing from Idle state to Attack State or Attack State to Idle State.
image
The UI and the debug tag is for checking if the state is changing properly.

Sandworm Trap Scripts:

In SandwormTrap(CharacterBody2D) has a script called SandwormTrap.gd that contains the following lines:

extends CharacterBody2D

@onready var player = get_parent().find_child(“Player”)
@onready var sprite = $Sprite2D

var direction : Vector2

func _ready():
set_physics_process(false)

func _process(_delta):
direction = player.position - position
print(direction.length())

func _physics_process(_delta):
pass

For the FiniteStateMachine(Node2D) has a script named SandwormFiniteStateMachine.gd that contains the lines:

extends Node2D

var current_state: SandwormState
var previous_state: SandwormState

func _ready():
current_state = get_child(0) as SandwormState
previous_state = current_state
current_state.enter()

func change_state(state):
current_state = find_child(state) as SandwormState
current_state.enter()

previous_state.exit()
previous_state = current_state

And for each of the State(Idle and Attack) contains a StateScript that has named SandwormState.gd:

extends Node2D
class_name SandwormState

@onready var debug = owner.find_child(“debug”)
@onready var player = owner.get_parent().find_child(“Player”)
@onready var animation_player = owner.find_child(“AnimationPlayer”)

Called when the node enters the scene tree for the first time.

func _ready():
set_physics_process(false)

func enter():
set_physics_process(true)

func exit():
set_physics_process(false)

func transition():
pass

func _physics_process(_delta):
transition()
debug.text = name

and the state scripts are extended with another script.
For Idle State, it was extended with the scipt named Idle:

extends SandwormState
@onready var collision = $“…/…/PlayerDetection/CollisionShape2D”

var player_entered: bool = false:
set(value):
player_entered = value
collision.set_deferred(“disabled”, value)

func transition():
if player_entered:
get_parent().change_state(“Attack”)

func _on_player_detection_body_entered(_body):
player_entered = true

For Attack State, it was extended with the script named Attack:

extends SandwormState

func enter():
super.enter()
owner.set_physics_process(true)
animation_player.play(“Attack”)

func exit():
super.exit()
owner.set_physics_process(false)

func transition():
var distance = owner.direction.length()
print('distance ', distance)
if distance < 1:
get_parent().change_state(“Attack”)

ArrowTrap Nodes:

image
image
The nodes are basically the same with the SandwormTrap. So, I’m not gonna explain it again.

ArrowTrap Scripts:

The ArrowTrap(CharacterBody2D) has the script lines of this:

extends CharacterBody2D

@onready var player = get_parent().find_child(“Player”)
@onready var sprite = $Sprite2D

var direction : Vector2

func _ready():
set_physics_process(false)

func _process(_delta):
direction = player.position - position

For FiniteStateArrow(FiniteStateMachine) also has the script lines of this:

extends Node2D

var current_state: ArrowState
var previous_state: ArrowState

func _ready():
current_state = get_child(0) as ArrowState
previous_state = current_state
current_state.enter()

func change_state(state):
current_state = find_child(state) as ArrowState
current_state.enter()

previous_state.exit()
previous_state = current_state

The states are the same, they have State Script attached to them each(Arrow_Idle and Arrow_Attack) and it looked like this:

extends Node2D

class_name ArrowState

@onready var debug = owner.find_child(“Debug”)
@onready var player = owner.get_parent().find_child(“Player”)
@onready var animation_player = owner.find_child(“AnimationPlayer”)

func _ready():
set_physics_process(false)

func enter():
set_physics_process(true)

func exit():
set_physics_process(false)

func transition():
pass

func _physics_process(_delta):
transition()
debug.text = name

Problem 1:

My sandworm trap should be able to detect what’s the distance between ‘it’ and the player and when the distance between them is less than 1, it will change state from Idle to Attack as shown in the Attack Script of Sandworm Trap:

func transition():
var distance = owner.direction.length()
print('distance ', distance)
if distance < 1:
get_parent().change_state(“Attack”)

But it didn’t. It just executes it anyway even if the player is so far away from it.

Attempts:

I debugged the distance and the distance always to zero and I don’t understand why? I suspect it must’ve something wrong with the owner variabele or is it because I have two owner variable used within one game scene. What I mean by that was I duplicated the boss in this video:

and I also used the owner variable for that and another owner for my sandwormTrap.

Problems 2:

I can’t extend a script named Arrow_Attack.gd to my ArrowTrap Attack State, it just created this:
image
NO IDEA WHAT THIS IS

Attempts:

I suspect it might have been I created the Script for FiniteStateArrow and the state script another folder, so the file path to those Scripts is:
res://New folder/Arrow_State.gd
res://New folder/Arrow_Trap.gd
res://New folder/FiniteStateArrow.gd
The file path to the ArrowTrap scene is:
res://arrow_trap.tscn

Any help would be great thanks!

The owner property refers to the root node of the packed scene (the .tscn file) the given node is in.
You can use the distance_to() or distance_squared_to() functions to get distances. Although your method should work too…
You could try using global_position instead of position. position is relative to the node’s parent, so if the nodes have different parents then using position to get the distance between them will not work.

Thanks for the suggestion, I’ll try to that.