3. Weapon Setup met Signals
Maak een weapon scene en leer signals gebruiken voor communicatie
Overzicht
In dit hoofdstuk maak je een Railgun weapon met zijn eigen script. Je leert hoe je weapon logic scheidt van player logic en signals gebruikt voor communicatie tussen nodes.
Input actions

Voor dit hoofdstuk heb je een extra Input Action nodig: shoot, dat zal worden gebruikt om het weapon af te vuren.
Project > Project Settings
Tab Input Map
In het veld "Add New Action", type: shoot
Click Add
Click het + icon naast "shoot"
Mouse Button > Left Button
Click OK
Close Project Settings
Railgun scene maken

Om te beginnen heb je een weapon scene nodig. Daarvoor gebruiken we het blaster model uit de assets.
Ga in de menu naar Scene > New Scene
Selecteer Node3D als root node
Klik Create
Hernoem de root node naar Railgun
Sleep het models/blaster.glb model vanuit het FileSystem panel naar de Railgun node in de Scene hierarchy
Het model wordt als child toegevoegd
Sla de scene op als res://objects/Railgun.tscn
Railgun script

Om te kunnen schieten, heb je 2 dingen nodig:
de player die een signaal uitstuurt dat ze willen schieten
het weapon dat reageert op dat signaal, door een functie uit te voeren
Dat wilt dus zeggen dat je Railgun een script nodig heeft, met een functie die kan schieten.
Selecteer de Railgun root node
Klik op Attach Script (het 📜 icoontje met een +, bovenaan het Scene Hierarchy venster)
Language: C#
Class Name: Railgun
Path: res://scripts/Railgun.cs
Klik Create
Railgun onshoot method
Player shoot signal
Open het
PlayerControllerscriptVoeg een nieuw Signal toe aan het script met het
[Signal]attribute. De naam van een Godot Signal moet eindigen metEventHandleren gebruikt een C# delegate.
Voer het signaal uit in de
_Processmethod wanneer de speler klikt met de muis. GebruikInput.IsActionJustPressedom te checken of de shoot actie net werd ingedrukt, enEmitSignalom het signaal uit te sturen. Merk daarbij op dat de naam van het signaal gewoonShootis, dus zonder hetEventHandlerdeel.
Shoot signal verbinden met onshoot method

Je hebt een Player die een Shoot signal uitstuurt wanneer de speler klikt, en een Railgun met een OnShoot() method. Verbind deze twee met elkaar!
In Godot doe je dit via het Node panel in de editor. Hier ga je de twee "elektrisch bedraden" - de Player zendt een signaal uit, en de Railgun luistert ernaar. Wanneer het signaal wordt uitgezonden, wordt automatisch de OnShoot() method aangeroepen.
Open de main scene
Voeg de Railgun scene toe aan de root van de main scene (sleep Railgun.tscn naar de scene hierarchy)
Selecteer de Player node in de hierarchy
Aan de rechterkant van de Editor, naast de Inspector tab, vind je het Node venster (klik erop als het niet zichtbaar is) Met de Player geselecteerd, zie je in het Node venster alle signals die de Player kan uitzenden
Dubbelklik op het Shoot signal
In het venster "Connect a Signal to a Method" selecteer je de Railgun node (dit is de ontvanger)
Bij Receiver Method klik op Pick
Selecteer de OnShoot method uit de lijst
Klik op Connect. In de Scene Hierarchy zie je nu een signaal-icoontje
naast de Player node. Dit geeft aan dat deze node een signal heeft geconnect. Als je erop klikt, zie je naar welke method het signaal verbonden is.Test het spel met F6. Wanneer je klikt met de muis, verschijnt in de Output tab onderaan de boodschap
"Railgun fired!"
Fire rate limiting

Momenteel kan de speler oneindig snel schieten door snel te klikken. Dit maakt het wapen overpowered en het voelt niet geloofwaardig aan. Implementeer een fire rate - een cooldown tijd tussen shots. Gebruik hiervoor een Timer node om de cooldown bij te houden.
Open de Railgun.tscn scene
Selecteer de Railgun root node
Voeg een Timer child node toe (rechtermuisknop > Add Child Node > Timer)
Hernoem de Timer naar FireRateTimer
Selecteer FireRateTimer in de hierarchy
In de Inspector, configureer:
Wait Time: 0.5 (cooldown van 0.5 seconden = 2 shots/sec)
One Shot: Aan (timer stopt na elke timeout, we starten hem handmatig)
Autostart: Uit (we starten de timer alleen wanneer we schieten)
Sla de scene op
Scene hierarchy:
Muzzle marker
Voordat we verder gaan, voeg een Muzzle Marker3D toe aan het wapen. Dit markeert de positie waar de projectielen vandaan komen - de tip van het wapen. Later gebruiken we dit voor visuele effecten zoals muzzle flashes en beam lines.
Open de Railgun.tscn scene
Selecteer de Railgun root node
Voeg een Marker3D child node toe (rechtermuisknop > Add Child Node > Marker3D)
Hernoem de Marker3D naar Muzzle
Selecteer Muzzle in de hierarchy
Gebruik de Move tool om de Muzzle vooraan de loop van het wapen te plaatsen
Sla de scene op
Open het
RailgunscriptVoeg een nieuwe [Export] variabele toe om de muzzle bij te houden
Sleep vervolgens in Godot de muzzle node naar de Muzzle in de inspector
Scene hierarchy:
Timer gebruiken in script
Nu passen we het Railgun script aan om de Timer te gebruiken.
Open het Railgun script
Voeg een variabele toe voor de timer referentie:
Nu checken we in
OnShoot()of de timer nog loopt. Als de timer loopt (dusIsStopped()geeftfalse), betekent dit dat we nog in cooldown zitten. We gebruikenreturnom de functie vroeg te stoppen.
Selecteer de Railgun node in de Godot Editor, en sleep de FireRateTimer node naar de fireRateTimer in de inspector
Weapon mount point

Maak een mount point in de Player scene waar je weapons aan kunt hangen. Dit is een lege Node3D die als referentiepunt dient - het weapon zal deze positie en rotatie volgen.
Open objects/Player.tscn
Selecteer de Camera3D node
Voeg een child node toe: rechtsklik Camera3D > Add Child Node
Zoek naar Node3D en klik Create
Hernoem de node naar WeaponMount
Pas de Transform > Position van WeaponMount aan in de Inspector:
X: 0.8 (rechts van het midden, voor rechtshandige weapon grip)
Y: -1 (iets naar beneden)
Z: -1.2 (voor de camera uit)
OPGELET! Bekijk de weaponMount in local transform en draai de Z-as, zodat die naar voor wijst!
Sla de scene op (Ctrl+S)
Scene hierarchy:
Weapon transform
Nu hebben we een WeaponMount punt, maar het weapon beweegt nog niet mee! De Railgun staat nog los ergens in de scene. Laat de Railgun elke frame de positie en rotatie van het WeaponMount volgen.
Dit doe je door de GlobalTransform van de Railgun gelijk te stellen aan de GlobalTransform van de WeaponMount. Een Transform bevat zowel positie, rotatie als scale - door deze te kopiëren volgt het weapon perfect de mount point.
Open het Railgun script
Voeg een nieuwe variabele toe voor de weapon mount referentie:
Nu gaan we in de method
_Process()elke frame de transform van het weapon updaten zodat het de WeaponMount volgt.
WeaponMount Toewijzen in de Scene

Nu moet je de verbinding maken tussen de Railgun en de WeaponMount.
Het probleem is dat de children van een child-scene (zoals de weaponmount een child is in de player scene) standaard niet zichtbaar zijn. Gelukkig kan je dit gemakkelijk oplossen.
Open de main scene (waar je Player en Railgun in hebt staan)
Rechts-klik op de Player node
Vink Editable Children aan
Selecteer de Railgun node
In de Inspector zie je nu een nieuwe property: Weapon Mount
Klik op Assign en navigeer naar: Player > Camera3D > WeaponMount
Selecteer WeaponMount en klik OK
Sla de scene op
Test met F6 - het weapon volgt nu je camera beweging!
Test het weapon system
Run de scene met F6
Beweeg met WASD en kijk rond met de muis
Het weapon volgt nu perfect je camera
Klik met de linker muisknop om te schieten
Probeer snel te klikken - door de fire rate zal dit niet lukken
Beam visualisation
Voeg nu een visueel effect toe aan de railgun. Wanneer je schiet, verschijnt er kort een beam die aangeeft waar je heen schiet.
Open scripts/Railgun.cs
Voeg een lege
ShowBeam()method toe onderaan de klasse:
Maak een dunne cilinder mesh die we als beam gebruiken:
Voeg een material toe om de beam cyan te kleuren:
Maak een MeshInstance3D en voeg deze toe aan de scene:
Bereken de richting en afstand tussen start en einde:
Positioneer, roteer en schaal de beam correct:
Verwijder de beam automatisch na 0.05 seconden:
Roep
ShowBeam()aan vanuitOnShoot():
Test met F6 - je zou nu een korte cyan beam moeten zien wanneer je schiet!
Complete railgun script
Laatst bijgewerkt