Inhoud
Wat vooraf ging
- U hebt de Blueprint Visual Scripting introductie doorgenomen.
- U hebt weet van variabelen.
Inleiding
U hebt reeds kennisgemaakt met programmeren via Blueprints Visual Scripting. We gaan nu dieper ingaan op een aantal basisbegrippen van het programmeren.
- Dit project bouwt verder op het project gemaakt in de handleiding Start to Program – Blueprints Visual Scripting – Basisbegrippen – Variabelen.
- Open dit project, of bouw het eventueel opnieuw.
- Open de ThirdPersonCharacter Blueprint.
Deze Blueprint bevat een aantal variabelen/eigenschappen waar we in deze handleiding bewerkingen op gaan uitvoeren.
- IsLevend – deze eigenschap houdt bij of ons karakter nog steeds in leven is of niet.
- Naam – de naam die we ons karakter wensen te geven.
- Gezondheid – een waarde tussen 0 en 100 die aanduidt hoe gezond ons karakter nog is.
- MaxGezondheid – de maximale gezondheid voor mijn karakter. MaxGezondheid is ingesteld als een constante.
- Klik op de Event Graph en merk de event BeginPlay op.
Bij het opstarten van het programma/spel wordt de waarde van de variabele MaxGezondheid toegewezen aan de variabele Gezondheid. De variabele Gezondheid krijgt dus, iedere keer als we opstarten, de waarde van MaxGezondheid toegewezen. Dus, na het opstarten is Gezondheid gelijk aan MaxGezondheid.
In deze handleiding wensen we dit niet langer. U kunt alles selecteren en verwijderen (Delete-toets) of u kunt de verbinding, de link, verbreken. Dit laatste gaan we doen (zodat we de code kunnen laten staan, zonder verbinding wordt deze niet uitgevoerd).
- Klik met de rechtermuisknop ingedrukt op de Exec-pin van de BeginPlay-event.
De verbinding/link is verwijderd. De code blijft wel staan, ter info, maar wordt niet langer meer uitgevoerd.
- Geef de variabele Gezondheid een Default Value (bv. 70) om mee te werken.
Nu zijn we klaar om verschillende, heel eenvoudige berekeningen, uit te voeren.
Ik veronderstel dat het bouwen van de code gekend is en dat ik niet alles steeds stap voor stap moet uitleggen en dat het tonen van de code voldoende moet zijn. Hebt u hier toch nog problemen mee, herneem dan even de basishandleiding.
Toetsenbord-events
De verschillende berekeningen 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.
- Compile, Save en Play om dit uit te testen.
We gaan deze techniek in onderstaande voorbeelden gebruiken.
Strings
Een string is een tekenreeks, een niet opgemaakte tekst. We bespreken hier een beperkt aantal bewerkingen, hier vindt u alle String-functies.
- Klik met de rechtermuisknop ingedrukt ergens in de Blueprint en zoek naar String. U vindt alle String-functies (u moet eventueel wat scrollen).
Print String
Onderstaande code kent u reeds, het print een string, namelijk de variabele Naam. Dit gebeurt bij het drukken op de A-toets.
Zoals u weet werkt Print String enkel in Debug-mode (en dus niet in het eigenlijke programma).
We gaan Print String gedurende deze handleiding constant gebruiken om het resultaat te bekijken.
Append
Append laat toe om strings samen te voegen en zo bv. een zin te bouwen.
Bv. u wilt de zin bouwen “Mijn naam is: ” en vervolgens moet uw naam, de waarde van de variabele Naam komen.
Oké, maar ik wil mijn zin mooi afsluiten met een punt.
- Klik daarvoor op Add Pin, er wordt een nieuwe pin toegevoegd.
- Typ het punt in.
Nog een voorbeeld, stel u wilt de zin bouwen variabele Naam + “, uw gezondheid is: ” + variabele Gezondheid + “.”.
Denk eraan de nodige spaties te typen en merk de conversie op, de variabele Gezondheid is immers van het type Integer en dient dus geconverteerd naar het type String.
BuildString
Een alternatief voor Append, indien andere niet String-variabelen worden gebruikt, is BuildString. BuildString komt in verschillende varianten, naargelang het type.
We gaan bovenstaand voorbeeld herwerken maar nu met BuildString: variabele Naam + “, uw gezondheid is: ” + variabele Gezondheid + “.”
De variabele Gezondheid is van het type Integer, we gebruiken dus de Integer-variant.
Merk op dat u hier een vast aantal pins hebt en dat u er geen extra kunt toevoegen.
Merk ook op dat er geen conversie nodig is, u begrijpt wel waarom?
To Upper en To Lower
Met de functies To Upper en To Lower kunt u de string respectievelijk omzetten naar hoofdletters en kleine letters.
Onderstaand voorbeeld zet de variabele Naam om naar hoofdletters.
Lengte
De functie Len geeft de lengte van de String terug als een Integer.
Merk de conversie op.
Trimmen
Trimmen is het wegnemen van overbodig spaties aan het begin met de functie Trim of het einde met de functie Trim Trailing van een String.
Onderstaande code gaat eerst de beginnende en vervolgens de nakomende spaties wegnemen.
Let op: bovenstaande code neemt de spaties links en rechts weg van de variabele Naam voor deze variabele getoond wordt maar… de variabele Naam zelf wordt nergens gewijzigd en blijft dus de spaties behouden. Bovenstaand voorbeeld is dus maar een heel tijdelijke oplossing (voor de afdruk).
Praktischer is dat we, eens de spaties verwijderd zijn, de naam, zonder spaties nu, opnieuw toewijzen aan de variabele Naam. Dit gebeurt via aan SET. Deze SET Naam wordt uitgevoerd nadat de spaties verwijderd zijn en voor de Print String. SET bevat Exec-pins en maakt dus deel uit van de “instructielijn”.
Links, midden en rechts
Met de functies Left, Right en Mid (en enkele variaties) kunt u een aantal tekens van links, rechts en in het midden afzonderen als een nieuwe String.
Onderstaande code zal de eerste 5 tekens, de 5 meest linkse tekens, van de variabele Naam afzonderen en weergeven. In mijn geval heeft de variabele Naam de waarde “Geert Linthoudt” en wordt dus “Geert” afgezonderd en weergeven.
Een variant op de functie Mid is de functie Get Substring.
Zoeken
In bovenstaand voorbeeld heb ik zelf de 5, de lengte van mijn voornaam, ingetypt. Maar zou het niet handiger zijn moest ik kunnen zoeken naar de eerste spatie en de positie van die eerste spatie gebruiken om mijn voornaam af te zonderen? Dit kan gebruikmakend van de functie Find Substring. Deze functie geeft de positie, als een integer, weer waar de substring, die kan bestaan uit 1 of meerdere tekens, begint.
Onderstaande code past het bovenstaand voorbeeld aan maar zoekt nu eerst naar een spatie.
Het is niet te zien maar vergeet niet een spatie te typen bij Substring.
Use Case en Search from End zijn booleans (waar of niet waar) die u kunt aan- en uitvinken. Respectievelijk of er moet rekening gehouden worden met hoofdletters (Use Case) en of het zoeken moet beginnen vanaf het einde (Search from End).
Eventueel kunt u een Start Position (een Integer) ingeven.
Vervangen
Met Replace kunt u tekens vervangen door andere tekens.
Onderstaand voorbeeld vervangt alle e’s door o’s en kijkt niet naar hoofdletters (Ignore Case). U kunt uiteraard ook meerdere tekens zoeken en vervangen.
Reverse
De functie Reverse draait de String gewoon om.
Splitsen
De functie Split splitst een String in 2 op basis van een te zoeken string. Het resultaat is echter niet 1 maar 2 strings, voor en na de splitsing. de Output-parameter Return Value is een Boolean die aangeeft of er al dan niet gesplist is. Indien waar kan er eventueel opnieuw gesplitst worden (in een lus, zie later).
De pin In Str bevat de tekst waar naar gezocht moet worden om te splitsen, hier dus een spatie.
Onderstaande code splits de variabele Naam in 2, de voornaam en de achternaam. Nadien wordt de Append-functie gebruikt om deze beiden weer te geven.
Vergeet niet de spatie te typen bij In Str!
Testen, Booleaanse vergelijkingen
Sommige functies hebben een Boolean (waar of onwaar) als Output-parameter. Naargelang de uitkomst (waar of onwaar) kan het programma dan een bepaalde richting uitgaan, de zogenaamde Control Flow. We komen hier later op terug maar ik geef al eens een overzicht van de voornaamste Booleaanse vergelijken met Strings.
Merk telkens de Return Value op die een rood kleurtje heeft, dit rode kleurtje verwijst naar het datatype Boolean.
Text
Het datatype Text komt minder voor en heeft ook minder mogelijkheden om mee te werken dan met Strings. Ik beperk me dan ook tot het geven van de link waar u een overzicht van alle functies vindt.
Een functie zou ik echter eens willen aanstippen omdat je ze zeker zal tegen komen en dat is de functie Format Text.
De functie Format Text bouwt een tekst met bepaalde woorden tussen {}, deze woorden kunnen dan nadien worden ingevuld (bv. met de waarden van variabelen of de uitvoer van andere functies). Het is een goed alternatief voor Append.
Hieronder ziet u het herwerkte voorbeeld van hier boven, de splitsing. Let op, de conversies zijn deze keer niet automatisch gebeurd, ik heb ze zelf moeten maken via de functie ToText(string).
De functie ToText kan ook gebruikt worden om getallen (integer of float) om te zetten naar tekst met bv. het gewenste aantal cijfers na de komma.
Tekst Render
Een Text Render kan worden toegevoegd aan een level om tekst naar wens weer te geven.
Set Tekst
- To Tekst (Float) zorgt voor de opmaak van het toegewezen getal.
- Merk op hoe de Minimum Fractional Digits en Maximum Fractional Digits beiden op 2 staan om exact 2 cijfers na de komma weer te geven.
- Append wordt gebruikt om een ” %” toe te voegen achter het getal.
- Set Text wordt gebruikt om tekst toe te kennen aan een Text Render.
- De specifieke Text Render actor wordt als Target van Set Text toegewezen.
Integer
Een Integer is een geheel getal. We bespreken hier een beperkt aantal bewerkingen, hier vindt u alle Integer-functies.
- Klik met de rechtermuisknop ingedrukt ergens in de Blueprint en zoek naar Integer. U vindt alle Integer-functies (u moet eventueel wat scrollen).
Operanden
Operanden worden gebruikt om eenvoudige berekeningen uit te voeren, denk aan optellen, aftrekken, vermenigvuldigen,… van 2 of meer getallen. Het datatype Integer in Unreal Engine kent volgende klassieke operanden:
- Merk op dat de meeste operanden 2 integers als invoer verwachten. De uitzondering is ABS (absolute waarde) dat het getal zonder voorgaand teken (negatie) teruggeeft, het maakt dus van een negatief getal een positief getal.
- De uitvoer is steeds een nieuwe, berekende, integer.
- Bij sommige operanden kunt u via Add pin meerdere invoer toevoegen.
- De %-operand staat voor de modulus, de rest van de deling.
De volgorde van de berekening
In vele programmeertalen is
1 + 2 * 3 = 7
Dit komt omdat de vermenigvuldiging voorrang heeft op de optelling. Er wordt dus eerst 2 * 3 = 6 uitgevoerd en vervolgens wordt er 1 bij opgeteld en dat maakt dus 7. Wilt u toch eerst de optelling uitvoeren dan moet u haakjes gebruiken en de berekening wordt dan:
(1 + 2) * 3 = 9
Blueprint Visual Scripting volgt de volgorde van de verbinding. Onderstaande berekening van 1 + 2 * 3 zal dus resulteren in 9.
Merk ook de conversie op van Integer naar String.
Variabelen gebruiken
Uiteraard kunnen we ook met variabele werken als invoer, of uitvoer voor de berekening.
Onderstaande berekening vermindert de waarde van de variabele Gezondheid (die bij mij een Default Value van 70 heeft) met 10. Het is belangrijk dat u de variabele Gezondheid met de bovenste pin verbindt (anders krijgt u 10 – 70 als berekening).
De uitvoer is dus 70 – 10 = 60
Maar is de waarde van de variabele Gezondheid nu ook gewijzigd naar 60 of niet?
Laten we dit uittesten door niet het resultaat van de berekening te printen maar de waarde van de variabele Gezondheid. Pas de Blueprint aan zoals hieronder, wat is de uitvoer denkt u?
De uitvoer is nu 70, ondanks de aftrekking is de eigenlijke waarde van de variabele Gezondheid niet gewijzigd. U merkt ook op dat deze Blueprint niet “mooi” oogt. Meestal, niet altijd, is dit een aanwijzing dat er iets fout zou kunnen zijn.
De oplossing is: na de berekening de berekende waarde opnieuw toekennen aan de variabele via een SET. Pas de Blueprint opnieuw aan zoals hieronder. Merk ook de vernieuwde verbinding op, SET heeft zijn eigen invoer- en uitvoerpin (Exec-pins) en deze moeten dus komen tussen de toetsenboerd-event en de Print String.
Verhogen met 1, verlagen met 1 en negatie
De onderstaande operanden
- ++ = verhogen met 1 (IncrementInt)
- — = verlagen met 1 (DecrementInt)
- – = negatie (NegateInt)
zullen de waarde van de variabele wel direct wijzigen (zonder een bijkomende SET). Merk de ruitvormige invoerpin op (we spreken van By Ref maar dit zien we later).
Onderstaande code zal de variabele Gezondheid verhogen met 1.
Integerdeling
Stel, uw wilt het percentage Gezondheid (waarde 70) ten opzichte van de MaxGezondheid (waarde 100) weten, dan kan u de waarde van de variabele Gezondheid delen door de waarde van variabele MaxGezondheid. U maakt onderstaande Blueprint. Merk wel al op dat u de variabele Gezondheid met de eerste, bovenste pin, als teller moet verbinden en de variabele MaxGezondheid in de tweede pin als Noemer. U hebt niet de vrijheid de verbinding om te draaien, want dan krijgt u een andere berekening.
Maar als u het resultaat bekijkt dan krijgt u de waarde 0, moet dat niet 0.7 zijn! Hoe komt dit?
Wel, kijk eens naar de uitvoerpin, die is van het type Integer en geeft dus geen decimale getallen terug, enkel gehele getallen. Vandaar de uitkomst 0.
Zo dadelijk gaan we dit probleem oplossen.
Willekeurige getallen
Wilt u het programma een willekeurig geheel getal laten bereken dan kan dit met onderstaande functies.
- Random Integer – levert een geheel getal op tussen 0 en Max – 1.
- Random Integer in Range – levert een geheel getal op tussen Min en Max inbegrepen. Dus Min >= Getal <= Max.
Onderstaande code zal een willekeurig getal tussen 1 (inbegrepen) en 45 (inbegrepen) genereren.
Testen, Booleaanse vergelijkingen
Net als bij de Sting-functies hebben sommige Integer-functies een Boolean (waar of onwaar) als Output-parameter. Naargelang de uitkomst (waar of onwaar) kan het programma dan een bepaalde richting uitgaan, de zogenaamde Control Flow. We komen hier later op terug maar ik geef al eens een overzicht van de voornaamste Booleaanse vergelijken met Integers.
Float
Een Float is een decimaal getal. We bespreken hier een beperkt aantal bewerkingen, hier vindt u alle Float-functies.
- Klik met de rechtermuisknop ingedrukt ergens in de Blueprint en zoek naar Float. U vindt alle Float-functies (u moet eventueel wat scrollen).
Operanden
Operanden worden gebruikt om eenvoudige berekeningen uit te voeren, denk aan optellen, aftrekken, vermenigvuldigen,… van 2 of meer getallen. Het datatype Float in Unreal Engine kent volgende klassieke operanden:
- Merk op dat de invoer– en uitvoerpins telkens van het type Float zijn.
- Deze zijn bijna dezelfde als bij het datatype Integer met aanvulling van E (Exponent), SQRT (vierkantswortel) en ^2 (2de macht).
Het datatype Float kent, net als Integer ook de operanden om te verhogen, verlagen met 1 en voor de negatie. Merk ook hier opnieuw de ruitvormige pin op wat erop duidt dat de waarde van de gebruikte variabele zal gewijzigd worden (zogenaamd By Ref).
Het rekenen met Float is hetzelfde als met Integer, ik ga dit niet hernemen maar me verder focussen op de verschillen.
Unreal Engine komt ook met een aantal gevorderde wiskundige functies. Ik ga deze enkel aanhalen maar niet verder op ingaan.
Afronden
In tegenstelling tot gehele getallen (Integer) kunnen decimale getallen (Float) afgerond worden. Unreal Engine komt met een hele reeks functies om af te ronden. Ze ontvangen allen een Float en geven een Integer terug.
- FCeil – Afronden naar het volgende gehele getal (9,8 wordt afgerond naar 10 en -9,8 wordt afgerond naar -9).
- Floor – Afronden naar het vorige gehele getal (9,8 wordt afgerond naar 9 en -9,8 wordt afgerond naar -10).
- Round – Afronden naar het dichtstbijzijnde gehele getal (9,5 wordt afgerond naar 10 en -9,5 wordt afgerond naar -9).
- Truncate – Afronden naar een geheel getal in de richting van 0 (9,8 wordt afgerond naar 9 en -9,8 wordt afgerond naar -9).
Maak nu zelf een Blueprint die deze verschillende afrondingen uittest door telkens een andere afronding te gebruiken. Hieronder ziet u één voorbeeld.
Deling
We hebben hierboven gezien dat de Integerdeling van de variabele Gezondheid (waarde 70) door MaxGezondheid (waarde 100) niet opleverde wat we verwacht hadden, we kregen 0 als resultaat maar verwachtten 0,7 omdat de Integerdeling een geheel getal teruggaf.
Als we deze deling nu echter uitvoeren met de Floatdeling dan krijgt u wel de verwachtte 0,7 omdat een Floatdeling een Float (decimale waarde) teruggeeft.
Merk de conversies op.
Unreal Engine kent ook de functie Division die u de Rest van de deling en de Integer waarde oplevert (vergelijk het met de klassieke staartdeling).
In ons voorbeeld is de Rest = 70 en Resultaat = 0.
Willekeurige getallen
Net zoals u willekeurige gehele getallen (Integer) kan genereren kan u ook willekeurige decimale getallen (Float) genereren.
De werking is identiek aan het genereren van willekeurige gehele getallen (Integer).
Testen, Booleaanse vergelijkingen
Net als bij de Integer-functies hebben sommige Float-functies een Boolean (waar of onwaar) als Output-parameter. Naargelang de uitkomst (waar of onwaar) kan het programma dan een bepaalde richting uitgaan, de zogenaamde Control Flow. We komen hier later op terug maar ik geef al eens een overzicht van de voornaamste Booleaanse vergelijken met Float.
Behandelde Basiscompetenties uit de module ICT Programmeren – Start to program
- IC BC228 – kent de verschillende principes en onderdelen op basis waarvan een programma kan opgebouwd worden
- IC BC229 – begrijpt de basisprincipes van programmeren
- IC BC237 – kan een eenvoudig programma wijzigen
- IC BC240 – kan een eenvoudig programma maken
- IC BC242 – kan een programma uittesten
- IC BC352 – begrijpt het systeem en de functies die achter een programma zitten