Emit signal only when variable is changed inside of the class

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By websterek

Hi, I’m looking fo a way to signal bunch of objcts (like elevators) to tern on when some specific button will be pressed. But when it’s activated signal is constantly emiting, is there any way to send this signal only when variable is changed?

Something like oneshoot when node is connecting but I need to recive this signal whenever it’s changed.

I have found some method using set/get but in my situation everything needs to be inside of the class, my variables are changing internally.

Best!

:bust_in_silhouette: Reply From: wyattb

Maybe your class should emit the signal when a variable has changed. And yes setters would be the right place for that.

:bust_in_silhouette: Reply From: MysteryGM

The Godot emit_signal() only fires once per call. So the idea will be to design your code so that it only fires when the variable is updated.

This design fires a signal called OnlyOnce when 4 seconds has passed

extends Control

    #+/- seconds
    var CustomTimer = 4
    
    signal OnlyOnce
    
    func _process(delta):
    	#make the code for the timer
    	if CustomTimer > 0:
    		CustomTimer -= delta
    	else:
    		#Now we fire the signal only once
    		emit_signal("OnlyOnce")
    		#ResetTimer
    		CustomTimer = 4

The other receiving object will have a link to the signal that looks like this:

extends Label

var SignalCounter = 0

func _on_Control_OnlyOnce():
	SignalCounter += 1
	self.text = str(SignalCounter)

This text will now update every 4 seconds.

We could also have avoided signals:

extends Label

var FireCounter = 0

func UpdateText():
	FireCounter += 1
	self.text = str(FireCounter)

This is very similar to the signal, it is a function that any object can call.

Then in the controller we call this function directly:

extends Control

    #+/- seconds
    var CustomTimer = 4
    
    func _process(delta):
    	#make the code for the timer
    	if CustomTimer > 0:
    		CustomTimer -= delta
    	else:
    		#Instead of a signal we call the function in the other object
    		$Label.UpdateText()
    		#ResetTimer
    		CustomTimer = 4