Start to Program – Blueprints Visual Scripting – Basisbegrippen – Functies

print
Deze handleiding maakt deel uit van het programmeertraject:


Inhoud


Wat vooraf ging


Inleiding

In de vorige handleiding hebt u een eerste keer kennisgemaakt met het aanmaken van een Level Blueprint.

We hebben geprogrammeerd dat het licht automatisch aangaat bij het binnengaan van het “Huisje” en automatisch uit bij het verlaten van het “Huisje”.

We hebben daarvoor gebruik gemaakt van de events OnActorBeginOverlap en OnActorEndOverlap. Die de Visibility eigenschap van het object PointLight wijzigde.

We gaan deze code nu verder optimaliseren door het DRY-principe toe te passen.

  • Start het project dat bovenstaande Level Blueprint bevat en ga naar deze Level Blueprint.

DRY – Don’t Repeat Yourself

Eventjes wat algemeen, los van Unreal Engine. Wat is DRY?

DRY is simpel gezegd: schrijf geen twee keer dezelfde code.

Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.

Bovenstaande quote gebruikt twee (nieuwe) begrippen: piece of knowledge en representation.

Neem ons vorig programma, u wilt een lamp doen branden. Om de lamp te doen branden hebt u programmeercode (Blueprint Visual Scripting) nodig. U plaatst deze programmeercode in een eigen functie (functie, procedure, module, deelprogramma,… vele programmeertalen gebruiken een andere benaming voor wat vaak, ongeveer, hetzelfde is. In C++, en bij uitbreiding Unreal Engine wordt de term function gebruikt).

Deze functie krijgt een specifieke naam. De code in de functie is de piece of knowledge. De naam van deze functie is de representation waarmee de piece of knowledge wordt aangeroepen.

De functie, en de bijhorende code, wordt slechts eenmaal geschreven. De representation die deze functie aanroept wordt iedere keer hergebruikt waar u de piece of knowledge, in dit geval de lamp doen branden, nodig hebt.

Waarom is het DRY-principe belangrijk?

Als u tegen dit principe zondigt, en u herhaalt dezelfde code herhaaldelijk, dan zal u bij iedere potentiële wijziging aan deze code, deze wijziging moeten herhalen op alle plaatsen waar u de code gebruikt hebt.

Stel, u wilt een specifieke foutboodschap weergeven. Deze foutboodschap zal op meerdere plaatsen gebruikt worden. U kunt zondigen tegen het DRY-principe en deze foutboodschap telkens waar u ze nodig heeft opnieuw intypen. Maar stel dat u de foutboodschap wilt wijzigen. Dan moet u overal waar u deze foutboodschap ingetypt hebt de wijzigingen aanbrengen (en hopelijk vergeet u er geen te wijzigen).

Past u het DRY-principe toe dan hebt u die foutboodschap (piece of knowledge) aan een representation toegekend (gekoppeld) die u nadien herhaaldelijk gebruikt hebt. Als u nadien de foutboodschap (piece of knowledge) wilt wijzigen moet u enkel maar op die ene plek, binnen de functie, de wijziging aanbrengen.

Door DRY te programmeren:

  • wint u tijd (omdat u sneller fouten kunt verbeteren vermits u ze maar op één plek moet verbeteren).
  • beperkt u de kans op fouten.
  • maakt u de code ook leesbaarder.

Functies, concrete toepassing van het DRY-principe

Het DRY-principe is in zijn essentie “schrijf geen code tweemaal“.

Laat ons nu eens een kijkje nemen naar onze huidige Level Blueprint.

U merkt al snel op dat er bepaalde code, meer specifiek de code die de lamp aan- of uitschakelt herhaalt wordt in zowel de OnActorBeginOverlap-event als in de OnActorEndOverlap-event.

De oplossing ligt hem dus in het aanmaken van een functie en deze nadien tweemaal aan te roepen (1 keer binnen de OnActorBeginOverlap-event en 1 keer binnen de OnActorEndOverlap-event.

De functie aanmaken

  • Binnen Level Blueprint, klik links op New Function.

  • Geef de functie een passende naam (bv Lichtschakelaar).

Merk op dat er een nieuw tabblad met node aangemaakt is met de gekozen naam.

In het Detail-panel kunt u eigenschappen van de functie wijzigen (we doen dit voorlopig niet).

  • Ga naar de Event Graph en selecteer de zich herhalende nodes éénmaal (u ziet ze hieronder met een oranje omkadering). De Delay-node is een speciaal geval. U zou de Delay-node in theorie kunnen mee selecteren, want het herhaalt zich ook, ware het niet dat een functie geen Delay-node accepteert.

  • Knip nu de geselecteerde nodes en plak ze binnen de functie Lichtschakelaar.
  • Maak de verbinding, via de Exec-pin, met de functie Lichtschakelaar.

Bij deze is de functie klaar, we moeten ze nu nog aanroepen.

De functie aanroepen

De functie aanroepen gebeurt opnieuw in de Event Graph.

  • Ga naar de Event Graph.

Er zijn 2 manieren om de functie toe te voegen aan Level Blueprint.

  • Links zie je de naam van de functie staan. Sleep deze in Level Blueprint.

  • Klik met de rechtermuisknop in Level Blueprint, zoek en selecteer de functie onder Call Function.

  • Voeg op een van bovenstaande manieren de functie Lichtschakelaar toe en maak de verbinding (achter de Delay-node).

Doe nu hetzelfde voor de OnActorEndOverlap-event.

  • Selecteer en verwijder de nodes die zich eveneens binnen de functie bevinden.
  • Voeg de functie Lichtschakelaar toe en maak de verbinding (achter de Delay-node).

Als u wil kan je deze functie ook toepassen bij de BeginPlay-event. Let er dan wel op dat de Visibility als eigenschap voor het object PointLight staat aangevinkt (zodat ze door te “togglen” uit gaat).

  • Voeg de functie Lichtschakelaar ook toe aan de BeginPlay-event.

Oké, we zijn klaar om te testen.

  • Compileer het Level Blueprint door te klikken op de knop Compile. Vergeet dit niet!
  • Build en start het level. Alles werk zoals voorheen.

Parameters toevoegen

Onze bovenstaande functie werkt perfect maar aangezien we het object PointLight zelf opnemen in de functie zal deze functie enkel maar werken met dit specifieke object PointLight.

Voor onze eenvoudige level, die maar één licht bevat, is dit voldoende, maar stel dat u meerdere lichten opgenomen hebt en u wilt deze allen via de functie Lichtschakelaar laten werken?

De oplossing ligt hem in het niet langer vast opnemen van een specifieke object PointLight binnen de functie maar de mogelijkheid geven een, willekeurig object PointLight, mee te geven aan de functie.

Iets meegeven aan een functie gebeurt via een parameter. Een parameters is steeds van een bepaald type, in dit geval het type Pointlight.

U hebt Inputs-parameters (die het meest gebruikt worden) en Outputs-parameters.

Om een functie met een parameter (of parameters) toe te voegen:

  • Ga opnieuw naar de functie Lichtschakelaar.
  • We gaan eerst een kopie nemen van de huidige functie zodat we een functie met en zonder parameters hebben. Klik met de rechtermuiskop op de naam van de functie Lichtschakelaar en kies voor Duplicate.

  • Geef vervolgens een passende naam aan de nieuwe functie (bv. Lichtschakelaar_Met_Parameter, ok, niet meteen de meest flitsende naam maar voor die voorbeeldproject volstaat dit).

We gaan nu een Input-parameter toevoegen aan onze nieuwe functie Lichtschakelaar_Met_Parameter.

  • In het Details-panel, onder Inputs, duidt u het +-teken aan en krijgt ziet de knop + New Parameter. Klik op + New Parameter.

  • Geef een passende naam aan de parameter (bv. Lichtbron).
  • Een parameter is steeds van een specifiek type. Het standaard type is Boolean (waar of niet waar). Klik op het pijltje naar Boolean om het gewenste type te kiezen. U ziet de meest gebruikte types bovenaan staan.

We wensen een licht toe te voegen als parameter, zodat het licht niet vast ligt binnen de functie maar van buiten de functie kan meegegeven worden. Het type van de parameters is dus PointLight of meer beter nog het type Light (een Light is een algemener type dan een PointLight en maakt zo de functie meer algemeen en dus herbruikbaarder).

  • Zoek naar Light (of PointLight ook goed).

  • Klik Light aan om het toe te voegen als parameter.

Merk ook op dat er aan de functie, binnen de Blueprint, een “verbindingbolletje” is bijgekomen. Deze parameter Lichtbron is nu de Target van de functie Toggle Visibility.

  • Verbind de parameter Lichtbron met de target van de functie Toggle Visibility. De nodige conversie wordt automatisch toegevoegd.

De nog steeds aanwezige verbinding met het object PointLight is niet langer nodig, zelfs niet meer gewenst, en mag dus verwijderd worden.

  • Verwijder het object PointLight en de bijhorende conversie/casting naar Target (aanklikken en dan de Delete-toets indrukken).

We hebben nu een functie Lichtschakelaar met een verwijzing naar een vaste lichtbron en de functie Lichtschakelaar_Met_Parameter waar we een lichtbron aan kunnen meegeven.

Laten we nu, bv. bij de event OnActorEndOverlap, gebruik maken van de functie Lichtschakelaar_Met_Parameter.

  • Ga opnieuw naar de Event Graph van Level Blueprint.
  • Verwijder onder de OnActorEndOverlap de functie Lichtschakelaar.
  • Voeg de functie  Lichtschakelaar_Met_Parameter toe en maak de verbinding met de Delay-functie (herlees hierboven hoe u dit kunt doen).

  • Compileer het Level Blueprint door te klikken op de knop Compile. Vergeet dit niet!
  • Build en start het level.

Het blijkt niet te werken. Inderdaad, als we het “Huisje” binnen gaan dan gaat het licht wel aan, maar het gaat niet langer uit als we het “Huisje” verlaten!

Ook Unreal Engine merkt dit op want onderaan rechts verschijnt een foutmelding.

  • Klik op Show Message Log om de foutmelding te zien.

Vrij vertaald: “We hebben geen lichtbron toegekend”.

  • Selecteer het object PointLight in het Level (eventueel in World Outliner).
  • Ga naar de Event Graph van Level Blueprint.
  • Klik met de rechtermuisknop in Level Blueprint en klik op Create a reference to PointLight (we krijgen deze optie omdat PointLight geselecteerd is).

  • Verbindt nu Object PointLight met de parameter Lichtbron.

Oké, we zijn klaar om te testen.

  • Compileer het Level Blueprint door te klikken op de knop Compile. Vergeet dit niet!
  • Build en start het level. Alles werk zoals voorheen.

Commentaar toevoegen

Nu onze Blueprint een beetje uitgebreider wordt kan het handig zijn om commentaar toe te voegen.

Commentaar dient voor:

  • Derden die met uw Blueprint moeten werken en die willen/moeten weten waar dat gedeelte van de Blueprint precies voor dient (zonder het zelf diepgaand te moeten analyseren).
  • Uzelf, om u te helpen herinneren waarvoor een specifiek deel van de Blueprint dient. U hebt sneller een overzicht van de verschillende delen van de Blueprint.

Commentaar kan worden toegevoegd aan:

  • Een specifieke node.
  • Een groep van nodes.

Commentaar toevoegen aan een specifieke node

  • Ga opnieuw naar de Event Graph van Level Blueprint.
  • Als u een node aanduidt krijgt u links bovenaan 3 puntjes, de zogenaamde Toggle Comment Bubble. Klik op deze 3 puntjes en u kunt commentaar toevoegen.

  • Vervolgens typt u de gewenste commentaar in.

  • Als alternatief kunt u ook met de rechtermuisknop klikken op de node en de gewenste commentaar intypen bij Node Comment.

Commentaar toevoegen aan een groep nodes

  • Selecteer de gewenste nodes (met behulp van de Ctrl-toets of door erover te slepen).
  • Druk op de C-toets.

  • Typ de gewenste commentaar in.
  • Eventueel moet u nadien de “commentaar”-kader wat aanpassen zodat alle nodes er mooi instaan.

Commentaar wijzigen

  • (dubble)Klik op de commentaar die u wilt wijzigen.
  • U komt “in” de commentaar te staan en kan beginnen met wijzigen.

Conclusie

Oké, het eindresultaat van ons “project” is geen stap vooruit gegaan, waarom dan al deze moeite?

Wel, omdat, door het toepassen van het DRY-principe onze code “mooier” wordt, overzichtelijker, beter te onderhouden.

Wil ik nu iets wijzigen aan de “lichtschakelaar” dan moet ik dit enkel doen binnen de functie, ongeacht waar en hoe vaak deze functie gebruikt is. Het bespaart me niet enkel tijd, maar het voorkomt ook fouten (door sommige lichtschakelingen vergeten aan te passen).


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 BC242 – kan een programma uittesten
  • IC BC243 – kan een programma documenteren
  • IC BC352 – begrijpt het systeem en de functies die achter een programma zitten

Geef een reactie

Deze website gebruikt Akismet om spam te verminderen. Bekijk hoe je reactie-gegevens worden verwerkt.

  • Abonneer je op deze website d.m.v. e-mail

    Voer je e-mailadres in om je in te schrijven op deze website en e-mailmeldingen te ontvangen van nieuwe berichten.