Assigning multiple values to a node

Godot Version

4

Question

So when my level changes it goes to a new camera, and this is attached to the player character. Is there a way to either add multiple cameras to one variable or make the camera a single constant global variable? All of this code is attatched to the player currently, but would it work better to make it a global thing?

@onready var camera_sync: Camera2D = $"../Camera2D"

yeah I think its better if you make it a global thing because to make multiple cameras to one variable contains alot of steps and errors.

how could i go about switching it over? I tried to just copy and paste the parts involving the camera to my global script, but it didn’t work. Is there a different setup for global?

What do you want to happen? Is there a problem with using a new camera?

yes the camera doesn’t work because its a different one, the whole level crashes, and i want to make it so theres one consistent camera across levels

Seems strange for something to reference a sibling camera and survive a level change while the camera is destroyed. I assume you aren’t using get_tree().change_scene_to_file or neither would persist, and only a global would. Maybe sharing more about how you change levels and where the camera is would help to find a solution.

1 Like

ok heres my full code for the character:
“”"extends CharacterBody2D

class_name Player

var gravity = ProjectSettings.get_setting(“physics/2d/default_gravity”)

@onready var animated_sprite_2d = $Sprite2D as PlayerAnimatedSprite
@onready var area_collision_shape = $“Area2D/area collision shape”
@onready var body_collision_shape = $bodycollisionshape
@onready var area_2d = $Area2D

var run_speed_damping = 0.5
var speed:float = 300.0
var jump_velocity = -400

@onready var min_stomp_degree = 35
@onready var max_stomp_degree = 145
@onready var stomp_y_velocity = -150

@onready var camera_sync: Camera2D = $“../Camera2D”
@onready var should_camera_sync: bool = true

func _physics_process(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
	
if Input.is_action_just_released("jump") and velocity.y < 0:
	velocity.y *= 0.5
	
var direction = Input.get_axis("left","right")

if direction:
	velocity.x = lerpf(velocity.x, speed * direction, run_speed_damping * delta)
else:
	velocity.x = move_toward(velocity.x, 0, speed * delta)

animated_sprite_2d.trigger_animation(velocity, direction)

move_and_slide()

func _on_area_2d_area_entered(area):
if area is Enemy:
handle_enemy_collision(area)
print(“lalal”)
if area is Block:
handle_block_collision(area)

func handle_block_collision(block: Block):
if block == Block:
die()

func handle_enemy_collision(enemy: Enemy):
if enemy == null:
return

var angle_of_collision = rad_to_deg(position.angle_to_point(enemy.position))

if angle_of_collision > min_stomp_degree && max_stomp_degree > angle_of_collision:
	enemy.die()
	on_enemy_stomped()
else:
	die()

func on_enemy_stomped():
velocity.y = stomp_y_velocity

func die():
animated_sprite_2d.play(“die”)
area_2d.set_collision_mask_value(3, false)
set_collision_layer_value(1, false)
set_physics_process(false)

var death_tween = get_tree().create_tween()
death_tween.tween_property(self, "position", position + Vector2(0, -48), .5)
death_tween.chain().tween_property(self, "position", position + Vector2(0,256),1)
death_tween.tween_callback(func (): get_tree().reload_current_scene())

func _process(_delta):
if global_position.x > camera_sync.global_position.x && should_camera_sync:
camera_sync.global_position.x = global_position.x
if global_position.x < camera_sync.global_position.x && should_camera_sync:
camera_sync.global_position.x = global_position.x

func _on_brick_2_body_entered(_body: Node2D):
die()
“”"

and here is the scene change code:
“”" func process(delta):
if entered == true:
var current_scene_file = get_tree().current_scene.scene_file_path
var next_level_number = current_scene_file.to_int() + 1
var next_level_path = "res://levels/world
" + str(next_level_number) + “.tscn”
get_tree().change_scene_to_file(next_level_path)
“”"

I create my cameras in the project’s main scene, and assign it to a group from within the editor. I then use get_tree().get_first_node_in_group() to retrieve it in code as needed.

So you do use get_tree().change_scene_to_file, I don’t think a global is the best solution. What error do you get exactly? Changing the scene in _process also seems error prone, why not change the scene when you set entered to true? Best to avoid _process for things that do not happen every frame, use signals/events for as much as you can. I’m not sure that the camera is the issue.

the scene does change when entered is true, I just set it up to work with a folder I made. That part works just fine, Its just getting the camera to follow to the next scene

You mentioned the whole level crashes, what error message do you get? Could you post the remote scene tree during the debugging too?


Are you sure World2 has a camera named Camera2D next to the player? Could you expand the remote tab entirely or use print_tree_pretty()

like this?

It seems to me like you’re overcomplicating things.

Just leave the camera attached to the player, move the player to the new level, and don’t have any code to set the camera anywhere. If there’s only one Camera2D in the scene Godot will find and use it without you needing to add any code.

This gives enough information, it shows that there isn’t a Camera2D as a sibling of the Player, there is no way for this scene to run past the first frame. You can run this World2 by opening it and pressing F6, you will see the same error.

If you put a Camera2D in this scene then the script will work. It is very likely you do not want to “keep” the last camera, making a new one for this scene is preferred, it will be used automatically.

As dragonforge-dev has said you may have a better workflow if you add the Camera2D as a child of the player, you could set it to “Top Level” if you want to keep controlling it without the player’s transform interfering.

1 Like