6. Road Placement & Base Placer
Maak een UI systeem om tussen verschillende building types te wisselen met arrow buttons
Overzicht
In dit hoofdstuk leer je:
UI-scene maken met HBoxContainer layout
BuildingSelector-script met texture extraction
Preview textures van MeshLibrary ophalen
Arrow buttons voor cycling tussen buildings
Input handling centraliseren in UI
UI-architectuur
Tot nu toe was het alleen mogelijk om building ID 0 te plaatsen via linkermuisklik. Je moest de code aanpassen om een ander building type te selecteren. Niet erg gebruiksvriendelijk!
In dit hoofdstuk maak je een visuele gebouw-selector met:
Preview textures van alle 5 gebouwen
Arrow buttons om te cyclen tussen building types
Gecentraliseerde input handling
De UI haalt preview textures direct van de MeshLibrary - geen extra assets nodig!
UI Scene opzetten
Bouw de visuele interface voor de building selector.
Scene aanmaken:
Maak een nieuwe User Interface scene
Hernoem de root node naar UI
Sla op als
scenes/UI.tscnZet Mouse > Filter op Ignore
Container toevoegen:
Voeg een HBoxContainer child node toe aan UI
In de Inspector, klik Layout → Anchors Preset → Top Left
Zet Position: X: 20, Y: 20
Zet Theme Overrides > Constants > Separation: 10
Left Arrow Button:
Voeg een TextureButton child toe aan HBoxContainer
Hernoem naar LeftButton
Texture Normal:
sprites/arrow_decorative_w.pngCustom Min Size: 32, 32
Zet Layout > Container Sizing > Vertical op Shrink Vertical
Preview Texture:
Voeg een TextureRect child toe aan HBoxContainer
Hernoem naar PreviewTexture
Texture:
sprites/icon_outline_square.png(placeholder)Custom Min Size: 64, 64
Expand Mode: Ignore Size
Stretch Mode: Keep Aspect Centered
Right Arrow Button:
Voeg een TextureButton child toe aan HBoxContainer
Hernoem naar RightButton
Texture Normal:
sprites/arrow_decorative_e.pngCustom Min Size: 32, 32
Zet Layout > Container Sizing > Vertical op Shrink Vertical
Sla de scene op!
BuildingSelector script implementeren
Maak het script en implementeer de building selectie logica.
Nieuwe Godot-specifieke elementen:
Control- Base class voor alle UI elementenTextureRect- UI node om een texture te tonenTextureButton- Klikbare button met textureMeshLibrary.GetItemPreview()- Haalt preview texture op van een MeshLibrary item
Maak een nieuw script:
Klik rechtermuisknop op scripts/ folder
Create New → Script...
Language: C#, Inherits: Control, Class Name: BuildingSelector
Path:
scripts/BuildingSelector.csKlik Create
Definieer de class en voeg UI exports toe:
Voeg system exports toe. Deze geven toegang tot BuildingPlacer en GridMap.
Voeg private fields toe voor state. De array slaat 5 building preview textures op.
Sla het script op!
Texture extraction implementeren
Haal de preview textures op uit de MeshLibrary.
Voeg een lege
ExtractBuildingTextures()method toe:
Haal de MeshLibrary op. Dit is de bron van alle preview textures.
Haal alle 5 building previews op. Elk building type heeft ID 0-4 in de MeshLibrary.
Preview textures:
GetItemPreview() genereert automatisch een texture van het 3D model
Geen handmatige screenshots nodig!
Elk building type wordt visueel weergegeven in de UI
Sla het script op!
Building selectie logica
Implementeer cycling tussen building types met arrow buttons.
Voeg een lege
ChangeBuilding()method toe:
Update de building index. Tel direction bij de huidige index (1 voor rechts, -1 voor links).
Voeg wraparound toe met modulo. Dit zorgt ervoor dat je van building 4 naar 0 gaat (en vice versa).
Modulo wraparound:
+ _buildingTextures.Lengthvoorkomt negatieve getallen% _buildingTextures.Lengthbeperkt de waarde tot 0-4Voorbeeld: index 5 wordt 0, index -1 wordt 4
Update het geselecteerde building ID in BuildingPlacer:
Update de preview texture in de UI:
Sla het script op!
Initialisatie en input handling
Koppel button signals en centraliseer input handling.
Nieuwe Godot-specifieke elementen:
_UnhandledInput()- Ontvangt input events die niet door UI zijn afgehandeld
Voeg een lege
_Ready()method toe:
Roep
ExtractBuildingTextures()aan om alle textures te laden:
Koppel button signals met lambda expressies. Wanneer een button wordt geklikt, roep ChangeBuilding() aan.
Lambda expressies:
() => ChangeBuilding(-1)is een inline functionRoept ChangeBuilding aan met parameter -1 (links) of 1 (rechts)
Kortere syntax dan aparte methods maken
Initialiseer de UI met het eerste building (index 0):
Sla het script op!
Voeg een lege
_UnhandledInput()method toe onderaan de class:
Waarom _UnhandledInput()?
Ontvangt input die niet door UI elements is afgehandeld
Button clicks worden door de UI afgehandeld
Mouse clicks in de game world komen hier aan
Voeg build input handling toe. Check of de "build" action is gedrukt.
Check of er gebouwd kan worden voordat je bouwt:
Roep de
Build()method aan:
Input flow:
User klikt linkermuisknop in game world (niet op UI)
"build" action wordt triggered
CanBuild() checkt of placement geldig is
Build() plaatst het geselecteerde building
Sla het script op!
BuildingPlacer input verwijderen
Verwijder de oude input handling uit BuildingPlacer.
Open scripts/BuildingPlacer.cs en verwijder de _Input() method:
VERWIJDER DEZE METHOD:
Waarom verwijderen?
BuildingSelector handelt nu alle input af
Geen duplicate input handling meer!
Centraal punt voor alle UI-gerelateerde input
Sla het script op!
UI koppelen en testen
Integreer de UI in de main scene en test het systeem.
Open
scenes/UI.tscnSelecteer de UI root node
In de Inspector, koppel het BuildingSelector.cs script
Configureer de UI exports:
PreviewTexture: Sleep de PreviewTexture node
LeftButton: Sleep de LeftButton node
RightButton: Sleep de RightButton node
Sla de scene op!
Open
scenes/main.tscnKlik rechtermuisknop op de Main root node
Selecteer Instantiate Child Scene...
Kies
scenes/UI.tscnSelecteer de UI node in de scene tree
Configureer de system exports in de Inspector:
BuildingPlacer: Sleep de BuildingPlacer node
GridMap: Sleep de GridMap node
Sla de scene op!
Druk F5 om het spel te runnen.
Test building selectie:
Klik op de rechter arrow → preview verandert naar building 1
Klik meerdere keren rechts → cycle door alle 5 buildings
Bij building 4, klik rechts → wrapt naar building 0
Klik links → cycle terug
Test building placement:
Selecteer een building met de arrows
Klik linkermuisknop op grass naast een road → building verschijnt
Selecteer een ander building
Plaats het → nieuw building type verschijnt
Wat moet werken:
Arrow buttons cyclen door alle 5 buildings
Preview texture update bij elke selectie
Linkermuisklik plaatst het geselecteerde building
Buildings draaien correct naar de road
Werkt alles? Sluit het spel (F8)
Veelgemaakte fouten
Preview textures zijn null: Controleer of de GridMap export correct is ingesteld en een MeshLibrary heeft.
Buttons reageren niet: Controleer of de button signals zijn gekoppeld in
_Ready().Input werkt niet: Zorg dat je
_UnhandledInput()gebruikt, niet_Input(). UI elements consumeren input in_Input().Buildings worden niet geplaatst: Controleer of de BuildingPlacer export correct is ingesteld in de UI node.
Wraparound werkt niet: Check of je
+ _buildingTextures.Lengthgebruikt in de modulo berekening (voorkomt negatieve getallen).
Volledig script
Laatst bijgewerkt