Signaalit¶
Johdanto¶
Signaalit ovat Godotin versio tarkkailija-mallista. Ne antavat solmun lähettää viestejä, joita muut solmut voivat kuunnella ja joihin ne voivat vastata. Esimerkiksi sen sijaan, että tarkistaisi jatkuvasti onko painiketta painettu, painike voi lähettää signaalin kun sitä on painettu.
Muista
You can read more about the observer pattern here: https://gameprogrammingpatterns.com/observer.html
Signaalien avulla pelin objektit voidaan erottaa toisistaan, mikä johtaa paremmin järjestettyyn ja hallittavampaan koodiin. Sen sijaan, että objektien on pakko olettaa, että muut objektit ovat aina läsnä, ne voivat lähettää signaaleja, joita kaikki kiinnostuneet objektit voivat kirjautua kuuntelemaan ja vastaamaan.
Alla muutamia esimerkkejä siitä, miten voit käyttää signaaleja omissa projekteissasi.
Ajastin-esimerkki¶
To see how signals work, let's try using a Timer node. Create a new scene with a Node2D and two children: a Timer and a Sprite. In the Scene dock, rename Node2D to TimerExample.
Spriten tekstuurille voit käyttää Godotin ikonia, tai mitä tahansa muuta kuvatiedostoa. Tee niin valitsemalla Load
spriten tekstuuri attribuutin pudotusvalikosta. Lisää skripti root solmuun, mutta älä lisää siihen vielä mitään koodia.
Skenepuusi pitäisi näyttää tältä:

Avaa Timer-solmun ominaisuudet ja napsauta Autostart-tekstin viereistä valintaruutua. Tämä käynnistää ajastimen automaattisesti, kun skene ajetaan. Wait Time-ominaisuus voi pysyä 1 sekunnissa.
Napsauta ”Inspector”-välilehden vieressä olevaa välilehteä ”Node”. Tältä välilehdeltä löytyvät kaikki signaalit, joita valittu solmu voi lähettää. Timer-solmun tapauksessa meitä kiinnostaa ”timeout”. Tämä signaali lähetetään, kun ajastin osoittaa 0
.

Click on the "timeout()" signal and click "Connect..." at the bottom of the signals panel. You'll see the following window, where you can define how you want to connect the signal:

On the left side, you'll see the nodes in your scene and can select the node that you want to "listen" for the signal. Note that the Timer node is blue, this is a visual indication that it's the node that is emitting the signal. Select the root node.
Varoitus
Kohdesolmuun täytyy olla liitettynä skripti, muutoin saat virheilmoituksen.
If you toggle the Advanced menu, you'll see on the right side that you can bind an arbitrary number of arguments of (possibly) different types. This can be useful when you have more than one signal connected to the same method, as each signal propagation will result in different values for those extra call arguments.
Ikkunan alalaidassa on kenttä nimeltä "Vastaanottava metodi". Tämä on kohdesolmun skriptissä sen funktion nimi, jota haluat käyttää. Godot'n oletusarvoinen nimeämiskäytäntö tätä funktiota luodessa on _on_<solmun_nimi>_<signaalin_nimi>
, mutta voit halutessasi muuttaa nimen.
Napsauta "Connect"-painiketta ja voit nähdä, että skriptiin on luotu funktio:
extends Node2D
func _on_Timer_timeout():
pass # Replace with function body.
public class TimerExample : Node2D
{
public void _on_Timer_timeout()
{
// Replace with function body.
}
}
Nyt oletuskoodi voidaan korvata millä tahansa koodilla, jonka haluamme signaalia vastaanottaessa suorittaa. Laitetaan kuvake välkkymään:
extends Node2D
func _on_Timer_timeout():
# Note: the `$` operator is a shorthand for `get_node()`,
# so `$Sprite` is equivalent to `get_node("Sprite")`.
$Sprite.visible = !$Sprite.visible
public class TimerExample : Node2D
{
public void _on_Timer_timeout()
{
var sprite = GetNode<Sprite>("Sprite");
sprite.Visible = !sprite.Visible;
}
}
Aja skene ja näet, että kuvake välkkyy sekunnin välein. Ajoitusta voi muuttaa Timer-solmun Wait Time-ominaisuudella.
Signaalien yhdistäminen koodin kautta¶
Signaaleja voi yhdistää koodilla editorin sijaan. Tämä on usein tarpeen, kun solmuille luodaan ilmentymiä koodin kautta, eikä yhteyksiä voida luoda editorin avulla.
Irrota ensin signaali valitsemalla yhteys Timer-solmun "Node"-välilehdessä ja napsauttamalla "Disconnect"-painiketta.

Yhteyden muodostaminen koodilla onnistuu connect
-funktion avulla. Laitetaan se _ready()
-funktioon, jotta yhteys muodostetaan ajon aikana. Funktion syntaksi on muodossa <lähdesolmu>.connect(<signaalin_nimi>, <kohdesolmu>, <kohdefunktion_nimi>)
. Timer-solmun yhteyden koodi näyttää tältä:
extends Node2D
func _ready():
$Timer.connect("timeout", self, "_on_Timer_timeout")
func _on_Timer_timeout():
$Sprite.visible = !$Sprite.visible
public class TimerExample : Node2D
{
public override void _Ready()
{
GetNode("Timer").Connect("timeout", this, nameof(_on_Timer_timeout));
}
public void _on_Timer_timeout()
{
var sprite = GetNode<Sprite>("Sprite");
sprite.Visible = !sprite.Visible;
}
}
Mukautetut signaalit¶
Voit määritellä myös omia mukautettuja signaaleja Godotissa:
extends Node2D
signal my_signal
public class Main : Node2D
{
[Signal]
public delegate void MySignal();
}
Kun mukautetut signaalit on määritelty, ilmestyvät ne myös Inspector-välilehteen ja niitä voidaan yhdistää solmun sisäänrakennettujen signaalien tavoin.
Signaalin lähettämiseksi koodin kautta, käytä emit
-funktiota:
extends Node2D
signal my_signal
func _ready():
emit_signal("my_signal")
public class Main : Node2D
{
[Signal]
public delegate void MySignal();
public override void _Ready()
{
EmitSignal(nameof(MySignal));
}
}
A signal can also optionally declare one or more arguments. Specify the argument names between parentheses:
extends Node
signal my_signal(value, other_value)
public class Main : Node
{
[Signal]
public delegate void MySignal(bool value, int other_value);
}
Muista
The signal arguments show up in the editor's node dock, and Godot can use them to generate callback functions for you. However, you can still emit any number of arguments when you emit signals. So it's up to you to emit the correct values.
To pass values, add them as the second argument to the emit_signal
function:
extends Node
signal my_signal(value, other_value)
func _ready():
emit_signal("my_signal", true, 42)
public class Main : Node
{
[Signal]
public delegate void MySignal(bool value, int other_value);
public override void _Ready()
{
EmitSignal(nameof(MySignal), true, 42);
}
}
Lopputulos¶
Monista Godotin valmiista solmutyypeistä löytyy signaaleja tapahtumien havaitsemiseen. Esimerkiksi kolikkoa ilmentävä Area2D-solmu lähettää ``body_entered`-signaalin kun pelihahmon fysiikkakappale siirtyy sen törmäysmuodon sisään. Tämän avulla saadaan selville milloin pelaaja on kerännyt kolikon.
Seuraavassa osiossa, Ensimmäinen pelisi, rakennamme kokonaisen pelin, jossa signaaleja käytetään monin eri tavoin yhdistämään pelin eri komponentteja.