Search code examples
godotgdscriptgodot4

Node3D Global_transform retunring nil


I have the following code for a Runway to launch fighters in my game.

extends Node3D
class_name Runway

@onready var end_node: Node3D = $End

var moving: bool = false

func set_moving(new_value: bool):
    moving = new_value

func get_end() -> Vector3:
    end_node.global_transform.origin

func get_start() -> Vector3:
    get_global_transform().origin

func is_free_to_land():
    true

How can I make the Node3D return it's global position? It has one but sometimes I get nil which is wird and not documented.


Solution

  • No, the global_transform of a Node3D cannot be nil.

    You didn't post the error you got, but I suspect the error is that in this line:

    end_node.global_transform.origin
    

    Either end_node is null, or it is an invalid reference. Those aren't the same case...


    For the first case (null), it means that this failed:

    @onready var end_node: Node3D = $End
    

    Which should have also given you an error. Which would stem from the node not actually being placed there.

    Advice on this case would be to either use a unique name for the node, so you can use use % syntax with it. Or export a Node variable that you can set from the inspector.


    For the second case (invalid reference), end_node was freed by other means beyond the script we are looking at.

    If this is what you are facing then then you need to check:

    if is_instace_valid(end_node)
        pass
    

    If this is happening during a scene transition it is probably OK. However, if it is not, it might require further investigation into why it is happening.

    Try searching for queue_free in your code base. Barring that, consider connecting to the tree_exiting signal and checking is_queued_for_deletion. If that does not get it, be suspicious of remove_child + free combos. As last resort attach a script and check for NOTIFICATION_PREDELETE in _notification.


    I would also expect get_end and get_start to be reporting errors because they do not return. No, in GDScript the last statement does not automatically return, not even if it is the only statement.

    A little less evident, this is just a couple warnings (which might or might not be disabled in your settings):

    func is_free_to_land():
        true
    

    This does not return, but it does not state that it returns, so that is not an error. And also, true as an statement does nothing, which is not an error either.


    And you probably can make set_moving into a setter.