I have several objects having composite pattern. Something like this:
An infantry scene:
CharacterBody3D
- ObjStatus (Node)
A tank scene:
VehicleBody3D
- ObjStatus (Node)
ObjStatus is a Node class that holds HP, various parameters, etc. All of these units use this ObjStatus.
Infantry and Tank instantiate ObjStatus in their scene. There are other unit scenes such as Ship, Jet, etc. and they all use ObjStatus as well. All of them will get the reference to their node in their ready function:
The thing is when I instantiated these infantries and tanks in the battlefield scene, I would like to modify their HP and all of their parameters right on the editor while editing the battlefield scene - imagine at the start of the mission, some infantries and vehicles already have taken damage.
Normally how to do this? While it is possible to do this in code, but given the amount of objects that could be in the battlefield scene, I would like to do this in the editor.
You could add your own export to the root node that propagates down, or check “Editable Children” in the instantiated scene.
There’s a plugin “Hoist” I haven’t tried but aims to help, it requires Editable Children to be on though so I’m unsure how much benefit that is to you.
Another thing I could think of is to create an “Object Generator” Node class which holds all the required exported variables that could be modified directly in the editor, and creates the required objects in the game with the required values instead.
I mean your Infantry would contain a @export var health that is copied into ObjStatus’s HP on ready, it allows you to change the variable in editor; but it’s not a great solution, more scripts, more links in the chain to break
Since you linked to another reply I made, I’m going to give you a slightly different answer based on what I’m reading here.
Is there a reason that ObjStatus is a node? If it is a plain Node object, I’d recommend you consider instead making it a Resource object. The reason being that you can then export it as a variable on the root node object and still edit it in the Inspector, but no longer need to rely on Editable Children (which have a few gotchas).
Instead, you can create it as a Resource:
class_name ObjectStatus extends Resource
@export var hp: int
@export var speed: int
Then create a base class for all the units to inherit from, like so:
class_name Unit extends CharacterBody3D
@export var status: ObjectStatus
Then just inherit that for all unit types, and they will have an exported variable all ready for them to use.
class_name Infantry extends Unit
class_name Tank extends Unit
EDIT:
Based on what @gertkeno said below, then I’d recommend this:
class_name Infantry extends CharacterBody3D
@export var status: ObjectStatus
class_name Tank extends CharacterBody3D
@export var status: ObjectStatus
You pretty much could make a “root” class that features all the nescesary vars and then create inner classes with especific roles (like enemy, player, NPC etc.).
For exemple
class_name root_class
extends # whatever, could be a CharacterBody2D
# wanted variables
then
class_name enemy
extends root_class
# rest
or maybe as a resource, just like the other guy said.
Right now, the functions for taking damage and receiving status are defined in the ObjStatus and it also send self as a reference so the status node could add status to it. It’s the way I designed the architecture.
I have been experimenting with Resource right now, and since ObjStatus has became Resource entirely, I cannot send in self or use get_parent anymore. This means I will have to re-design a bit.
I see that down the road, using Resource will be the way to go in the long run.
For Editable Children, it works by storing per-instance overrides of a scene’s child nodes—but that convenience comes at a cost. The biggest issue is that these overrides don’t stay in sync with the original scene, so if the base scene changes later, instances can become inconsistent, throw errors, or require manual reconfiguration. This effectively breaks the idea of a single source of truth and makes large projects harder to maintain.
It also introduces fragility and confusion: structural changes (like renaming or moving nodes) can break edited instances, and some properties or behaviors may not work reliably or behave differently across instances or exports. Overall, while useful for quick tweaks, Editable Children tends to scale poorly because it creates hidden differences between instances and increases maintenance overhead.