Starten met programmeren van een 3D omgeving in Unreal Engine – Bewerkingen in 3D

print
Deze handleiding maakt deel uit van het programmeertraject:


Inhoud


Wat vooraf ging


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.

Voorbeelden

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 op de X-as op.
  • Via de functionaliteit Delta (Rotation) wordt de hoek (in graden) bepaald tussen de “kijkrichting” en de oriëntatie 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.

Locatie, oriëntatie en transformatie

De locatie, oriëntatie en transformatie van een actor opvragen

Onderstaand instructies kunnen gebruikt worden om de locatie, oriëntatie 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.

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.

Actor roteren

Onderstaande code roteert een actor iedere Tick 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.

Voorbeeld

Besturing van een vliegtuig

Onderstaande code, de besturing (voorwaartse snelheid en rotatie) van een vliegtuig, komt uit Blueprint van een FlyingPawn uit een project gebaseerd op de Flying Template.

  • De Tick-event wordt iedere frame uitgevoerd maar de framerate is afhankelijk van de hardware en dus niet constant. De Delta Seconds is als “de tijd tussen de frames” en deze is wel constant. Omdat de verplaatsing van ons “vliegtuigje” onafhankelijk moet verlopen van de hardware die de framerate bepaalt (anders zou het vliegtuigje op de ene pc harder vliegen dan op de andere) werken we met Delta Seconds.
  • De huidige snelheid, bepaald door de variabele Current Forward speed wordt vermenigvuldigt met de Delta Seconds.
  • Make Vector levert met de X-as de voorwaartse beweging die via AddActorLocalOffset wordt toegevoegd aan Delta Location en dus ons vliegtuigje voortuit laat vliegen.
  • Get World Delta Seconds, ongeacht de framerate, wordt vermenigvuldigt met de variabelen Current Pitch Speed, Current Yaw Speed en Current Roll speed en vormt een nieuwe rotatie Make Rotator die wordt gebruikt voor de Delta Rotation van AddActorLocalRotation.

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:

Voorbeelden

Mario Kart boost

We hebben het allemaal wel eens gespeeld, jaja geef maar toe, Mario Kart. Mario Kart bevat een aantal “platformen” dat de snelheid een boost geeft.

Hieronder ziet u een eigen uitwerking van deze “boost”. Wellicht een erg vereenvoudigde, maar werkende, oplossing.

Ik ga het project niet volledig uitwerken en beperk me tot de code. Ik gebruikte hiervoor een Advanced Vehicle Project.

Maak een Bluepint Class aan dat het “platform” bevat en een Box Collision component (bv. met de naam Trigger). Voeg ook een Arrow component toe die de richting, waarin moet overlapt worden, aangeeft.

In de Event Graph voegt u onderstaande code toe.

  • Bij het einde van de overlapping van de Box Collision (met de naam Trigger), dus bij een On component End Overlap-event, Cast to VehicleBlueprint (want enkel wagens krijgen een boost en geen per toeval overlopend konijntje).
  • Het overlappende voertuig heb ik in de variabele Voertuig bewaard voor later hergebruik.
  • Ik vraag de snelheid op via Get Velocity en bewaar deze in de variabele Snelheid (door de Velocity op te vragen en niet de Forward Vector kan het voertuig ook achterwaarts rijdend een boost krijgen).
  • Get Forward Vector van de Arrow levert ons de richting van het overlappende “platform” op (deze Arrow is een component in de Blueprint van het “platform”).
  • Nu we beiden richtingen, van het voertuig en van het “platform” kennen vergelijken we deze met een Dot product.
  • Indien het Dot Product een positieve waarde oplevert hebben het voertuig en het “platform” eenzelfde richting, en wordt de Boost toegepast.
  • Voor de Boost heb ik een eigen Custom Event aangemaakt. Gewoon, om het overzichtelijk te houden, dus niet uit “technische” redenen.
  • Ik heb ervoor gekozen dat de Boost 4 seconden duurt en een verdubbeling van de snelheid teweeg brengt. Ik gebruik hiervoor een tijdslijn die van 1 naar 2 gaat gedurende 1 seconde, nadien 2 seconden op 2 blijft en nadien weer gedurende 1 seconde terugzakt naar 1. Dit is de Versnelling.

  • De tijdslijn wordt telkens, bij iedere nieuwe overlapping, van het begin (Play from Start) afgespeeld.
  • De tijdslijn levert een Versnelling op (een waarde tussen 1 en 2) en deze Versnelling wordt vermenigvuldigd met de Snelheid (vastgelegd bij het overlappen, het is deze snelheid waarmee overlapt werd dat verdubbeld wordt).
  • Deze nieuwe snelheid wordt toegekend aan de parameter New Vel van de functionaliteit Set Physics Linear Velocity, de Target is het Voertuig (meer bepaald de Mesh van het voertuig).

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. De eigenlijke controle is geselecteerd.

  • 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.

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

Making Procedural Content

Random Streams

Building a Jump Pad

Adding Camera Shake

Creating a Slow Motion Effect


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

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.