One of the more useful features of Unity, that I’ve been missing since I stopped using that mess of a thing (not due to the latest upset; they burned me away before that), was its support of Smalltalk/Objective-C style message passing (Send/BroadcastMessage
). Godot’s signals are a perfectly good way to decouple code within the same node subgraph, letting you “pull” messages from a known node, which is great for most of the times one would use message passing in Unity — and I’d bet more performant to boot. What it’s less great for is “pushing” messages to nodes unknown at scripting time.
For example, consider a scene having a child node that’s responsible for handling an actor’s health. It may have a signal which is emitted when the actor dies, and a function for applying damage. Now let’s also consider an exploding barrel, which needs to find anything that can take damage within its blast range (an Area2D, for the sake of example) and apply a set amount of damage. Signals do not work well for this, because it doesn’t make sense to inject and remove a subscription to an exploded
signal as a separate step.
It also doesn’t work very well to call damage
on whatever’s returned by get_overlapping_bodies
, since then you have to introduce scripting to every child of CollisionBody2D to either track health there, or forward it to whatever’s managing health. It’s also not great to look for a HealthComponent directly underneath the body, since that may not be where the designer put it. It probably does not make sense to make a health node the child of a body, unless that is the root of the actor (if it is, that strikes me as a bad idea). A better way, it seems to me, to handle this sort of case would be to send a message like we did in Unity.
Godot’s documentation, and stuff like the forums, doesn’t really talk about it much, but there is actually a way to do this pattern, built into Godot. Enter: Node.propogate_call
!
This function recursively calls a specified function (if it exists) in all of its children (and optionally the node itself). This is even a bit more powerful than I remember the SendMessage
being in Unity, since it walks down the tree from the specified node. Pair this with the root node in the scene tree and you’ve got a replacement for BroadcastMessage.