Get_world_3d() results in an error due to null value

Godot Version

4.3 Stable Steam

Question

Hi All

Same issue as HERE but I don’t understand the ‘solution’ or what I’m doing wrong in my code. So therefor I ask the question again (as I cannot reply to the existing topic)

The goal that I’m trying to perform:
I’m trying to get the position from my 3D scene were I click the left mouse button.

The long story
Within the project I have a singleton ‘Global’ which has multiple variables and functions, and were I’m trying to add the functionality for the ray casting. The ray casting is (at this moment) a separate script which I call with the following code:

extends Node

var RayCasting  : Node

func _ready():
	RayCasting = load("res://Content/Global/raycasting.gd").new()

The code from raycasting.gd looks like this:

extends Node3D

const CFG_RAY_LENGTH := 1000

func getCastInformation(CollisionMask: int = 0xFFFF_FFFF) -> Dictionary:
# Prepare environment information
	if get_world_3d() == null:
		return {}
	var SpaceState = get_world_3d().direct_space_state
	var Camera = get_viewport().get_camera_3d()
	var MousePos = get_viewport().get_mouse_position()
	
# Prepare ray positions
	var RayStartPos = Camera.project_ray_RayStartPos(MousePos)
	var RayEndPos = RayStartPos + Camera.project_ray_normal(MousePos) * CFG_RAY_LENGTH
	
# Prepare query parameters
	var Query = PhysicsRayQueryParameters3D.create(RayStartPos, RayEndPos)
	Query.collide_with_areas = true
	Query.collision_mask = CollisionMask
	
# Execute ray casting
	var result = SpaceState.intersect_ray(Query)
	return result

I call these scripts in my test scene which has its own script with following code:

extends Node3D
var StartPos : Vector3

func _unhandled_input(_event: InputEvent) -> void:
	if Input.is_action_just_pressed("mouse_btn_left"):
		var test = Global.RayCasting.getCastInformation()

I’m running the scene with F6 (current scene). Which results in the error.

I already figured out that the error is due to a null reference. But I’m lost how and what to check. What is the World3D? I looked in the official docu, but I do not know what they are referring to. I added a WorldEnvironment to my test scene, but that didn’t do the trick. Also it’s not the root, and ChatGPT could also not help me further :sweat_smile:

So I need some beginners course what the World3D is, and/or what additional parameters I should assign to the get_world_3d() method.

Many thanks already for any help/suggestions :grinning:
Regards,

Ludo

PS I have reduced the code to only the relevant parts for my issue

Your raycasting node is not added to the scene tree, so it cannot access the scene’s world3D. Could you add this raycasting.gd to your globals?

Hi Gertkeno

The ‘RayCasting’ is the instance of ‘raycasting.gd’ that I create/add within the ‘Global’ node. In the tree the ‘Global’ node is present, so I would guess (from my C++/CoDeSys experience), that the code is running. If I call ‘Global.RayCasting.’ than the editor can find the info. Or does the ray casting need to be it’s own node (Node3D)??

Regards

Ludo

If you do not use add_child(RayCasting) then you only have a reference to RayCasting, but it is not part of the world/tree.

2 Likes

As mentioned by @gertkeno there must be a node added within the tree. So in my singleton ‘Global’ I have updated the code to:

etends Node

var RayCasting  : Node

func _ready():
	RayCasting = load("res://Content/Global/raycasting.gd").new()
	RayCasting.name = "RayCasting"   #Name displayed in tree
	add_child(RayCasting)

The node is now added to the tree as a child from my node ‘Global’.

Then the function World3D works like a charm.
Thanks @gertkeno for your quick anwser :smiley:

Regards

Ludo

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.