Can I connect a signal to an exported variables?

Godot Version

4.3

Question

In short, I want to connect different signals using exported variables.
For example if I have this setup:
Spell
├ProjectileComponent
├DamageComponent
└CollisionComponent
I’d like for the collision component, to have a signal for example “hit entity” and to give that to the damage component.
Or if I could replace the DamageComponent with a EffectComponent, which would instead of dealing damage, would give a status effect.

Another example could be instead of a collision component, it would be a timer component with an additional explosive component.
Timer could be connect to Explosive and Explosive to Damage. So it would work like a grenade of sorts.

Maybe you could chain these components with await inside of a overriden function. As an example if each spell overrides a apply_effect function with it’s own signal awaiting.

# timer component
func apply_effect() -> void:
    await get_tree().create_timer(2.0).timeout

# collision component
func apply_effect() -> void:
    var hit = await area.body_entered
    get_parent().target = hit

# damage component
func apply_effect() -> void:
    if get_parent().target:
        get_parent().target.take_damage(10)

Then you could loop through these component awaiting each apply_effect

for child in get_children():
    await child.apply_effect()

So basically create my own callbacks instead of using built in signals?

You would still be using signals, probably the same signals you need to use anyways; instead of emitting more signals you are handling the interactions within the functions. No connecting needed, though you would have to order your components based on how they interact with each other in sequence.

Would it be possible to somehow use exported variables to call specific functions? For example having an exported variable of “timer callback” and the timer component using that for it’s callbacks? Maybe an exported list of those components that need to get the timer callback?

You can use strings.

@export var call_this: String

func _ready() -> void:
    call(call_this)
    timer.connect("timeout", Callable(self, call_this))

I seem to have a bit of a problem implementing this, could you explain a bit more in depth?
I’m trying to implementing using a Timer, but I am getting this error:
image

Got it working.

So I should rather approach this as two lists, one for each component or one list and each component should have a callback function that is being called?

It’s tough for me to imagine, I feel like you also need node references in the mix so two lists (or one list of resources with node + function name) is surely required?

Oh! I completely forgot about resources, I could definitely create a custom resource of a “spell caller” which would hold the component, function name and variables to send to that component.

1 Like

Actually, I think I can manage to just have a callback function in each component, since mostly components are split into two groups (with a few special cases). Effect and Condition.
For example, timer component and explosive component. Timer is the condition and explosive is the effect, since once the condition of the timer running out is met, it calls the explosive.
And if I want some extra information, for example area component (used for AOE stuff), I could just have that extra string which would say which function to call, like “expand” or “enable”. and have the specified size for the expand function already sit in the area component