Just my (rather long) two cents:
In godot you can already use entity-component-like composition, by including child nodes, that extend some script (still only one), and use get_parent()
to update their parent's values, and get_node("../<name>")
to access sibling components.
Sample:
#player.tscn
Player - Node2D (no script)
Component_A - Node (extends "component_a.gd")
Component_B - Node (extends "component_b.gd")
Sprite - Sprite (no script)
Sword - Node2D (instance of "res://player/player_sword.tscn")
This usage has a few bad things about it, though:
- You have to prefix everything with
get_parent()
, or some variable.
- If you
export
some variables, you can edit them in the parent scene only after using the "Show children" option.
- You can work around this one by adding a script on the parent node where you only
export
variables, and define mappings, but it's a bit of hassle
- Another workaround would be to make a reusable entity script that exports an
Array
, and have children components access values like get_parent().values[index_swing_distance]
, where index_swing_distance
is exported on the component.
Also, if you were to go with this method, here is a tip:
- If you want to get another component, you can use
export(NodePath) var other_component_path
, and then get_node(other_component_path)
. This would allow for more separation, and multiple components of the same type inside the same entity (esp. useful for Sprite
s and the like). If you want to give a default, you can also use literal NodePath declaration, like export(NodePath) var other_component_path = @"../other_component"
(or, simply NodePath("../other_component")
).