godotengine / godotengine/godot
SceneState's get_node_groups does not return groups for scenes that have their own PackedScenes
- Dominant language
- C++
- Stars
- 117k
- Forks
- 26.8k
- PR merge metrics
- PR metrics pending
Description
### Tested versions
Godot 4.6.1
### System information
Godot v4.6.1.stable - Windows 10 (build 19045) - Multi-window, 1 monitor - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 3050 (NVIDIA; 32.0.15.7602) - 12th Gen Intel(R) Core(TM) i5-12400F (12 threads) - 15.83 GiB memory
### Issue description
It turns out that if a node in your PackedScene is a PackedScene instance itself, or `state.get_node_instance(idx)` is not null, if you run get_node_groups() on that idx it will report not belonging to any groups.
However, if you instead obtain the *instance* of that node, then you run get_node_groups(0) on its root node, it will correctly report the groups it belonogs to.
Here is working code I ran on a packed scene to reproduce the issue:
```py
extends Node
@export var packed_scene: PackedScene
func _ready() -> void:
var valid_keys: PackedStringArray = []
var state = packed_scene.get_state()
for idx in state.get_node_count():
var state_name = state.get_node_name(idx)
print(state_name)
var groups = state.get_node_groups(idx)
print(groups)
if "pickable" in groups:
valid_keys.append(state.get_node_name(idx))
var instance = state.get_node_instance(idx)
if instance:
var instance_state = instance.get_state()
var groups_b = instance_state.get_node_groups(0)
if "pickable" in groups_b:
valid_keys.append(state.get_node_name(idx))
print(valid_keys)
```
```
output:
Node3D
[]
SpotManager
[]
Camera3D
[]
body_a
[]
body_b
[]
SpotLight3D
[]
["body_a", "body_b"]
```
### Steps to reproduce
1. Create a scene and set its node group to something like "pickable"
2. Create another scene ("investigation") and add the previous pickable scene into its node tree
3. Create a new scene and add a script to it w/ @export var packed_scene: PackedScene
4. Set the packed_scene to the "investigation" scene you created previously
5. Run code in _ready():
```py
var state = packed_scene.get_state()
for idx in state.get_node_count():
var state_name = state.get_node_name(idx)
print(state_name)
var groups = state.get_node_groups(idx)
print(groups)
```
All groups will be blank, despite not being true.
6. Add additional code to check if the node is an instance itself:
```py
var instance = state.get_node_instance(idx)
if instance:
var instance_state = instance.get_state()
var groups_b = instance_state.get_node_groups(0)
print(groups_b)
```
7. This time, the correct groups should be displayed on the root node!
### Minimal reproduction project (MRP)
[SceneTreeNodeGroupMRP.zip](https://github.com/user-attachments/files/25426119/SceneTreeNodeGroupMRP.zip)
Running the project you should get this output:
```
Investigation has groups: []
Pickable has groups: []
Pickable2 has groups: []
Pickable3 has groups: []
ManualPickable has groups: ["pickable"]
Icon has groups: []
Found nodes in group 'pickable': ["ManualPickable"]
Pickable is an instanced node and has groups: ["pickable"]
Pickable2 is an instanced node and has groups: ["pickable"]
Pickable3 is an instanced node and has groups: ["pickable"]
Found instanced nodes in group 'pickable': ["ManualPickable", "Pickable", "Pickable2", "Pickable3"]
```
Contributor guide
Research direction
Run the linked minimal reproduction project and inspect the PackedScene.get_state(), get_node_groups(), and get_node_instance() entry points described in the report. Compare group results for direct nodes and nested PackedScene instances; done means get_node_groups() reports the groups belonging to nested scene nodes consistently with the instance state.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- game-dev
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100