Inhoud
- Wat vooraf ging
- Inleiding in 3D
- Inleiding in 3D
- Vectoren
- Berekeningen met vectoren
- Locatie, oriëntatie en transformatie
- Dot en Cross product
- Praktische voorbeelden
- Quickshots
Wat vooraf ging
- U bent vertrouwd met de werkomgeving van Unreal Engine.
- U kunt werken met variabelen.
- U kunt eenvoudige bewerkingen maken.
Inleiding
Bewerkingen, berekeningen in 3D zijn alom aanwezig bij het programmeren in een 3D omgeving. In deze handleiding wil ik de belangrijkste begrippen en bewerkingen in 3D bespreken.
Situering van deze handleiding binnen Unreal Engine
Inleiding in 3D
Assen
We spreken van een 3D wereld omdat er drie coördinaten, drie dimensies, zijn:
- Lengte
- Breedte
- Hoogte
of
- Forward
- Right
- Up
of
- X
- Y
- Z
Rotatie
Voor rotatie worden ook vaak de onderstaande termen gebruikt:
- Roll – rotatie rond de X-as.
- Pitch – rotatie rond de Y-as.
- Yaw – rotatie rond de Z-as.
Merk op dat in de laatste 2 afbeeldingen de X en Y ogenschijnlijk een andere richting uitwijzen, maar dit is maar schijn, de X-as is nog steeds Forward. Niets houdt u tegen het vliegtuigje de andere kant te laten opvliegen.
Unreal Engine gebruikt deze waarden eveneens. Bekijk hieronder de functionaliteit Make Rotator.
Transformatie
In een 3D wereld hebben we dus steeds 3 waarden nodig. Een variabele die deze 3 waarden kan bevatten is een Vector.
Locatie, Rotatie en Schaling bevatten allen 3 waarden en zijn dus allen vectoren.
- Rood is de X-as.
- Groen is de Y-as.
- Blauw is de Z-as.
Locatie, Rotatie en Schaling maken alle drie deel uit van een Transformatie zoals de functionaliteit MakeTransform weergeeft.
Vectoren
Een vector is in essentie een variabele die bestaat uit 3 getallen (van het type Float) en het dus mogelijk maakt 3 waarden bij te houden die corresponderen met de X-as, Y-as en de Z-as.
Laat ons eerst een variabele van het datatype Vector aanmaken.
We doen dit bijvoorbeeld als deel van de ThirdPersonCharacter Blueprint.
- Ga naar de ThirdPersonCharacter Blueprint door bijvoorbeeld in de World Outliner te klikken op Edit ThirdPersonCharacter.
- Maak een nieuwe variabele aan met een passende naam (bv. MijnVector).
- Wijzig het datatype naar Vector.
- Klik op Compile.
Merk de X, Y en Z op.
- Sleep de Vector-variabele in de Blueprint en kies voor een Get.
- Klik met de rechtermuisknop ingedrukt op de Pin en kies voor Split Struct Pin.
U krijgt nu de vector “uitgevouwen” in de 3 onderliggende coördinaten X, Y en Z. U kunt hetzelfde doen bij een Set.
Berekeningen met vectoren
Vectoren kunnen zowel met andere Vectoren als met getallen (Integer en Float) berekend worden. Het resultaat is telkens een nieuwe vector.
Hieronder ziet u een overzicht:
Vergelijkingen met vectoren
Vectoren kunnen vergeleken worden, u kunt een zekere tolerantie (afwijking) meegeven. Het resultaat van een vergelijking is ook hier een Boolean.
Functionaliteiten van vectoren
Vectoren komen met heel wat functionaliteiten, hieronder een overzicht van een aantal interessante.
Locatie, rotatie en transformatie
World, Relative en Local
Location en Rotation kunnen voorkomen in een World, Relative en Local variant.
- World – roteer (Rotation) of verplaats (Location) een Actor ten opzicht van zijn positie in de wereld.
- Relative – roteer (Rotation) of verplaats (Location) een Actor ten opzicht van zijn eventuele Parent Actor zoals de Scene Root binnen een Blueprint. Bijvoorbeeld een deur roteert Relative t.o.v. de Scene Root van de Blueprint Class.
- Local– roteer (Rotation) of verplaats (Location) een Actor ten opzicht van zijn eigen lokale referenties.
Het verschil tussen World en Local
- World – de Z-as wijst altijd recht naar boven, de X-as en Y-as staan hier loodrecht op.
- Local – de Z-as volgt de rotatie van de actor zelf. Is de actor 45° geroteerd dan zal ook de Z-as 45° geroteerd zijn, de X-as en de Y-as staan hier loodrecht op.
De locatie, rotatie en transformatie van een actor opvragen
Onderstaand instructies kunnen gebruikt worden om de locatie, rotatie en transformatie van de actor in te stellen (SET) en op te vragen (GET).
De locatie opvragen
Stel, u wenst te weten waar ons karakter zich in de wereld bevindt en u wilt deze coördinaten (de X, Y en Z) op het scherm afgedrukt zien.
We plaatsen deze code het best bij ons ThirdPersonCharacter zelf.
- Open de ThirdPersonCharacter Blueprint, moest u er al niet in bezig zijn, en klik op de Event Graph.
Omdat we een continue “update” wensen gebruiken we de Tick-event, een Delay zorgt voor enige vertraging want een Tick is gemakkelijk 60 FPS (Frames Per Second), dus 60 keer per seconde. De locatie van ons karakter wordt opgevraagd via de functionaliteit GetActorLocation. Aangezien we rechtstreeks in de Blueprint van ons karakter werken is de Target = Self.
Op onderstaande schermafbeelding ziet u dat ons karakter net een sprongetje, van geluk, gemaakt heeft. U ziet dit aan de gewijzigde waarde van de Z-coördinaat.
De richting van een actor opvragen
De functies Get Forward Vector , Get Right Vector, Get Up Vector, geven aan in welke richting een actor geroteerd is. Het resultaat is een vector.
Onderstaande code geeft u de richting van de pijl (Arrow)van een Character.
De richting van verplaatsing van een actor opvragen
Velocity is een vector die de richting van verplaatsing aangeeft. U gebruikt hiervoor de functionaliteit Get Velocity.
Onderstaande code geeft u de Velocity van een voertuig (Vehicle blueprint uit een Advanced Vehicle Project).
De snelheid opvragen
Onderstaande Blueprint haalt de snelheid van het voertuig op.
Vraag eerst de velocity op via Get Velocity en haal daarna de VectorLenght op, ken dit toe aan een variabele.
De locatie, rotatie of transformatie van een Actor wijzigen
U kunt de locatie, rotatie of transformatie van een Actor wijzigen door een nieuwe waarde te Setten of een waarde (Delta) toe te voegen via Add.
Merk op dat Actor standaard op Self staat, binnen een klasse op basis van een Actor is dit de actor van de klasse zelf. Indien het om een andere Actor gaat moet u deze meegeven.
SetActor
AddActor
Onderstaand voorbeeld zal een Actor 100 eenheden over de Y-richting verplaatsen via AddActorLocalOffset na het drukken op de 1-toets.
Actor roteren
Onderstaande code roteert een actor iedere Tick -10 over de Y-as.
Delta Seconds
Hebt u al opgemerkt dat de Tick-event een pin Delta Seconds heeft?
De Tick-event wordt iedere frame uitgevoerd. Hoe sneller uw computer, hoe meer frames per seconde er worden weergegeven en hoe sneller de rotatie.
Dit is vaak niet gewenst, zeker niet in een multiplayer-omgeving. Om de rotatie constant te houden moet deze onafhankelijk zijn van de framerate. Delta Seconds, je zou kunnen zeggen, de tijd tussen de frames, bieden de oplossing als ze worden meer opgenomen in de bewerking.
Dot en Cross product
- Dot Product – de interactie tussen gelijke dimensies (x*x, y*y, z*z). Het resultaat is een getal (Float).
- Cross product – de interactie tussen verschillende dimensies (x*y, x*z, y*z, y*x, z*x, z*y). Het resultaat is een vector.
Dot product
Dot product gaat na of twee vectoren dezelfde richting uitwijzen.
Het resulteert in een waarde tussen -1 en 1.
- -1 is volledige de tegengestelde richting
- 0 is loodrecht op mekaar
- 1 is volledig dezelfde richting
Of anders gezegd:
- een negatieve uitkomst – de vectoren wijzen in tegengestelde richting
- nul – de vectoren staan loodrecht op mekaar
- een positieve uitkomst – de vectoren wijzen in eenzelfde richting
In bovenstaand voorbeeld zal Dot product een positieve uitkomst geven want beide pijlen (vectoren) wijzen in eenzelfde richting.
Cross product
Cross product, ook wel vector product genoemd, levert een nieuwe vector, een nieuwe richting, op, op basis van de regel van de rechter hand.
Een Cross product meet de oppervlakte van 2 vectoren.
De wiskunde
De wiskunde valt buiten de doelstelling van deze handleiding, maar voor de liefhebbers wil ik och deze links delen:
Onderstaande video gaat wat dieper in op de onderliggende wiskunde.
Praktische voorbeelden
Richting vergelijken
Onderstaande functie gebruikt DOT Product om na te gaan of uw Character en een object (hier de Arrow) in dezelfde richting wijzen.
- Vraag de rotatie op van beide actors (hier uw Character en de Arrow) via GetWorldRotation.
- Vraag de Forward Vector (Get Forward Vector) op van de rotatie.
- Bereken de DOT Product tussen beide vectoren. Indien de uitkomst positief is wijzen beide actors dezelfde richting uit. Hoe meer de uitkomst de waarde 1 nadert hoe meer ze evenwijdig lopen in dezelfde richting.
Beweeg de actor voorwaarts?
Onderstaande functie berekent of de actor zich voorwaarts beweegt.
- Vraag de Forward Vector op van de Actor via Get Actor Forward Vector.
- Vraag de Velocity (beweging) op van de Actor via Get Velocity. Normaliseer (Normalize), herleid tot waarden tussen 0 en 1, deze vector om een kleine beweging uit te sluiten.
- Bereken de DOT Product tussen beide vectoren.
- Indien de uitkomst positief is, is er een voorwaartse beweging.
Afstand tussen 2 punten berekenen
Hieronder ziet u een voorbeeld dat de afstand tussen 2 punten berekent.
De wiskundige formule is:
Merk op dat hier een functie zeker op zijn plaats is.
Merk op hoe Break Vector een vector opbreekt in zijn X-as, Y-as en Z-as.
Het aanroepen van de functie:
De richting van een karakter (in graden)
Onderstaande code is een methode om de richting (in graden) van uw karakter (pawn) te kennen. Het resultaat is de richting waarin uw karakter kijkt in graden tussen -180° en 180°.
- U vraagt uw karakter (pawn) op via Get Player Pawn.
- Met de functionaliteit Get Base Aim Rotation vraagt u de richting op waarin het karakter (Pawn) “kijkt”.
- Get Velocity en RotationFromXVector levert ons de richting van de Pawn op de X-as op.
- Via de functionaliteit Delta (Rotation) wordt de hoek (in graden) bepaald tussen de kijkrichting en de richting van de Pawn op de X-as.
- Via de functionaliteit Break Rotator halen we de richting van de Z (Yaw) op en bewaren die in een variabele Direction.
Ligt uw Character ondersteboven?
Onderstaande functie gaat na of uw Character ondersteboven ligt. U voegt deze functie toe binnen uw Character Blueprint.
- Vraag de rotatie (Get Socket Rotation) van de pelvis (bekken) van de Mesh van uw Character op. Meer over sockets bespreken we later in deze handleiding.
- Vraag de Get Right Vector op om de richting van de oriëntatie te bepalen.
- Voer een Dot product uit tegenover de Z-as (naar boven dus).
- Is het resultaat van Dot product groter dan of gelijk aan 0 dan ligt ons Character naar boven georiënteerd (IsFacingUp? = true).
Ligt een voertuig ondersteboven?
Onderstaande functie in de klasse van het voertuig zelf (VehicleBlueprint) gaat na of een voertuig ondersteboven ligt en stil staat, om nadien eventueel te respawnen.
- Om na te gaan of het voertuig ondersteboven ligt wordt de Up Vector opgevraagd (Get Actor Up Vector) en gekeken of het DOT-product met de Z-as (die de waarde 1 heeft) kleiner is dan 0.5.
- Om na te gaan of het voertuig stil staat wordt Vehicle Movement Get Forward Speed opgevraagd en gekeken of deze kleiner is dan 0.5.
- Indien beiden waar zijn wordt een variabele Stuck? (of welke naam u zelf verkiest) op True gezet, anders op False.
Een actor (bv. een zaklamp) plaatsen voor de speler
Onderstaand voorbeeld toont hoe u een object kunt plaatsen (bv. een zaklamp) voor de speler zodat het object meebeweegt met de speler.
Hiertoe moet zowel de rotatie als de locatie van de speler en het object overeenkomen.
Rotatie
Zorg dat de Actor, de zaklamp, mee roteert met de camera.
- Vraag de rotatie op van zowel de actor, de zaklamp, als van de speler via GetActorRotation.
- RInterp To (de R staat voor Rotation) zorgt voor een vloeiende overgang tussen deze twee rotaties op basis van de eigenschap Delta Time die u opvraagt via Get World Delta Seconds en de eigenschap Interp Speed die u zelf een waarde toekent.
- Stel de nieuwe rotatie van de actor in via SetActorRotation.
Locatie
Plaats de Actor (zaklamp) op een zekere afstand voor de camera.
- U vraagt de locaties op van de actor en van de speler via GetActorLocation, maar aan de locatie van de speler moet u de Camera Offset toevoegen (dit is een vector met waarden voor de X-as, Y-as en Z-as) die worden opgeteld bij de huidige locatie waarden.
- VInterpTo (de V staat voor Vector) zorgt eveneens voor een vloeiende overgang tussen deze twee locatie op basis van de eigenschap Delta Time die u opvraagt via Get World Delta Seconds en de eigenschap Interp Speed die u zelf een waarde toekent.
- Stel de nieuwe locatie in van de actor via SetActorLocation.
Lanceerplatform
Om een lanceerplatform te maken kunt u gebruikmaken van de bestaande functionaliteit LaunchChracter.
Een actor (bv. een tekst) die zich steeds roteert naar de speler toe
Onderstaand voorbeeld toont hoe u een Actor (bv. tekst) kunt laten roteren in de richting van de speler wanneer deze speler zich binnen een zekere afstand bevindt.
De volledige Blueprint ziet er als volgt uit.
Afstand tussen de actor en de speler
- De afstand tussen de Actor wordt bepaald door de locaties van beiden op te vragen via GetActorLocation. De functie VectorLenght levert de eigenlijke afstand op.
De Rotatie van de actor wijzigen
- De rotatie van de Actor in de richting van de speler kan bepaald worden door de functionaliteit Find Look at Rotation die als invoer de locaties van de actor en de speler opvraagt via GetActorLocation.
- De rotatie van de actor wordt ingesteld via SetWorldRotation.
Onderstaande video was een inspiratiebron.
Tumbler
Een Tumbler (tuimelaar) roteert een Actor met de muis.
- Vraag de muispositie op via Get Mouse X en Get Mouse Y.
- Vermenigvuldig de waarde van Mouse X met -1.
- Vermenigvuldig de waarden van Mouse X en Mouse Y met een gekozen Tumbler Speed.
- Maak met de berekende waarden van Mouse X en Mouse Y een nieuwe Rotater via Make Rotator.
- Vraag de rotatie van de actor die u wenst te roteren op via GetWorldRotation en combineer deze met de gemaakte nieuwe Rotator via CombineRotators.
- Bewaar de nieuwe rotatie voor de actor met SetWorldRotation.
Onderstaande video gebruikt een Tumbler om een object te inspecteren.
Teleporter
Onderstaande, uitgebreidere tutorial, legt het gebruik van een teleporter uit en pakt ook een aantal mogelijke problemen met het teleporteren aan.
Quickshots
Quickshots zijn korte, op zichzelf staande video’s, rond een specifiek onderwerp. Meestal aansluitend bij wat net besproken is.
Adding 3D Widgets
Custom Projectile
Random Streams
Behandelde Basiscompetenties uit de module ICT Programmeren – Specifieke ontwikkelomgeving: eenvoudige functionaliteiten
- 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 BC247 – kan de bouwstenen van een specifieke ontwikkelomgeving gebruiken
- IC BC250 – kan bij het programmeren in functie van een specifieke ontwikkelomgeving, een juiste logica volgen