Giter Club home page Giter Club logo

Comments (10)

timothyqiu avatar timothyqiu commented on July 3, 2024 4

This limitation is by design, see godotengine/godot-proposals#4096.

get_tree().current_scene.get_node("%UniqueNamedNode") should work.

By the way, hard-coding name/path of a node that is outside the current scene is making an assumption about the structure of that scene. It might be closer to best practice to have spawned_instance expose a set_the_important_node(node: Node) method.

from godot.

timothyqiu avatar timothyqiu commented on July 3, 2024 2

Scene unique names are scoped to the owner scene. i.e., owner's subtree.

The UniqueNameNode can only be accessed by nodes stored in scene.tscn.

Your onready variable is inside a script attached to the root node of spawned_instance.tscn, so it can only access scene unique names defined spawned_instance.tscn. And there're no nodes named UniqueNameNode there.

from godot.

JekSun97 avatar JekSun97 commented on July 3, 2024

I tested the project, I can confirm that this problem exists

from godot.

lucassene avatar lucassene commented on July 3, 2024

Scene unique names are scoped to the owner scene. i.e., owner's subtree.

The UniqueNameNode can only be accessed by nodes stored in scene.tscn.

Your onready variable is inside a script attached to the root node of spawned_instance.tscn, so it can only access scene unique names defined spawned_instance.tscn. And there're no nodes named UniqueNameNode there.

Understood. So there is no way to dynamically instantiate a script that references a node using the % unique name? I don't know how things are handled internally, but that's a kind of big limitation. I believe it would be good to make it possible.

I tried setting the owner of the SpawnedInstance node both before and after calling add_child(), and both to self (Spawner) and get_tree().get_edited_scene_root(), but %UniqueNamedNode was still null.

from godot.

huwpascoe avatar huwpascoe commented on July 3, 2024

I'd go one further @export var some_node: MyNode and then it can picked in the inspector window (but maybe that's not what you're after?)

from godot.

lucassene avatar lucassene commented on July 3, 2024

My usage is for spawning enemies instances where there are many enemies already in the scene (which would make sense to assume its structure).

Making the spawner script set_important_node(node: Node), would require that node to have reference to the unique named nodes I need, which atm, it doesn't really need to know them.

Adding an exported variable would require me to update them in the inspector for every single enemy that starts in the scene, which is not really viable.

I appreciate all your replies. I think the best approach for now it is just using an enemy manager of some sort to update the "important nodes" refs inside its _ready() method.

Maybe we can change this to a proposal to have instantiated nodes to still have access to unique named nodes? I don't know the implications of this changes, though.

from godot.

lucassene avatar lucassene commented on July 3, 2024

This limitation is by design, see godotengine/godot-proposals#4096.

get_tree().current_scene.get_node("%UniqueNamedNode") should work.

By the way, hard-coding name/path of a node that is outside the current scene is making an assumption about the structure of that scene. It might be closer to best practice to have spawned_instance expose a set_the_important_node(node: Node) method.

I tried using: get_tree().current_scene.get_node("%UniqueNamedNode")
And I was still getting null ref in the MRP.

from godot.

huwpascoe avatar huwpascoe commented on July 3, 2024

My usage is for spawning enemies instances where there are many enemies already in the scene (which would make sense to assume its structure).

If it's just letting enemies know where the player is, then assigning a group to the player will let the enemies be able to get a list of all players instances.

Otherwise yeah, "enemy manager"...

from godot.

lucassene avatar lucassene commented on July 3, 2024

My usage is for spawning enemies instances where there are many enemies already in the scene (which would make sense to assume its structure).

If it's just letting enemies know where the player is, then assigning a group to the player will let the enemies be able to get a list of all players instances.

Otherwise yeah, "enemy manager"...

It is not related to the player. More for navigation and AI. But your group idea is great, thanks for that!

With that said, I still think instantiated nodes should be able to access nodes with unique names as normal.

from godot.

bs-mwoerner avatar bs-mwoerner commented on July 3, 2024

This may be just a case of "wrong tool for the job". Scene unique nodes are intended for scenes working with their own nodes. And the name is meant quite literally, too: They are unique to their scene, not globally, so when your HUD has a unique node named "Score", the game won't break the instant you add a game over message that also has a node named "Score". They can both happily exist next to each other, each with their own unique node. You can also spawn multiple HUDs into the game and their respective unique nodes will still work as expected without them getting confused by name clashes.

As a consequence, however, if your SpawnedNode scene says "give me my unique node 'Child'" and it doesn't have a unique node "Child", then it won't simply return the unique node of a different scene (the Spawner) that happens to use the same name.

So for your use case, you're not actually looking for a "scene unique node" but rather a "node with a global name" that you can find from everywhere in your game. And that's indeed what Godot calls a "node group". They're called "groups" because here multiple nodes with the same (group) name may exist at the same time, so get_nodes_in_group() may return more than one node.

If this kind of coupling is a bit too loose for your taste, there's also the "NodePath parameter" concept mentioned above. Your inner scene can export a parameter and expect the parent scene to put a reference to an external node there when it spawns a new child (that's how an AnimationPlayer is associated with its "root" node, for instance). The idea is that you don't create a hard dependency on the inner structure of another scene but rather have that scene tell you where the node that you need access to is.

from godot.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.