How can we make a node/node_path globally acessable?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By The_Black_Chess_King

How can we make a node globally acessable to other nodes in stabilished trees?

Say I have a camera inside my player node, and I have a fog texture in a canvas node, which it’s shader will use the camera position to offset the UV. How do I make the camera globally acessable? I am familiar with autoloads, but I can’t get it to work properly, my intention is to make a standard structure of nodes for my game maps, like:

MAP_001_The_Gargatua:
    DYNAMIC:
        LIGHTS
        OBJECTS
        ENTITIES:
            ENEMY_001
            PLAYER
                MAIN_ACTIVE_CAMERA
        MOVEABLES
        ITEMS
    STATIC:
        TILESETS
    POST_PROCESS_CANVAS:
        FOG
        VEINS_FX
        BLOOD_FX

Then some objects could store their reference in a global node, then they could be called from any other node in the map. My current situation is the FOG texture shader trying to access the camera inside the player. I would do currently a lot of get_parent() or get_tree().

My project is getting bigger, and so far have been doing direct referencing like get_node() or $ pathing, which I know, isn’t the best approach, my get_parent() get_tree() get_node() codes are looking like a noodle soup, no pun intended, it’s all over the place.

Sometimes I can bypass this using the dinamic design approach, wherer B doesn’t need to know A to do X. I do this using classes and pre-determined common variables like OBJECT_TYPE:Door, or using the collision layers, or using other methods like filtering by NODE type, but sometimes we need to reference a specific object like the Player.

So how can I store the path of a node or the node itself in a global access point? Or my approach with this situation is wrong?

:bust_in_silhouette: Reply From: imjp94

Firstly, to get the main camera of the scene you can simply access it from Viewport.get_camera(), while main viewport can also be accessed with Node.get_viewport():

var main_camera = get_viewport().get_camera()

For accessing other node globally, it is recommended to use group:

# Retrieve all nodes under "player" group
var players = get_tree().get_nodes_in_group("player")

Oops, didn’t metioned it was a 2D camera, my bad, but sadly, the get_viewport() line retrieves only the 3D camera as it is currently. Somebody opened a discussion about that somewhere…

The_Black_Chess_King | 2020-03-26 17:36

It’s ok, at least I learn something new, didn’t know that before

imjp94 | 2020-03-26 19:40

:bust_in_silhouette: Reply From: 1234ab

What I do is “registering” it to a global script.
IDK if it’s good advice.
With an autoloaded global script I can:
var player
And in the player script’s _ready:
global.player = self
and after that everyone can access player with global.player
Only thing is that you better not access it from _ready, because it may not be there in time. You can use call_deferred().
Grouping is the way to go for enemies (there is more than one enemy) and it may be better for other nodes too.