How to modify child node from another scene

Godot 4.3stable
So, this is my current scene:
Main

  • Player
    I also have a Player scene (separate), containing a Camera3D.

My problem is that i can’t access the camera from my Main script, and if I try to with @onready var camera_3d: Camera3D = $Camera3D, it just says that camera_3d is nil.
Can anyone help please?

Try this? $Player/Camera3D to access the camera, as it is inside the player.

Yes, I also tried that but the problem persisted.
To be honest I think the problem was somewhere else, since I then changed that and it started working fine.
Basically I was using a connect in the _ready() of another script, and after commenting it, somehow this script started working again.
Now my problem is that the signals connecting different scripts (also different scenes) don’t work :D.
Could you help me with that?

extends Node3D

#Signals
signal sphere_destroyed
var player_node = preload("res://player.tscn")

#func _ready():
	#$destroy_sphere.pressed.connect(_on_destroy_sphere())

func _on_destroy_sphere():
	print("on destroy sphere")
	queue_free()
	sphere_destroyed.emit()
	print("sphere_destroyed emitted")

This is the script I was referring to (and the commented part). I don’t understand why it doesn’t work with my Main script:

extends Node

#Nodes

@onready var player: Node3D = $Player
@onready var camera_3d: Camera3D = $Player/Camera3D
@onready var sphere: Node3D = $Sphere
var sphere_scene = preload("res://sphere.tscn")

#Signals

signal destroy_sphere

#Global Constants and Variables

const distance = 10.0

# Camera Foreward Vector
func _ready():
	sphere.queue_free()
	randomize()
	spawn_sphere()

func _input(event):
	
	if event is InputEventKey and event.keycode == KEY_ESCAPE:
		Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
		get_tree().quit()
	
	if event.is_action_pressed("shoot") and camera_collision():
		destroy_sphere.emit()
		print("destroy_sphere emitted")
		#arrives here but doesn't connect to actual function in sphere

func spawn_sphere():
	#Add new_sphere to scene to manipulate it
	var new_sphere = sphere_scene.instantiate()
	add_child(new_sphere)
	
	var screen_size = get_viewport().get_visible_rect().size
	
	#Generate causal point on screen
	var random_screen_pos = Vector2(
		randf() * screen_size.x,
		randf() * screen_size.y
	)
	
	#Project camera vector through this casual point
	var from = camera_3d.project_ray_origin(random_screen_pos)
	var direction = camera_3d.project_ray_normal(random_screen_pos)
	var to = from + direction * distance
	
	new_sphere.global_transform.origin = to
	
	#new_sphere.connect("sphere_destroyed", _on_sphere_destroyed)

func _on_sphere_destroyed():
	camera_3d.rotation_degrees = Vector3.ZERO
	camera_3d.rotation_x = 0.0
	camera_3d.rotation_y = 0.0
	
	spawn_sphere()
	
func camera_collision():
	var camera = get_viewport().get_camera_3d()
	var viewport = get_viewport().get_size()
	
	var ray_origin = camera.project_ray_origin(viewport/2)
	var ray_end = ray_origin + camera.project_ray_normal((viewport/2)) * distance
	
	var new_intersection = PhysicsRayQueryParameters3D.create(ray_origin, ray_end)
	var intersection = player.get_world_3d().direct_space_state.intersect_ray(new_intersection)
	
	return not intersection.is_empty()

I also inserted the Sphere scene in my Main, like with Player.
Sorry to bother you after that quick of a response c:

1 Like