Inhoud
- Wat vooraf ging
- Inleiding
- Een Array maken
- Array functies
- Extra – Een array met willekeurige getallen
Wat vooraf ging
- U hebt de Blueprint Visual Scripting introductie doorgenomen.
- U hebt weet van variabelen.
- U kunt een functie aanmaken.
- U kunt eenvoudige bewerkingen uitvoeren.
- U hebt een basiskennis van Arrays.
- U hebt weet van Flow Control.
Inleiding
Deze handleiding bouwt verder op de basishandleiding over arrays en voegt een complexere toepassing toe. Hebt u reeds kennisgenomen van deze basishandleiding dan kunt u zich beperken tot:
Situering van deze handleiding binnen Unreal Engine
Een Array maken
We weten reeds dat een variabele een waarde van een bepaald datatype kan bevatten, bijvoorbeeld een getal (met het datatype Integer).
Maar stel dat we nu 10 gelijkaardige getallen nodig hebben, moeten we dan 10 variabelen aanmaken? En stel dat we er 10000 nodig hebben, moeten we dan 10000 variabelen aanmaken?
Gelukkig niet.
Hebt u meerdere gelijkaardige waarden nodig, bv. meerdere gelijkaardige getallen, de namen van de vestigingen van het PCVO Groeipunt,… dan plaatst u deze niet in een enkele variabele maar in een lijst van variabelen. Zo’n lijst van gelijkaardige variabelen van eenzelfde datatype wordt ook een Array genoemd.
Met gelijkaardig bedoel ik dat ik in een array die de vestigingen van het PCVO Groeipunt wil bijhouden, ik technisch wel de namen van de cursisten zou kunnen steken (deze zijn ook strings) maar ik dit toch beter niet doe. Ik maak dan beter een tweede array aan maar deze keer met de namen van cursisten.
Hoewel we verderbouwen op vorige handleidingen verkies ik toch met een nieuw project te starten.
- Start een nieuw Third Person Desktop/Console project van Maximum Quality With Starters Content en geef het een passende naam.
Ik verkies ook om te werken in de Level Blueprint.
- Om de Level Blueprint te openen klikt u in de knoppenbalk van de Viewport op Blueprints – Open Level Blueprint.
De Level Blueprint wordt geopend in de zogenaamde Event Graph. De Level Blueprint kent enkel maar deze Event Graph.
In de Events Graph worden de events geprogrammeerd.
Ik herneem ook nog even hoe u Toetsenbord-events kunt aanmaken.
Stel, ik wil een lijst met de vestigingen van het PCVO Groeipunt bijhouden. Deze vestigingen zijn namen, Strings dus, ik wil dus eigenlijk een lijst van strings bijhouden. Een lijst op zich is eigenlijk een lijst van variabelen van een bepaald datatype (hier String), we beginnen dus met het aanmaken van een variabele met de naam Vestigingen van het datatype String.
Variabele aanmaken
- Klik op +Variable in het My Blueprint-panel om een nieuwe variabele aan te maken.
- Geef de variabele de naam Vestiging en het datatype String.
Variabele omvormen tot een array
Nu we de variabele hebben kunnen we er een array van maken.
- Klik op het streepje achter het datatype en kies voor Array (de 9 blokjes).
- Klik op Compile.
Elementen toevoegen aan een array
Nu we de array hebben kunnen we elementen toevoegen.
Weet dat ieder element dat u toevoegt een index krijgt die kan gebruikt worden om het gewenste element te selecteren. Weet dat de eerste index de Index 0 is(we spreken van een zero-based index).
- Klik op Adds Element om een element toe te voegen.
- Typ de naam van de vestiging in en herhaal het toevoegen (via Adds Element) voor iedere vestiging.
Merk opnieuw de nummering, de index, op die begint bij 0.
Eventueel kunt u nog elementen Insert(en), Delete(n) en Duplicate(n).
Onze array is aangemaakt en reeds opgevuld met een aantal startwaarden.
Get en Set
- Sleep de array in de Level Blueprint voor een Get en een Set.
Wellicht merkt u meteen een probleem op, zowel die Input– als Output-parameters zijn allen arrays. Dit maakt dat onderstaande code een fout zal genereren.
U kunt een array dus niet zomaar printen.
Oké, eigenlijk is dit logisch want wat wilt u eigenlijk, alle vestigingen printen? Wellicht niet, wellicht wilt u een specifieke vestiging printen.
Om toch alle elementen van een array, alle vestigingen, af te drukken, moet u deze één voor één doorlopen. Dit kunt u doen met een For Each Loop (of For Each Loop with Break). Het Array Element bevat de eigenlijke waarde (de vestiging), Array Index de index binnen de array.
De code die we gaan maken gaan we elk aan een toets koppelen. Hiertoe moeten we toetsenbord-events gebruiken.
- Klik met de rechtermuisknop ingedrukt ergens in de Blueprint en zoek naar Keyboard.
- Vervolgens zoekt u naar de gewenste toets (bv. de F-toets) en klikt u deze aan.
U ziet de Exec-pins Pressed en Released staan. Deze kunnen we gebruiken voor het indrukken (Pressed) en weer loslaten van een toets (Released). Key is een Output-parameter die informatie over de ingedrukte toets bevat.
Om alle elementen van een array één voor één te doorlopen gebuikt u een For Each Loop.
Onderstaande code zal, bij het drukken op de F-toets, de waarde van alle elementen van de array Vestigingen één voor één tonen.
Om alle Actors van een specifieke klasse op te vragen gebruikt u de node Get All Actors of Class en geeft u de gewenste Actor Class mee.
Het resultaat, de uitvoer, is een array van alle elementen van de opgevraagde klasse.
U gebruikt de For Each Loop om iets te doen met al deze Actors.
Onderstaande code komt uit een latere handleiding en demonstreert de methode.
Array functies
Een array kent heel wat functionaliteiten.
We bespreken hier de meest belangrijke functionaliteiten.
Waarden opvragen
De normale Get (om waarden op te vragen van een variabele) wordt vervangen door de functie Get.
- Voeg de array Vestigingen toe via een gewone Get.
- Sleep nu een verbindingslijn uit de Output-pin en zoek naar Get.
Merk op dat u kunt kiezen tussen:
Get (a copy), waardoor een kopij wordt opgevraagd van de waarde. Als u dus de waarde van die opgevraagde kopij wijzigt, wijzigt de eigenlijke waarde in de array zelf niet.
Get (a ref) waardoor een referentie wordt opgevraagd naar de waarde. Als u dus de waarde van die opgevraagde referentie wijzigt, wijzigt u ook de eigenlijke waarde in de array.
- Eigenlijk is het gelijk wat u kiest maar het meest veilige is Get (a copy), kies dus voor Get (a copy).
De functie Get vraagt een element op uit array op basis van de index. Dit element op zich, de vestiging, een string, kan dan wel worden geprint.
Onderstaand voorbeeld vraagt het eerste element (index 0) op uit de array Vestigingen en drukt het af via Print String.
Merk op dat de functie Get de kleur van het datatype van de array overneemt.
Indien u wenst kunt u ook weer werken met een variabele via Promote to Variable.
- Klik met de rechtermuisknop ingedrukt op de Integer Input-pin en kies voor Promote to Variable.
- Geef de nieuw aangemaakte Integer variabele een passende naam (bv. Index).
- Compile.
- Via Default Value in het Details-panel kan u nu een testwaarde, bv. 0, voor de index, ingeven.
Hieronder ziet u het gebruik van de Get-functie met de variabele Index.
Elementen toevoegen en invoegen
Add
De Add-functie wordt gebruikt om achteraan de array een element toe te voegen.
Zo is er onlangs een vestiging in Gent bijgekomen. Onderstaande code toont hoe u deze nieuwe vestiging kunt toevoegen.
Indien u wenst kunt u ook weer met een variabele werken voor de Input-pin zoals hierboven, ik bespaar me nu even de moeite.
Merk op dat de Add-functie een Output-pin heeft die de index van het net toegevoegde element bevat. Deze index kan dan gebruikt worden om de waarde op deze indexpositie op te vragen (Get) en uit te printen.
Weet dat als u het programma stopt, u de vestiging de volgende keer opnieuw moet toevoegen!
Add Unique
Add Unique doet eigenlijk twee zaken:
- het element dat u wenst toe te voegen opzoeken in de array.
- Als het element nog niet voorkomt in de array wordt het element toegevoegd, indien het element wel reeds voorkomt in de array wordt het niet toegevoegd.
Op deze manier voorkomt u dat eenzelfde element, eenzelfde waarde, 2 keer wordt toegevoegd en dat ieder element, iedere waarde, in de array dus uniek is.
Merk de Output-pin op, dit is een integer waarde van de index waar het element is toegevoegd, achteraan de array, dit is hetzelfde als bij de gewone Add-functie. Het verschil is dat bij Add Unique deze Output-pin ook een -1 (INDEX_NONE) kan resulteren indien het element niet is toegevoegd omdat het reeds voorkwam in de array.
Onderstaande code demonstreert dit.
Merk op dat als u de eerste keer op de D-toets drukt u de index-waarde van het nieuw toegevoegde element krijgt. Drukt u nogmaals op de D-toets dan krijgt u -1 als uitvoer. Klopt, het element is immers tijdens de eerste druk op de D-toets toegevoegd.
Insert
De Insert-functie wordt gebruikt om een element op een specifieke positie in te voegen. Indien u een element invoegt schuift het element dat zich reeds op die positie bevond, en alle volgende elementen, één indexpositie op.
Omdat dit minder vaak gebruikt worden dan de Add-functie beperk ik me tot het tonen van de keuze.
Onderstaand voorbeeld voegt een nieuwe vestiging Gent toe op de plaats bepaald door de waarde van de variabele Index. Indien de waarde van de variabele Index 0 is wordt het nieuwe element, de nieuwe vestiging, vooraan ingevoegd.
Set Array Element
Set array Elem(ent) is een beetje een combinatie tussen een klassieke Set en Insert. Net als bij Insert geldt ook hier de opmerking dat u dit wellicht niet zo heel vaak zal gebruiken.
Het enige verschil met Insert is de optie Size to Fit, moet de array automatisch langer worden als u een index meegeeft die buiten de huidige array ligt?
Length versus Last Index
De functie Length geeft u de lengte van de array.
De functie Last Index geeft u, het laatste (hoogste) indexgetal.
In de praktijk is:
Last Index = Length – 1
Onderstaand voorbeeld demonstreert dit.
Elementen (waarden) opzoeken
Er zijn twee functies om waarden op te zoeken Find en Contains.
- Find – zoekt het element en geeft de index terug (-1 indien de waarde niet gevonden is).
- Contains – zoekt het element en geeft aan of het al dan niet gevonden is (Een Booleaanse vergelijking die True of False kan zijn).
Indien u wenst kunt u ook weer met een variabele werken voor de Input-pin zoals hierboven, ik bespaar me nu even de moeite.
Verwijderen
Verwijderen kan ook door middel van 3 functies Remove, Remove Index en Clear.
- Remove – zoekt het element en verwijdert alle voorkomens van het element (indien hetzelfde element, dezelfde waarde, meerdere keren voorkomt in de array). Een Output-pin geeft aan of er effectief een verwijdering gebeurd is (Een Booleaanse vergelijking die True of False kan zijn).
- Remove Index – verwijdert het element op een specifieke index.
- Clear – verwijdert alle elementen in een array, maakt dus de array leeg.
Om te controleren of de Index wel bestaat kunt u het testen met een Is Valid Index.
Extra – Een array met willekeurige getallen
Als afsluiting van deze handleiding, en van de reeks aan basishandleidingen, gaan we een stukje programmeren. Een herhaling van zowat alles dat we tot nu toe gezien hebben.
We starten met het genereren van een reeks van willekeurige getallen en om te testen houden we het beperkt, bv. 6 willekeurige getallen met een waarde tussen 1 en 10.
Wat hebben we nodig aan variabelen?
- Een Integer-array (naam Getallen) van getallen.
- Een Integer-variabele (naam AantalGetallen) die bijhoudt hoeveel getallen we wensen te zien.
- Een Integer-variabele (naam MaxGetal) die bijhoudt wat de hoogste waarde is voor onze getallen die we gaan genereren.
- Een Boolean-variabele (naam Dubbel?) die aangeeft of er al dan niet een dubbelle waarde is (voor een tweede fase van ons programma).
Oké, nu we weten wat we nodig hebben kunnen we starten. Weet dat als u pas later denkt aan een variabele u die altijd zonder veel moeite kunt bijmaken via o.a. Promote to Variable.
- Maak al deze variabelen (en array) aan via My Blueprint.
Wat willen we nu doen?
Wel, we wensen een reeks van een aantal (bepaald door de variabele AantalGetallen) willekeurige (met een waarde tussen 1 en Maxgetal) getallen genereren en deze bijhouden in de array Getallen. Uiteindelijk wordt als verificatie die array uitgeprint.
Ik zou zeggen, probeer even zelf. Voor u verder kijkt probeert u dit zelf op te lossen. Het zou moeten lukken.
Oké, geprobeerd?
Hieronder ziet u een oplossing. Ik spreek over een oplossing en niet over DE oplossing omdat een probleem vaak op een aantal verschillende manier kan aangepakt worden.
Laten we even bekijken wat we hier hebben.
- Bij het indrukken van de E-toets.
- We moeten een aantal getallen genereren, daarvoor gebruiken we een iteratie, de ForLoop, deze Forloop begint standaard bij 0 (First Index), dit is oké. De Last Index bepaalt het aantal keer de lus wordt doorlopen (Last Index – First Index). De variabele AantalGetallen bevat deze waarde. Nu, omdat we de lus starten bij 0 en u wellicht in de variabele AantalGetallen de exacte waarde hebt ingegeven moeten we van AantalGetallen nog 1 aftrekken om te voorkomen dat we de lus eenmaal teveel doorlopen.
- Wat er gebeurt binnen de lus wordt bepaald door de Loop Body van de For Loop, dus alles dat uit de Output-pin Loop Body vertrekt wordt herhaald tijdens de lus.
- Wat moet er herhaald worden? Het genereren van een willekeurig getal en dit getal toevoegen aan de array Getallen. Het genereren van een willekeurig getal gebeurt via Randon Integer in Range, de Min(imale waarde) mag op 1 blijven staan, de Max(imale waarde) krijgt de waarde van de variabele MaxGetal. Het op deze manier gegenereerde getal wordt toegevoegd (ADD) aan de array Getallen.
- Als we dit het nodige aantal keer gedaan hebben, dus als de For Loop Completed is dan moet de array worden afgedrukt.
- We gebruiken hiervoor een variant op de ForLoop, namelijk de ForEachLoop (speciaal toegevoegd voor arrays), merk op dat deze ForEachLoop een Input-pin heeft voor een array. De ForEachLoop zal ieder element van de array doorlopen. De Output-pin Loop Body bepaalt weer de inhoud van de lus, in dit geval gewoon een afdruk via Print String. Wat moet er worden afgedrukt? De waarde van het Array Element.
Zo, dit zou moeten werken, had u dit ook gevonden?
Geen dubbele waarden
We gaan nu een stapje verder en we willen dubbele waarden voorkomen. We wensen dus enkel unieke waarden in onze array.
Oké, terug aan u, probeer het eerst zelf te vinden voor u verder kijkt.
Wellicht dacht u in eerste instantie aan volgende oplossing, u had immers tot nu toe goed opgelet en u weet dus van het bestaan van ADDUNIQUE.
Goed opgelet en goed gedacht maar, u voelt mij al aankomen, het geeft niet het gewenste resultaat. U krijgt wel unieke getallen maar u hebt soms ook minder getallen dan uw aantal gevraagde getallen. Hoe komt dit?
Wel, ADDUNIQUE voegt enkel een waarde toe indien deze nog niet bestaat in de array, tot hier geen probleem. Maar… bestaat de waarde wel al, dan voegt hij niets toe en de lus loopt gewoon verder zonder dat er een getal is toegevoegd aan onze array Getallen.
Wat is de oplossing?
Indien ADDUNIQUE een getal wilt toevoegen dat reeds toegevoegd is moet niet zomaar worden verder gegaan maar moet een nieuwe poging ondernomen worden. Er moet een nieuw willekeurig getal gegenereerd worden en dit nieuwe getal moet worden toegevoegd. Maar… aangezien dat nieuwe getal ook reeds kan bestaan binnen de array volstaat het niet om dit eenmaal te proberen maar moet dit herhaald worden tot er een getal gegenereerd is dat nog niet bestaat in de array Getallen en dat kan worden toegevoegd.
U ziet de oplossing hieronder. De toevoegingen en wijzigingen zijn geselecteerd (oranje rand).
- Ik heb dit onder de F-toets geplaatst maar u kunt ook gewoon verder werken onder de E-toets.
- Merk op dat inderdaad ADDUNIQUE wordt gebruikt maar dat er gekeken wordt of er een dubbel gevonden is (ADDUNIQUE == -1). Het resultaat heb ik aan een Booleaanse Variabele Dubbel? toegewezen.
- Deze variabele Dubbel? dient als invoer voor de While Loop. U weet, de While Loop herhaalt de lus zolang de Booleaanse vergelijk True is (dus zolang ADDUNIQUE de waarde -1 oplevert, of nog anders gezegd, zolang een dubbele waarde is gegenereerd).
- De Output-pin Loop Body van de While Loop bepaalt wat herhaald wordt. Merk op, dit is eigenlijk hetzelfde van net voor de While Loop, namelijk het genereren van een willekeurig getal en het toevoegen aan de array Getallen als het nog niet toegevoegd is.
- Van zodra er een getal gegenereerd wordt dat nog niet bestaat in de array Getallen keert ADDUNIQUE de index van het toegevoegde getal terug en dit zal altijd verschillend zijn van -1. Dubbel? is dus niet langer meer gelijk aan -1 en de While Loop wordt beëindigd.
- Merk ook op dat helemaal op het einde, als de lus die het afdrukken regelt Completed is, de array wordt leeggemaakt met CLEAR. Waarom is dit denkt u? Wel laat het eens weg en druk een tweede maal op de toegewezen toets (E of F). U programma zal “hangen”, waarom?
- Wel, we vragen 6 unieke getallen op met een waarde van 1 tot 10. Als we een tweede keer op de toegewezen toets drukken dan worden er weer 6 getallen toegevoegd aan de array Getallen. Dat maakt dat de array 12 elementen bevat. Geen probleem in ons eerste voorbeeld maar nu we stellen dat de waarde uniek moeten zijn (geen dubbele waarden mag bevatten), wel het is onmogelijk om 12 getallen op te vullen met unieke getallen tussen 1 en 10.
- Daarom moet de array weer leeggemaakt worden (CLEAR) nadat hij afgedrukt is (of eventueel meteen na het drukken op de M-toets, dus helemaal in het begin van de code).
DRY-principe
Weet u nog, DRY staat voor Don’t Repeat Yourself. In bovenstaand voorbeeld hebben we herhalende code, namelijk het genereren van het willekeurige getal en het toekennen aan de array Getallen wordt zowel voor als binnen de While Loop herhaald.
Zouden we hier dus niet beter een functie van maken zodat we niet langer zondigen tegen DRY?
- Selecteer de nodes die zich herhalen (met uitzondering van SET Dubbel? die gebruikt wordt als test voor de While Loop) en klik ze aan met de rechtermuisknop ingedrukt en klik op Collapse to Function.
- Geef de functie een passende naam (bv. GenereerWillekeurigGetal).
- Als u dubbelklikt op de functie GenereerWillekeurigGetal ziet u de functie staan.
Ik zou deze functie nog verder kunnen optimaliseren door de array Getallen en MaxGetal als Input-parameters aan te bieden, maar dit is voor een gevorderde cursus, voorlopig ben ik hiermee tevreden.
- Keer terug naar de Event Graph. Verwijder de nodes die zich herhalen binnen de While Loop en nu opgenomen zijn in de functie GenereerWillekeurigGetal en voeg in hun plaats de functie GenereerWillekeurigGetal toe aan de Loop Body-pin van de While Loop.
Voila, al veel overzichtelijker!
Sorteren
Tenslotte, zou het niet leuk zijn moesten de waarden gesorteerd worden weergegeven?
Tuurlijk, alleen spijtig dat Unreal Engine niet standaard met een Sorteer-functie komt (via een uitbreiding kunt u die wel installeren). Niet getreurd, het is een mooie oefening om zelf een Sorteer-functie te programmeren.
Ik kies voor de Bubblesort.
Bubblesort werkt als volgt (volgens Wikipedia):
1. Loop door de te sorteren rij van n elementen en vergelijk elk element met het volgende. Verwissel beide als ze in de verkeerde volgorde staan. Schuif dan een stapje op.
2. Loop opnieuw door de rij, maar ga nu door tot het voorlaatste element, omdat het laatste element het grootste in de rij was.
3. Nog een keer, maar negeer dan de twee laatste elementen.
4. Ga zo door.
n. Nog een keer, maar negeer dan de laatste n-1 getallen.
n+1. Klaar.
Oké, laten we hier even bij stil staan. Hoe pakken we dit aan?
Wel, we starten met een praktisch voorbeeld, neem bv. een spel kaarten en leg pakweg 6 willekeurige kaarten voor u op tafel.
U zal wellicht meteen in staat zijn die kaarten te sorteren, maar eigenlijk, onbewust heeft ons brein heel wat berekeningen en vergelijkingen uitgevoerd. De computer kan niets “onbewust” doen, hij moet alles doen volgens een stappenplan, een algoritme. Dit stappenplan, dit algoritme, dienen wij aan de computer mee te delen, we doen dit via instructies. Dit wordt programmeren genoemd (maar dit wist u al).
We moeten het sorteren dat we onbewust meteen gedaan hebben nu ontleden in een stappenplan er een algoritme van maken. De Bubblesort is een sorteer-algoritme (er zijn er dus nog anderen).
Hoe werkt die Bubblesort?
Wel als een soort bubbel. Laten we dit als een stappenplan beschrijven.
- U vergelijkt de 1ste kaart met de 2de kaart. Als de 1ste kaart groter is dan de 2de kaart dan verwisselt u beide kaarten van plaats (swappen).
- Dan vergelijkt u de 2de kaart met de 3de kaart. Als de 2de kaart groter is dan de 3de kaart dan verwisselt u beide kaarten van plaats. Herkent u een patroon? Inderdaad, er is een patroon, een herhaling, we herhalen namelijk het vergelijken van kaarten en eventueel van plaats veranderen tot aan de voorlaatste kaart. De voorlaatste kaart? Inderdaad, want als u tot de laatste kaart zou doorlopen en u vergelijkt deze met de volgende… wel, er is geen volgende. Wij mensen zullen dan wel anticiperen, de computer zal “blokkeren”.
- Op het einde van de bovenstaande herhaling zal de hoogste kaart achteraan liggen, ze is als het ware naar achteren gebubbeld (vandaar de naam Bubblesort). Maar de andere kaarten liggen nog steeds in een niet gesorteerde volgorde. We dienen dus de herhaling van puntje 2 opnieuw te herhalen. Hoe vaak? Om zeker te zijn zo vaak als er kaarten zijn.
- De herhaling van puntje 3 (noem het de buitenste herhaling) zal de herhaling van puntje 2 (de binnenste herhaling) dus… herhalen, alleen deze herhaling hoeft niet meer tot het einde door te lopen. Na de eerste herhaling lag immers de hoogste kaart reeds achteraan, na de 2de herhaling zullen de twee hoogste kaarten achteraan liggen, na de derde… herkent u opnieuw een patroon? We hoeven dus de binnenste herhaling (van puntje 2) niet telkens te herhalen tot op het einde maar tot op het einde min het aantal keer dat er al herhaald is.
We gaan dit nu programmeren.
- We beginnen met een nieuwe functie aan te maken via +function in My Blueprint-panel me de passende naam Sorteer.
Welke invoer heeft onze Sorteer-functie nodig?
Wel, een array van het type Integer (want we gaan een array van het type Integer meegeven).
- Voeg een Input-parameter toe met een passende naam (bv. TeSorterenArray) van het type Integer. Vink ook Pass-By-Reference aan. We zijn dat begrip Reference reeds tegengekomen. In kort betekent het dat de array zelf wordt meegegeven en geen kopij. Dit betekent dus dat de meegegeven array zelf gesorteerd zal worden en geen kopij van de array. Dit is wat we hier wensen.
Let op, je kunt dit ook anders uitwerken, zonder Pass-By-Reference maar dan moet u de gesorteerde kopij van de meegegeven array als Output-parameter teruggeven.
Oké, we zijn klaar om te starten, probeer het eerst even zelf uit.
We gaan de Sorteer-functie stap voor stap uitwerken.
1. Loop door de te sorteren rij van n elementen en vergelijk elk element met het volgende. Verwissel beide als ze in de verkeerde volgorde staan. Schuif dan een stapje op.
Laat ons beginnen bij het begin “Loop door de te sorteren rij van n elementen”. Dit is wat ik omschreef onder mijn puntje 3 als de buitenste herhaling/lus.
Deze rij is de meegegeven array en de “n elementen” zijn het aantal elementen in de array die u kunt opvragen met Length of Last Index. Deze vormen de basis voor de buitenste lus.
De volgende stappen zijn:
2. Loop opnieuw door de rij, maar ga nu door tot het voorlaatste element, omdat het laatste element het grootste in de rij was.
3. Nog een keer, maar negeer dan de twee laatste elementen.
4. Ga zo door.
n. Nog een keer, maar negeer dan de laatste n-1 getallen.
Dit is wat ik omschreef als de binnenste herhaling.
Hoe vaak moet deze binnenste herhaling doorlopen worden? De formule is:
Aantal elementen – 1 (de lus loopt immers tot het voorlaatste element) – de hoeveelste keer u er al door gelopen bent (dit wordt bepaald door de index van de buitenste lus).
De Index van de binnenste lus zal gebruikt worden om de array elementen te bepalen die we gaan vergelijken en omwisselen. Omdat we deze Index meerdere keren zullen nodig hebben en om bijgevolg een “spaghetti” te vermijden ga ik deze Index aan een variabele toekennen.
Omdat deze variabele enkel gekend moet zijn binnen deze functie verkies ik een lokale variabele aan te maken.
- Klik op +Local Variable en maak een lokale variabele aan van het type Integer en geef het een passende naam (bv. LocalIndex).
- Set de waarde van de Index van de binnenste lus als waarde van de lokale variabele LocalIndex.
We gaan vanaf nu de lokale variabele LocalIndex gebruiken als Index.
Vervolgens moeten we het huidige element uit de lus (bepaald door LocalIndex) en het volgende element vergelijken en indien het eerste element groter is dan het tweede dan moeten we deze twee van plaats veranderen.
Om een element uit een array op te vragen hebt u de Get nodig, let op kies voor Get (a ref) en geen kopij (u weet ondertussen wel waarom, niet?).
We werken nu het vergelijken van de elementen en het omwisselen (via de SWAP) in één keer uit.
Door te dubbelklikken op een verbinding kunt u een bijkomend knooppunt maken dat u kunt gebruiken om alles overzichtelijk te houden.
Stel dat u dit niet zou doen, en ook geen lokale variabele had gebruikt dan had u kunnen eindigen in iets zoals hieronder. Het zal ook werken hoor, maar het is niet meer echt overzichtelijk.
Ik geef toe, een nadeel aan Blueprint Visual Scripting is dat u al snel in een onoverzichtelijke “spaghetti” belandt.
Gebruik dus (lokale) variabelen die u kunt hergebruiken, functies die u kunt hergebruiken en extra knooppunten om het overzichtelijk te houden.
We moeten tenslotte nog onze Sorteer-functie toevoegen aan de Level Blueprint. Dit gebeurt nadat de array is aangemaakt en voor hij is afgeprint.
- Klik op Event Graph en pas Level Blueprint als volgt aan.
Merk op, doordat een gewone afdruk via Print String eigenlijk van onder naar boven print heb ik de ForEachLoop gewijzigd in een ReverseForEachLoop, die de array dus van achter naar voor doorloopt zodat het kleinste getal bovenaan het scherm staat.
BELANGRIJK, in Unreal Engine Blueprints Visual Scripting wordt de Control Flow (of Flow Control) bepaald door de witte lijnen die de Exec-pins verbinden. Volg dus steeds de witte lijnen
Behandelde Basiscompetenties uit de module ICT Programmeren – Specifieke ontwikkelomgeving: eenvoudige functionaliteiten
- IC BC017 – kan ICT veilig en duurzaam gebruiken
- IC BC234 – kan de basisprincipes van programmeren in een specifieke ontwikkelomgeving toepassen
- IC BC236 – kan eenvoudige wijzigingen aan een programma aanbrengen
- IC BC241 – kan een programma in een specifieke ontwikkelomgeving maken
- IC BC250 – kan bij het programmeren in functie van een specifieke ontwikkelomgeving, een juiste logica volgen