Inhoud
- Wat vooraf ging
- Inleiding
- Wat moet de automatische deur doen?
- Wat hebben we ter beschikking?
- Blueprint Class
- Plaatsen en testen
Wat vooraf ging
- U bent vertrouwd met de werkomgeving van Unreal Engine.
- U bent vertrouwd met Blueprint Visual Scripting.
- Deze handleiding maar deel uit van de reeks AEC Blueprints stap voor stap.
Inleiding
Deze handleiding is geïnspireerd door deze tutorial op de Unreal Engine Learning website.
In deze handleiding werken we een automatische deur uit.
De bedoeling van deze handleiding is om stap voor stap een aantal belangrijke programmeertechnieken toe te passen.
Het is niet de bedoeling van deze handleiding om in detail te gaan, de bedoeling is om snel tot een werkend resultaat te komen. De details vindt u in andere handleidingen die ik in deze handleiding link. In tegenstelling tot de meeste van mijn andere handleidingen ga ik deze handleiding niet uitbreiden/verdiepen met aanvullende video’s.
Situering van deze handleiding binnen Unreal Engine
Wat moet de automatische deur doen?
De eerste vraag die we ons stellen is wat de automatische deur precies moet doen en wat we daarvoor nodig hebben.
De deur moet automatisch openen als we in de buurt van de deur komen.
- We moeten dus beschikken over… een deur, met een deurframe. Dit zijn zogenaamde Static Meshes die kunnen gemaakt zijn in een programma als 3Ds Max of Blender.
- We willen een dubbele deur die openschuift.
- We moeten nagaan wanneer de speler in de buurt is van de deur.
- We moeten de locatie de deur bijhouden. Iets bijhouden doen we in variabelen.
- We wensen een flexibel systeem dat we gelijk waar in ons level kunnen plaatsen en gemakkelijk kunnen wijzigen indien nodig.
Welke programmeertechnieken worden gebruikt?
Onderstaande programmeertechnieken komen aan bod.
Wat hebben we ter beschikking?
Het project, dat we geïnstalleerd hebben in de inleidende handleiding, heeft ons het nodige materiaal aangereikt. Indien we dit niet hadden, hadden we dit moeten aanmaken, of importeren, bv. van de Unreal Engine Marketplace.
U vindt het beschikbare materiaal voor de automatische deur in de Content Browser – AEC_BPs – Auto_Door.
We beschikken reeds over de nodige Static Meshes voor de deur en het deurframe.
Al hebben we ze niet meteen nodig, neem ook al een kijkje in de Materials van de deur en het deurframe.
Blueprint Class
Componenten
Een Blueprint Class is een verzameling van objecten die bij mekaar horen alsook de geprogrammeerde interactie met die objecten.
Als we dit toepassen op onze automatische deur dan horen de deur en het deurframe, alsook de interactie met de deur, het openen van de deur, samen en kunnen we dit samenbrengen in een Blueprint Class.
Een bijkomend voordeel van een Blueprint Class is dat u deze gemakkelijk kunt hergebruiken en kunt wijzigen, omdat alles wat u nodig hebt in dezelfde Blueprint Class staat. Een Blueprint Class komt dus ook tegemoet aan onze eis om een flexibel systeem te ontwerpen.
U kunt een folder maken waarin u alle Blueprint Classes verzamelt, of u kunt de Blueprint Class plaatsen in dezelfde folder als de nodige Static Meshes. We hebben reeds de folder AEC_BPs – Auto_Door, we gaan daar onze Blueprint Class plaatsen.
- Klik met de rechtermuisknop ingedrukt in de folder AEC_BPs – Auto_Door en kies voor Blueprint Class.
- Een object dat u in een level plaatst is een Actor, onze automatische deur, die we in het level gaan plaatsen, is dus een Actor. We moeten dus Actor als Parent Class, basisklasse, kiezen voor de Blueprint Class.
- Geef een gewenste naam (bv. BP_AutoDoor) en dubbelklik de aangemaakte Blueprint Class om deze te openen.
De Blueprint Class is leeg op de DefaultSceneRoot na. De DefaultSceneRoot wordt niet weergegeven in het level maar bevat wel de transformatie (locatie, rotatie en schaal) in het level van de Blueprint Class. De DefaultSceneRoot is dus de basis, de root, van de Blueprint Class.
- We gaan nu de Static Meshes, de deur en de deurframe toevoegen, als onderdelen/componenten van de Blueprint Class, onder deze DefaultSceneRoot. Dit kunt u doen door de Static Meshes te slepen vanuit de Content Browser in de Blueprint Class onder DefaultSceneRoot of u klikt op Add Component en u zoekt naar Static Mesh.
- Vervolgens geeft u een gewenste naam (bv. AutoDoor_Frame) en voegt u onder de eigenschap Static Mesh de gewenste Static Mesh AutoDoor_Frame toe.
De deurframe is geplaatst binnen de Blueprint Class, we moeten nu de linkse en rechtse deur plaatsen. Beiden moeten geplaatst worden binnen/onder de deurframe, zodat, als we de deurframe roteren, de deuren mee roteren.
- Selecteer AutoDoor_Frame en voeg, zoals hierboven beschreven, de Static Mesh AutoDoor toe met de naam AutoDoor_L. Wijzig de Location van de Y-as naar -47.5 zodat de deur op zijn plaats komt (zie hieronder).
- Klik met de rechtermuisknop op de net toegevoegde AutoDoor_L en kies voor Duplicate om de rechtse deur aan te maken, die uit dezelfde Static Mesh bestaat.
- Geef de naam AutoDoor_R en kies voor de Location van de Y-as op 47.5. Zet de Scale voor de Y-as op -1, dit spiegelt de deur.
- De deur moet opengaan als ons character in de buurt komt. Een manier om dit te doen is door een Box Collision toe te voegen, onder de AutoDoor_Frame.
- Geef het een gewenste naam, bv. Door_Trigger. Zet de Location voor de Z-as op 84 en Scale X = 4, Y = 3 en Z = 2. Deze waarden zijn relatief willekeurig en proefondervindelijk bepaald.
- Een Box Collision Generate Overlap Events. Een event is een gebeurtenis. Zo hebt u de On component Begin Overlap en de On Component End Overlap events die getriggerd worden bij het respectievelijk beginnen en het beëindigen van de overlapping van de Box Collison. Aan een event kunt u programmeercode toevoegen. Events sturen dus het programma.
- Klik op Compile en Save.
De nodige componenten zijn toegevoegd, we zijn klaar om de interactie te programmeren.
Variabelen
Technisch gezien is een variabele een locatie in het computergeheugen waar u naar kunt verwijzen, via een naam, en dat een waarde van een bepaald type (tekst, getal, vector,…) kan bevatten. Deze waarde kan in de loop van het programma variëren.
Praktisch gebruikt u variabelen om eigenschappen van de klasse of tussentijdse resultaten, voor later hergebruik, bij te houden. Kortom, variabelen worden gebruikt om informatie die we nodig hebben voor het programmeren bij te houden.
Voor de deuren willen we de startpositie bijhouden, het is immers deze positie die zal veranderen (variëren) als we de deur openen of sluiten.
De positie van de deur zal variëren ten opzichten van de Y-as (hierover zo dadelijk meer). De waarde van de Y-as is een decimale waarde, van het type Float dus. We moeten dus variabelen aanmaken van het type Float.
- Binnen de Blueprint Class BP_AutoDoor, klik op + Variable.
- Typ de gewenste naam in (bv. DoorR_Start) en druk op de Enter-toets.
- Kies vervolgens het Variable Type Float.
- Herhaal dit voor de tweede variabele DoorL_Start. Dit is iets eenvoudiger omdat Unreal Engine het vorig gebruikte Variable Type (hier Float) meteen klaarzet. U hoeft dus enkel op +Variable te klikken en de gewenste naam DoorL_Start te geven.
- Klik op Compile en Save.
We hebben nu twee variabelen waar we de startpositie van de deuren kunnen in bijhouden voor later hergebruik bij het programmeren.
Construction Script
Een Blueprint Class kan meerdere keren toegevoegd worden aan een level, er kunnen meerdere deuren toegevoegd worden aan het level. We kunnen dus meerdere instanties (Instances) van dezelfde Blueprint Class toevoegen aan het level. Elke instantie kan eigen specifieke waarden hebben. Zo zal bv. iedere instantie van de Blueprint Class van de automatische deur op een andere locatie staan en dus een eigen specifieke waarde hebben voor de locatie.
Specifieke eigenschappen die kunnen variëren per instantie worden in variabelen bijgehouden.
De Construction Script, die uitgevoerd wordt wanneer de instantie wordt toegevoegd aan het level, wordt vaak gebruikt om specifieke waarden van de instantie in de variabelen in te stellen.
We hebben net de variabelen DoorR_Start en DoorL_Start aangemaakt om de startposities van de deuren bij te houden. We gaan de waarden van deze variabelen, de startposities van de deuren dus, instellen in de Construction Script.
Let op, de Construction Script is niet de enige plek waar u waarden kunt toekennen aan variabelen.
- Klik op het tabje Construction Script. De node Construction Script staat klaar als een startpunt om andere nodes toe te voegen, om te programmeren dus.
We wensen de startpositie van de deuren op te halen en te bewaren in de respectievelijke variabele.
De deuren bevinden zich binnen de deurframe (AutoDoor_Frame). De deurframe bevindt zich onder de DefaultSceneRoot. De DefaultSceneRoot bevat de eigenlijke transformatie (locatie, rotatie en schaal) in het level, in de wereld. De locatie van de deur is dus relatief ten opzichten van de locatie van de zogenaamde Parent, hier dus de deurframe. De deur verplaatst zich over de Y-as, de groene pijl. Het is dus de relatieve locatie van de Y-as die we moeten bewaren.
Om de relatieve locatie van de Y-as van de rechtse deur te bekomen doet u het volgende.
- Sleep het component AutoDoor_R in de Blueprint. Er wordt een referentie gemaakt naar dit component waardoor we toegang krijgen tot zijn eigenschappen.
We hebben de relatieve locatie nodig.
- Sleep een execute line vanuit AutoDoor_R en zoek naar Get Relative. De originele tutorial op de Unreal Engine Learning website gaat voor Get Relative Transform, ik ga een stapje vlugger en kies meteen voor Get Relative Location.
- We hebben nu de Get Relative Location toegevoegd, de Output is echter van het type Vector. Een Vector is een Struct, een samengestelde variabele, en bevat 3 waarden, een waarde voor de X-as, een waarde voor de Y-as en een waarde voor de Z-as. We moeten niet de volledige vector hebben maar enkel de waarde van de Y-as. Klik met de rechtermuisknop ingedrukt op de Output-pin Relative Location en kies voor Split Struct Pin.
U hebt nu toegang tot de 3 waarden, waaronder de waarde van de relatieve locatie van de Y-as. Deze waarde willen we bijhouden in de variabele DoorR_Start.
- Sleep de variabele DoorR_Start in de Blueprint en kies voor Set (Set bewaart een waarde, Get vraagt een waarde op).
- De Set-node heeft een Input Exec-pin die u moet verbinden met de vorige Output Exec-pin. De waarde voor DoorR_Start komt van Relative Location Y. Maak de nodige verbindingen, door te slepen, zoals hieronder.
- Herhaal nu de bovenstaande stappen voor de linker deur. U bekomt het onderstaande.
- Om gemakkelijk te herkennen wat deze code doet voegen we Commentaar toe. Selecteer alle nodes door er over te slepen met de linkermuisknop ingedrukt en druk op de C-toets. Vervolgens kunt u, naar wens, commentaar intypen.
De startposities van de deuren zijn nu bewaard in de voorziene variabelen.
Let op, indien u geen variabelen zou gebruikt hebben, dit kan, moet u telkens u de startpositie van de deur nodig hebt bovenstaande code herhalen. Door de code éénmaal te programmeren en de startpositie te bewaren in een variabele om later te hergebruiken maken we ons het programmeren iets gemakkelijker.
Overlap Event
De deuren moeten automatisch openen als ons Character in de buurt komt van de deur. Daartoe hebben we de Door_Trigger, een Box Collision, toegevoegd. Deze Door_Trigger triggert een Event. U vindt, of plaatst, Events in de Event Graph.
- Klik op het tabje Event Graph, en kijk, we hebben geluk, er staat al een Event OnActorBeginOverlap klaar die we kunnen gebruiken.
We willen niet dat de deur plots opent, dit mag een tijdje, een paar seconden, duren. We hebben dus een Timeline nodig.
- Sleep vanuit de Output Exec-pin van de node Event OnActorBeginOverlap en zoek naar Add Timeline.
- Geef de Timeline een gepaste naam (bv. Opendoors).
- Dubbelklik op de naam van de Timeline, u komt in de Timeline terecht. We wensen een Float-waarde, de waarde van de locatie van de Y-as, te wijzigen. Klik op Add Float Track.
- Klik met de rechtermuisknop en kies voor Add Key… (of klik met de Shift-toets ingedrukt).
- De Timeline begint op een Time van 0 en een Value van 0, geef deze waarden in.
- We gaan nu het eindpunt van de Timeline toevoegen. Klik met de rechtermuisknop en kies voor Add Key… (of klik met de Shift-toets ingedrukt). Geef een Time in van 2 (seconden) en een Value van 1. Klik op Zoom To Fit Vertical om de volledige lijn te zien.
- Selecteer beide toegevoegde keys (met de Shift-toets), klik met de rechtermuisknop op een Key en kies voor Key Interpolation Auto (of User zoals in de online tutorial). Dit zorgt ervoor dat de tijdlijn in het begin en op het einde iets trager gaat, wat handig is voor onze deur.
- Zet nu ook nog de Length op, dezelfde, 2 seconden en vink Use Last Keyframe? aan.
De Timeline is klaar.
- Keer terug naar de Event Graph en zoek naar Event ActorEndOverlap. Ik heb de overige Events (Event Tick en Event Begin Play) verwijderd omdat we ze toch niet nodig hebben.
Als we de overlapping met de deur beëindigen, als we dus niet meer in de nabijheid van de deur zijn, moet de deur weer sluiten. Of andersgezegd, moet de Timeline omgekeerd (Reverse) worden.
- Verbind de Output Exec-pin van de Event ActorEndOverlap met de Reverse-pin van de Timeline.
We gaan de aangemaakte Output-node Open van de Timeline gebruiken om de deur te openen.
De deur openen komt neer op de deur verschuiven over tijd over de Y-as vanaf de startpositie van de deur over een zekere afstand.
We werken eerst de linkse deur uit.
We hebben de startpositie van de linkse deur nodig. We hebben die opgeslagen in de variabele DoorL_Start.
- Sleep de variabele DoorL_Start in de Blueprint en kies voor Get, we moeten immers de waarde opvragen.
De linkse deur moet 90 eenheden (centimeter) opschuiven. Die 90 is proefondervindelijk bepaald. We moeten, voor de linkse deur, deze 90 aftrekken van de startpositie (voor de rechtse deur gaan we 90 moeten bijtellen).
- Sleep vanuit DoorL_Start en zoek naar Float – Float.
- Geef de waarde 90 in.
De deur, meer correct de startpositie van de deur, moet verschuiven van de startpositie 90 naar links. Beiden waarden hebben we nu reeds ter beschikking. Om tussen beide waarden te schuiven hebt u een LERP (Lineaire Interpolatie) nodig.
- Zoek vanuit DoorL_Start naar Lerp.
Een Lerp-node heeft volgende Inputs:
A – Startwaarde (hier de startpositie)
B – Eindwaar (hier de startpositie – 90)
C – Alpha, de waarde die de positie bepaalt tussen A en B
De Output (Return Value) is een waarde die ligt tussen A en B op basis van de waarde van Alpha. Is Alpha = 0 dan is de Output gelijk aan de waarde van A, Is Alpha = 1 dan is de Output gelijk aan de waarde van B. Is Alpha een waarde tussen 0 en 1 dan wordt, evenredig, een gelijkwaardige waarde tussen A en B als Output gegeven.
In dit voorbeeld wordt de Alpha bepaald door de Open-waarde van de Timeline. De Open-waarde van de Timeline gaat van 0 tot 1 over 2 seconden. Halfweg de Timeline, na 1 seconde, is de Open-waarde 0.5 en heeft de Open-waarde de halve weg afgelegd tussen A (startpositie) en B (eindpositie). Op deze manier stuurt de Timeline het openen van de deur over een tijdspanne van 2 seconden.
- Maak de juiste verbindingen zoals hieronder.
De Output van de Lerp, de Return value, moet nu gebruikt worden om de relatieve locatie van de linkse deur over de Y-as te wijzigen.
- Analoog met de Construction Script, voeg een referentie toe naar de linkse deur door Autodoor_L in de Blueprint te slepen en voeg vervolgens de Get Relative Location-node toe.
- Klik met de rechtermuisknop ingedrukt op de Output-pin Relative Location en kies voor Split Struct Pin.
- We moeten een nieuwe locatie instellen, zoek dus, vanuit Autodoor_L naar Set Relative Location.
- Klik met de rechtermuisknop ingedrukt op de Input-pin New Location en kies voor Split Struct Pin.
Voor de nieuw locatie blijft de X-as en de Z-as ongewijzigd. Voor de Y-as moeten we de waarde halen bepaald door de Return Value van de Lerp-node.
- Maak de verbindingen zoals hieronder.
De links deur is uitgewerkt.
- Herhaal nu alle bovenstaande stappen voor de rechtse deur. Let wel op, u moet nu 90 optellen!
- Na wat verschuifwerk en het toevoegen van commentaar zou dit de volledige uitwerking moeten zijn.
Overzicht
In detail
Onze Blueprint Class voor de automatische deur is klaar. We gaan ze nu plaatsen en testen.
Plaatsen en testen
- Sleep de Blueprint Class BP_AutoDoor in het level en geef onderstaande waarden voor de Location, Rotation en Scale.
- Druk op Play en test het openen van de automatische deur.
Alles zou moeten werken. Werkt het niet naar wens, doorloop dan nog eens de programmeercode, wellicht is er een foutje ingeslopen.