scene_unique_nodes.rst 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. .. _doc_scene_unique_nodes:
  2. Scene Unique Nodes
  3. ==================
  4. Introduction
  5. ------------
  6. Using ``get_node()`` to reference nodes from a script can sometimes be fragile.
  7. If you move a button in a UI scene from one panel to another, the button's node
  8. path changes, and if a script uses ``get_node()`` with a hard-coded node path,
  9. the script will not be able to find the button anymore.
  10. In situations like this, the node can be turned into a scene
  11. unique node to avoid having to update the script every time
  12. the node's path is changed.
  13. Creation and usage
  14. ------------------
  15. In the Scene tree dock, right-click on a node and select
  16. **Access as Unique Name** in the context menu.
  17. .. image:: img/unique_name.webp
  18. After selecting the option, the node will now have a percent symbol (**%**) next
  19. to its name in the scene tree:
  20. .. image:: img/percent.webp
  21. You can now use the node in your script. For example, you can reference it with
  22. a ``get_node()`` method call by typing the % symbol, followed by the node's
  23. name:
  24. .. tabs::
  25. .. code-tab:: gdscript GDScript
  26. get_node("%RedButton").text = "Hello"
  27. %RedButton.text = "Hello" # Shorter syntax
  28. .. code-tab:: csharp
  29. GetNode<Button>("%RedButton").Text = "Hello";
  30. Same-scene limitation
  31. ---------------------
  32. A scene unique node can only be retrieved by a node inside the same scene. To
  33. demonstrate this limitation, consider this example **Player** scene that
  34. instances a **Sword** scene:
  35. .. image:: img/unique_name_scene_instance_example.webp
  36. Here are the results of ``get_node()`` calls inside the **Player** script:
  37. - ``get_node("%Eyes")`` returns the **Eyes** node.
  38. - ``get_node("%Hilt")`` returns ``null``.
  39. These are the results of ``get_node()`` calls inside the **Sword** script:
  40. - ``get_node("%Eyes")`` returns ``null``.
  41. - ``get_node("%Hilt")`` returns the **Hilt** node.
  42. If a script has access to a node in another scene, it can call ``get_node()`` on
  43. that node to get scene unique nodes from that node's scene. This also works in a
  44. node path, which avoids multiple ``get_node()`` calls. Here are two ways to get
  45. the **Hilt** node from the **Player** script using scene unique nodes:
  46. - ``get_node("Hand/Sword").get_node("%Hilt")`` returns the **Hilt** node.
  47. - ``get_node("Hand/Sword/%Hilt")`` also returns the **Hilt** node.
  48. Scene unique names don't only work at the end of a node path. They can be used
  49. in the middle to navigate from one node to another. For example, the **Sword** node
  50. is marked as a scene unique node in the **Player** scene, so this is possible:
  51. - ``get_node("%Sword/%Hilt")`` returns the **Hilt** node.
  52. Alternatives
  53. ------------
  54. Scene unique nodes are a useful tool to navigate a scene. However, there are
  55. some situations where other techniques may be better.
  56. A :ref:`Group <doc_groups>` allows locating a node (or a group of many nodes)
  57. from any other node, no matter what scene the two nodes are located in.
  58. A :ref:`Singleton (Autoload) <doc_singletons_autoload>` is an always loaded node
  59. that can be accessed directly by any node regardless of the scene. These are useful
  60. when some data or functionality is shared globally.
  61. :ref:`Node.find_child() <class_Node_method_find_child>` finds a node by name
  62. without knowing its full path. This seems similar to a scene unique node, but
  63. this method is able to find nodes in nested scenes, and doesn't require marking
  64. the node in the scene editor in any way. However, this method is slow. Scene
  65. unique nodes are cached by Godot and are fast to retrieve, but each time the
  66. method is called, ``find_child()`` needs to check every descendant (every child,
  67. grandchild, and so on).