Global variables not updating for all scenes

Godot Version

4.4.1.stable

Question

On my game I am working on, I have a map, player and enemy. I tried to figure this out by myself and look it up, but I couldn’t find a solution. This is also my first post, so if you need more information, ask me.

When the enemy goes within a player’s area, it teleports to the player position and turns it’s collision off. It also triggers the HUD to show a timer and a “clicks left” label, which you have to press the space a couple times to shake the enemy off, but occasionally, the enemy stays on the player. In this scenario, everything but the enemy’s position and collision does it’s normal thing. The HUD goes back to as if there was no enemy on you, and the player moves normally. I narrowed it down and think that the reason is that the global variable “Free” (Not as in “Queue_free”, just a variable called that) updates for everything but that enemy. I also noticed that the first enemy that spawns works fine, and any others with it (Multiple can be on you at once) work fine. But if the first is not there, instead of the enemies going in a random direction away from you, they stay. Using the print method, I figured out that if the first-spawned enemy is not on you, the enemies that are on you don’t recognize that the global variable has been updated. I have no idea why, but please help. Also, the globals are defined in project settings > globals.

Here is the Global code:

extends Node

var player : Vector3

var slugs := 2
var slug_speed := 50.0
var keys := 3
var clicks := 10
var timer := 5

var collected_keys = 0
var unlocked_locks = 0
var captured = false
var free = false
var clicks_left = 0
var time_left = 10
var dead = false

This is the enemy code:

extends CharacterBody3D

var SPEED = Global.slug_speed
var offset : Vector3
const offset_range = 2
var found = false

var capturing = false
var flying = 0

@onready var slime = preload("res://Slugs/slime.tscn")
@onready var nav_agent := $NavigationAgent3D

# Called when the node enters the scene tree for the first time.
func _ready() -> void:
	SPEED += randi_range(-25, 25)
	if SPEED < 10:
		SPEED = 10
	offset = Vector3(randf_range(-offset_range, offset_range), 
	randf_range(-offset_range, offset_range), randf_range(-offset_range, offset_range))


# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
	
	#face_at(self, Global.player, delta*(Global.slug_speed / 25))
	
	#var y_velocity = velocity.y
	
	#velocity = -global_transform.basis.z.normalized() * SPEED * delta #Constantly move forward
	
	#velocity.y = y_velocity
	
	#if Engine.get_frames_per_second() < 10:
		#Global.lag = true
	#else:
		#Global.lag = false
	var new_slime = slime.instantiate()
	get_parent().add_child(new_slime)
	new_slime.global_position = global_position + Vector3(0, 0.05, 0)
	
	##Other test stuff
	##var material = preload("res://Slugs/slime.tres")
	##var newMaterial = material.duplicate()
	##new_slime.find_child("MeshInstance3D").set_surface_override_material(0, newMaterial)
	##$MeshInstance3D.set_surface_override_material(0, preload("res://Slugs/slime.tres"))
	
	if not is_on_floor():
		velocity += get_gravity() * delta
	
	#var current_location = global_transform.origin
	#var next_location = nav_agent.get_next_location()
	#var new_velocity = (next_location - current_location).normalized * SPEED * delta
	if global_position.distance_to(Global.player) < 5:
		found = true
		nav_agent.set_target_position(Global.player)
	else:
		if found:
			found = false
			offset = Vector3(randf_range(-offset_range, offset_range), 
			randf_range(-offset_range, offset_range), randf_range(-offset_range, offset_range))
		nav_agent.set_target_position(Global.player + offset)
	
	#velocity = new_velocity
	var destination = nav_agent.get_next_path_position()
	
	if Global.player.distance_to(global_position) > 1 and flying == 0:
		var local_destination = destination - global_position
		var direction = local_destination.normalized()
		
		velocity = direction * SPEED * delta
		
		Global.free = false
		
		rotation.y = lerp_angle(rotation.y, atan2(-velocity.x, -velocity.z), delta * 10)
	elif flying == 0:
		#velocity.move_toward(Vector3.ZERO, 25)
		velocity = Vector3.ZERO
		
	if flying > 0:
		var direction = (global_position - Global.player).normalized()
		var movement = direction * SPEED * 3 * delta
		velocity.x = movement.x
		velocity.z = movement.z
		#offset = Vector3(-10, 0, 0)
		#velocity *= -1
		flying -= 1
	
	if capturing:
		$CollisionShape3D.disabled = true
		global_position = Global.player
	else:
		$CollisionShape3D.disabled = false
	
	if Global.free:
		print("Free")
		print(flying)
		print(capturing)
		if capturing and flying == 0:
			capturing = false
			flying = 20
			#velocity *= -3
	if capturing:
		print(Global.free)
		print(flying)
		print(name)
	
	move_and_slide()
	print("Slug Free: " + str(Global.free))

func face_at(object : Node, Position : Vector3, Speed):
	var pos2d := Vector2(object.global_position.x, object.global_position.z)
	var target_pos2d := Vector2(Position.x, Position.z)
	var direction = (pos2d - target_pos2d)
	object.rotation.y = lerp_angle(object.rotation.y, atan2(direction.x, direction.y), Speed)

func capture(): #When the slug gets the player,
	capturing = true
	print("Capture")

func get_flying():
	return flying

Player code:

extends CharacterBody3D


var SPEED = 300.0
const JUMP_VELOCITY = 300.0
const FRICTION = 25
const GRAVITY = 0

var sensitivity := 0.002

var dead = false

@onready var twist_pivot := $TwistPivot
@onready var pitch_pivot := $TwistPivot/PitchPivot
@onready var raycast := $TwistPivot/PitchPivot/RayCast

func _ready() -> void:
	Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)

func _physics_process(delta: float) -> void:
	# Add the gravity.
	if not is_on_floor():
		velocity += get_gravity() * delta
	
	# Handle jump.
	if Input.is_action_pressed("Jump") and is_on_floor() and not Global.captured:
		velocity.y = JUMP_VELOCITY * delta
	
	# Get the input direction and handle the movement/deceleration.
	var input_dir := Input.get_vector("Move left", "Move right", "Move forward", "Move backward")
	var direction := (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
	
	if Input.is_action_just_pressed("ui_cancel"):
		if Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
			Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
		else:
			Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
	
	#$RayCast.global_rotation_degrees.x = pitch_pivot.global_rotation_degrees.x
	#$RayCast.global_rotation_degrees.y = twist_pivot.global_rotation_degrees.y
	
	if direction:
		var y_velcocity = velocity.y
		
		var movement = direction.x * twist_pivot.basis.x.normalized() * SPEED
		movement += direction.z * twist_pivot.basis.z.normalized() * SPEED
		velocity.x = movement.x * delta
		velocity.z = movement.z * delta
		
		if velocity.length() > SPEED:
			velocity = velocity.normalized() * SPEED
		velocity.y = y_velcocity
	else:
		#velocity = -twist_pivot.basis.z.normalized() * SPEED #Makes it constantly move forward in the 
		#direction you are looking
		
		velocity.x = move_toward(velocity.x, 0, FRICTION * delta)
		velocity.z = move_toward(velocity.z, 0, FRICTION * delta)
	
	Global.player = global_position
	
	if Global.captured:
		SPEED = 100.0
	else:
		SPEED = 300.0
	
	if Input.is_action_just_pressed("Interact"):
		if raycast.is_colliding():
			var collider : Node = raycast.get_collider()
			if collider.is_in_group("Key"):
				collider.queue_free()
				Global.collected_keys += 1
			elif collider.is_in_group("Door"):
				if Global.collected_keys > 0:
					Global.collected_keys -= 1
					Global.unlocked_locks += 1
					collider.get_child(4).queue_free() #Delete the 5th child (The first lock)
	
	if not Global.dead:
		move_and_slide()
	elif not dead:
		dead = true
		$AnimationPlayer.play("Death")

func _input(event: InputEvent) -> void:
	if not Global.dead:
		if event is InputEventMouseMotion:
			twist_pivot.rotate_y(-event.relative.x * sensitivity)
			pitch_pivot.rotate_x(-event.relative.y * sensitivity)
			pitch_pivot.rotation.x = clamp(pitch_pivot.rotation.x, deg_to_rad(-90), deg_to_rad(90))


func _on_area_body_entered(body: Node3D) -> void:
	if body.is_in_group("Slug"):
		if body.get_flying() == 0:
			if Global.clicks_left < 1:
				Global.time_left = Global.timer
			Global.clicks_left += Global.clicks
			body.capture()
			Global.captured = true

HUD code:

extends CanvasLayer

var previous_lag = false

var time_running = false

# Called when the node enters the scene tree for the first time.
func _ready() -> void:
	$Death.modulate.a8 = 0


# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
	$Game/Collected_keys_panel/Collected_keys.text = str(Global.collected_keys)
	if Global.lag and not previous_lag:
		previous_lag = true
		$Game/Lag.visible = true
	else:
		$Game/Lag.visible = false
	
	if Global.captured:
		if not time_running:
			time_running = true
			$Game/Captured/Time.start()
		$Game/Captured.visible = true
		if Input.is_action_just_pressed("Jump") and Global.time_left > 0 and Global.clicks_left > 0:
			Global.clicks_left -= 1
		$Game/Captured/Clicks.text = str(Global.clicks_left)
		$Game/Captured/Timer.text = str(Global.time_left)
		if Global.clicks_left < 1:
			Global.free = true
			Global.captured = false
	else:
		$Game/Captured.visible = false
	
	if Global.dead:
		if $Game.modulate.a8 > 0:
			$Game.modulate.a8 -= 10
		
		elif $Death.modulate.a8 < 255:
			Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
			$Death.modulate.a8 += 10
	
	if Global.free:
		print("Free: True hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii")
	else:
		print("Free: False")


func _on_time_timeout() -> void:
	Global.time_left -= 1
	if Global.time_left < 1 and Global.clicks_left > 0:
		Global.dead = true


func _on_replay_pressed() -> void:
	Global.dead = false
	Global.captured = false
	Global.collected_keys = 0
	Global.unlocked_locks = 0
	Global.time_left = 10
	Global.clicks_left = 0
	get_tree().change_scene_to_file("res://Maps/map_1.tscn")


func _on_home_pressed() -> void:
	get_tree().change_scene_to_file("res://Menus/start_screen.tscn")

Sorry, my code is kind of messy (I think)

Output (When the Global.free variable is updated):

Never mind, I just switched it to a signal instead of a variable and it works fine now.