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

print
Deze handleiding maakt deel uit van het programmeertraject:


Inhoud


Wat vooraf ging


Inleiding

In deze handleiding wordt kennis gemaakt met Physics.

Situering van deze handleiding binnen Unreal Engine


Physics

  • Start een nieuw Third Person Desktop/Console project van Maximum Quality With Starters Content en geef het een passende naam.

U kunt objecten (static meshes) Physics (fysische eigenschappen) laten simuleren. Hierdoor gaan deze objecten reageren op fysische acties (bv. wegduwen).

  • Selecteer het object en in het Details-panel vink Simulate Physics aan.

Collision

Een belangrijk aspect voor Physics is Collision.

  • Bouw deze kleine scene, 2 Wall’s met een SM_Door en SM_DoorFrame.

U kunt echter gewoon door de deur doorlopen, er is standaard geen Collison op deze deur.

Voor we de deur gaan toevoegen aan het level gaan we eerst Collision toevoegen (anders kunnen we gewoon door de deur door lopen zonder ze te openen).

  • Dubbelklik op de Static Mesh SM_Door.
  • Klik in het menu CollisionAdd Box Simplified Collision (een deur heeft slechts een eenvoudige Collision nodig).

  • Kik op de knop Collision en vink Simple Collision aan om de Collision te bekijken.

  • Kijk ook eens in het Details-panel om te zien of alles voor de Collision staat zoals hieronder (normaal wel).

  • Vergeet niet op Save te klikken om de wijzigingen te bewaren.
  • Vink Simulate Physics aan voor SM_Door.

  • Druk op Play en test dit uit.

Als u nu de deur probeert door te lopen… gebeurt er niets, u kunt er niet meer door.

De reden is dat de deur, SM_Door, gehinderd wordt door Collision van SM_DoorFrame.

  • Dubbelklik op de Static Mesh SM_DoorFeame.
  • Klik in de knop Collision en bekijk Simple Collision.

  • We zouden nu gewoon de Collision kunnen verwijderen via CollisionRemove Collision.

We gaan dit echter niet doen, we gaan het wat slimmer aanpakken en Collision enkel verwijderen voor Physische Actors en ons eigen Character (een Pawn).

  • In het Details-panel van SM_DoorFrame (dit kan vanuit de Static Mesh Editor (zoals in onderstaande schermafdruk) maar ook gewoon vanuit de Level Editor) zet CollisionCollision Presets op Custom, zodat u alles zelf kunt wijzigingen en geen op voorhand gekozen combinatie moet nemen, en vink voor Pawn en PhysicsBody Ignore aan i.p.v. Block.

  • Save en Play.

Loop tegen de deur en… ze valt om i.p.v. open te gaan.

  • Selecteer SM_Door en in het Details-panel onder PhysicsConstraints, Lock alle Positions en Rotations, door aan te vinken, behalve de Rotation over de Z-as, die wordt niet gelockt.

  • Druk Play… het kan zijn dat de deur vlot open gaat, of dat ze maar heel moeizaam open gaat.

Wanneer de deur moeizaam opengaat kan het zijn omdat de deur plat op de grond staat (Location Z = 130).

  • Verplaats de deur een eenheid (een cm) hoger zodat ze net boven de grond staat, zoals een echte deur trouwens (Location Z = 131).

  • Druk op Play en het zou moeten lukken.
  • Eventueel kunt u nog wat experimenten met de MassInKg en de Linear en Angular Damping.


Physics – Use the Force

We gaan The Force gebruiken, een combinatie van Physics en Tracing om:

  • Een Box omhoog te tillen.
  • Een Rots te verpulveren.
  • Een vijand van zijn sokkel blazen.

We gaan dit doen door te klikken op de F-toets (de F van Force) en we gaan een tracing for object (dit is een keuze, meer niet, dus een trace by channel had evengoed gekund) uitvoeren en zoeken naar PhysicsBody (voor de Box en de Vijand) en Destructible (voor de Rots). Om te debuggen gaan we de traceerlijnen permanent zichtbaar maken door Draw Debug Type op Persistent in te stellen.

  • Voeg een F-event toe aan de reeds besproken tracing en wijzig LineTraceByChannel naar een LineTraceForObject met een array van PhysicsBody en Destructible.

  • Klik vervolgens op de Out Hit-pin en kies voor Split Struct Pin.

Alle Out Hit-pins worden nu zichtbaar binnen de functionaliteit LineTraceForObject (dit bespaart ons een verbinding naar Break Hit Result)

  • Tenslotte gaan we checken of we iets geraakt hebben door te controleren of de Out Hit Hit Actor ? IsValid.

Een Box optillen

We gaan de Box het Object Type PhysicsBody geven.

  • Doe dit via Collision Presets en kies voor PhysicsActor, dit kent het Object Type PhysicsBody toe.

  • We maken er vervolgens een Blueprint van via Blueprint/Add Script zodat we eventueel code kunnen toevoegen, iets dat we niet meteen gaan doen, maar later misschien nodig kunnen hebben.

  • Geef de Blueprint een passende naam (bv. PhysicsBox) en bewaar het in de gewenste map (ideaal had u reeds een eigen mapje aangemaakt), ik plaats het in de map ThirdPersonBP.

  • Klik op Create Blueprint.

  • Compile en Save en sluit dit tabblad.

De voorbereiding van onze PhysicsBox is klaar, we gaan nu programmeren. We moeten dus de PhysicsBox optillen, meer concreet, de relatieve locatie (absolute locatie is een vaste locatie in het level, relatieve locatie ie een nieuwe locatie ten opzichte van de huidige locatie). Om ons object op te tillen hebben we een relatieve locatie nodig) via de Z-as (omhoog) te verhogen met bv. 100.

  • Ga naar de ThirdPersonCharacter Blueprint door bijvoorbeeld in de World Outliner te klikken op Edit ThirdPersonCharacter.

We passen onze Tracing By Object verder aan.

  • Eerst gaan we nagaan of we wel degelijk onze PhysicsBox geraakt hebben, we doen dit via een Cast to PhysicsBox.

  • Als Physics Box gaan we de locatie opvragen via de functionaliteit GetActorLocation.

Onderstaande schermafdruk zijn ingezoomd op de relevante gedeelten.

  • Omdat de verplaatsing enkel over de Z-as gebeurt gaan we de vector Return Value-pin opsplitsen via aanklikken met de rechtermuisknop ingedrukt en kiezen voor Split Struct Pin.

  • Maak nu ook de verbinding met de functionaliteit GetActorRelativeLocation en splits ook hier de New Relative Location-pin zodat we een X, Y en Z hebben.

  • Verbindt nu de beide X-waarden en de beide Y-waarde met elkaar. Bij de Z-waarde telt u eerst 100 op (de verplaatsing naar boven) voor u de verbinding maakt. Verbindt ook de PhysicsBox als Target, het werkt ook zonder deze verbinding maar dit is “properder”.

  • Compile, Save en Play.

Use the Force!

Een rots verpulveren

We gaan gebruik maken van de Starter Content die u, normaal, reeds toegevoegd hebt.

Als u dit toch zou vergeten zijn, geen probleem.

  • Klik in de Content Browser op Add New.
  • Klik op Add Feature or Content pack….

  • Selecteer Starter Content in het tabblad Content Packs.

De Starter Content is toegevoegd.

U vindt nu een bruikbare Rots (SM_Rock) in de map ContentStarterContentProps.

SM_Rock is een Static Mesh, we moeten die nu Destructible maken zodat we ze kunnen vernietigen.

In vroegere versies van Unreal Engine was de mogelijkheid om een Static Mesh Destructible te maken standaard ingebouwd. Nu moeten we een Plugin activeren.

  • Ga naar het menu EditPlugins.
  • Onder Physics vinkt u Enabled aan bij Apex Destruction.

U zal Unreal Engine opnieuw moeten opstarten om deze Plugin te activeren.

  • Herstart Unreal Engine en ga terug naar ContentStarterContentProps.
  • Klik nu met de rechtermuisknop op SM_Rock.
  • U ziet nu een nieuwe optie Create Destructible Mesh. Klik deze aan.

U komt in de DestructibleMesh Editor.

  • Klik op Fracture Mesh om de standaard destructie te genereren.

  • Save en sluit het tabblad.

U hebt een nieuw bestand SM_Rock_DM een Destructible Mesh.

  • Sleep deze destructible SM_Rock_DM in het level.
  • Compile, Save en Play.

Destructible is een Physics. Om de rots te vernietigen moeten Physics gesimuleerd worden.

  • Vink Simulate Physics aan in het Details-panel.

  • Compile, Save en Play.

Merk op dat de rots nu omvalt en uiteindelijk zal blijven liggen, hij is echter nog niet geëxplodeerd.

  • Om de rots nu te laten exploderen in 1000 stukjes moeten we terug naar de DestructibleMesh Editor van SM_Rock_DM.

We moeten twee aanpassingen maken:

  • Vink Enable Impact Damage aan (we gaan dit slechts tijdelijk gebruiken om de destructie te demonstreren). We gaan later Damage toebrengen op basis van de waarde van Damage Threshold (momenteel een waarde van 1). Let op, dit staat los van het aanvinken van Simulate Physics dat hierboven besproken wordt. Als Simulate Physics aan staat zal de rots bij het opstarten meteen verpulveren, anders verpulvert de rots pas als uw karakter er mee in aanraking komt (en dus damage toebrengt).
  • Zet het aantal gewenste stukken onder VoronoiCell Site Count van de huidige 25 naar het gewenste aantal. Ik kies voor 1000 maar weet dat dit enige procestijd zal vragen, hebt u een minder krachtige pc, kies dan een kleiner aantal.

  • Klik op Fracture Mesh om de standaard destructie te genereren. Met het schuivertje onder Explode amout kunt u het effect bekijken.
  • Save en sluit het tabblad.
  • Compile, Save en Play.

Oké, maar we willen dat dit slechts gebeurt op het moment we onze “Force” richten op de rotsblok. We gaan dit dus moeten programmeren.

We schakelen eerst ons Physics weer uit.

  • Als u niet wilt dat de rots omvalt bij het opstarten, vink Simulate Physics uit in het Details-panel. Ik laat het aanstaan.
  • Vink Enable Impact Damage opnieuw uit. Moest u Enable Impact Damage aanlaten dan zal uw rots ook verpulveren wanneer ons karakter er mee in contact komt en we wensen dit enkel wanneer we “The Force” toepassen.

Merk ook op dat dat onder Collision Presets het Object Type op Destructible staat. Tof, laat dit nu heel toevallig één van de object types zijn die we gaan tracen.

  • We maken er vervolgens een Blueprint van via Blueprint/Add Script zodat we eventueel code kunnen toevoegen, iets dat we niet meteen gaan doen, maar later misschien nodig kunnen hebben).
  • Geef de Blueprint een passende naam (bv. DestructibleRots) en bewaar het in de gewenste map (ideaal had u reeds een eigen mapje aangemaakt), ik plaats het in de map ThirdPersonBP.
  • Klik op Create Blueprint, Compile en sluit vervolgens de Blueprint.
  • Ga naar de ThirdPersonCharacter Blueprint door bijvoorbeeld in de World Outliner te klikken op Edit ThirdPersonCharacter. Ga naar de Event Graph.

We hebben reeds getest of een PhysicsBox was getraceerd (via een casting). Indien het geen PhysicsBox is dat we hebben getraceerd gaan we nu checken of het een DestructibleRots is, opnieuw via aan casting, nu een Cast to DestructibleRots.

  • Voeg een Cast to DestructibleRots uit vanuit de Cast Failed-pin van de Cast To PhysicsBox.

  • As Destructible Rots trekken we nu een verbindingslijn en zoeken we naar Apply Damage. Let op dat u de DestructibleComponent-variant selecteert.

Weet nog dat de Damage Threshold op 1.0 staat.

We moeten dus minimaal een Damage van 1.0 toebrengen.

  • Geef 1.0 in bij Damage Amount en maak de verbinding met de Exec-pin van de casting.

  • Klik op Compile, maar merk dat u een foutmelding krijgt.

Vrij vertaald, er wordt een Hit Location en Impulse Dir(ection) gevraagd.

  • We gaan deze halen bij de geraakte actor via GetActorLocation (we hadden ook de Out Hit Location-pin van de LineTraceForObject kunnen gebruiken).

  • Compile, Save en Play.

Oké, dit werkt en we kunnen het hier bij laten.

Maar wat dacht u van een beetje rook en een passend geluid?

Rook, of andere effecten is een zogenaamde Emitter. We gaan dus een Emitter moeten toevoegen.

  • Voeg een verbinding met Spawn Emitter at Location toe, kies P_Explosion als Emitter Template (P_Explosion komt met de StartersContent) en verbindt de Location met GetActorLocation.

Nu gaan we een geluidje toevoegen op de plaats waar de rots explodeerde.

  • Voeg een verbinding met Play Sound at Location toe, kies Collapse01 als Sound (Collapse01 komt met de StartersContent) en verbindt de Location met GetActorLocation.

  • Compile, Save en Play.

The force is strong with this one.

Een vijand van zijn sokkel blazen

Een derde en laatste voorbeeld is een “vijand” omver werpen, we gebruiken hiertoe opnieuw Physics.

Eerst gaan we een “vijand” toevoegen.

  • Ga naar de map waar u uw Blueprints plaatst (bv. ContentThirdPersonBP (eventueel de submap Blueprints)).
  • Klik met de rechtermuisknop in de map en kies voor Blueprint Class.

  • Kies Parent Class Character.
  • Geef de Blueprint de naam Vijand.
  • Dubbelklik om de Blueprint te openen.

Een Character Blueprint komt standaard met de volgende componenten.

  • CapsuleComponent
  • ArrowComponent
  • Mesh
  • CharacterMovement

Als u de Mesh selecteert, dan ziet u, in de Viewport, dat deze leeg is. We gaan dus eerst een Skeletal Mesh moeten toevoegen.

  • In het Details-panel, onder MeshSkeletal Mesh, selecteert u de gewenste Mesh, het gewenste karakter (bv. Sk_Mannequin het standaardkarakter dat we tot nu toe steeds gebruikt hebben).

  • Verplaats de Mannequin wat naar omlaag zodat net binnen de capsule past. De Z-waarde van de Location staat bij mij op -90.
  • Roteer de Mannequin zodat het hij in de richting van het pijltje (ArrowComponent) kijkt (zoals een echte man betaamt moet hij dus steeds zijn euh… pijltje achterna lopen). De Z-waarde van de Rotation staat bij mij op -90°.

Oké, onze mannequin staat er nogal stijfjes bij (in de zogenaamde A-pose). Dit komt omdat er nog geen animatie is toegekend.

  • In het Details-panel, onder AnimationAnim Class selecteert u de standaard animatie ThirdPerson_AnimBP.

Ons character staat nu in een Idle-pose te “ademen”.

Wij gaan onze vijand nu nog een rood kleurtje toekennen.

Om de kleur te wijzigen moeten we weten hoe, met welke parameter, de kleur wordt toegekend aan het gebruikte materiaal. U vindt het gebruikte materiaal van de Mannequin in het Details-panel onder Materials.

  • Dubbelklik het materiaal M_UE4Man_Body om het te openen.

In de wirwar aan nodes en verbindingen die dit materiaal maken ziet u de parameter BodyColor, deze bepaalt de kleur (momenteel een beige-achtige kleur) en die gaan we moeten wijzigen. We kunnen dit rechtstreeks hier door BodyColor te dubbelklikken en met de Color Picker een nieuwe kleur te kiezen.

Maar let op, dan gaan we dit materiaal rechtstreeks aanpassen en zullen ook andere Mannequins beïnvloed worden. We zouden een kopie van het materiaal kunnen wijzigen en dit toekennen aan onze vijandige Mannequin of we kunnen het dynamisch doen via programmeercode. ik verkies het laatste.

De kleur moet meteen worden gewijzigd als dit Vijand Character wordt toegevoegd aan het Level. Met andere worden, op het moment dat er een instantie wordt genomen van ons Character. De code die moet worden uitgevoerd als een instantie van een klasse (hier de klasse Vijand) wordt genomen moet worden toegevoegd aan de Construction Script van de klasse.

  • Sluit eventueel de Material Editor en ga terug naar onze Vijand Bluepint.
  • Ga naar het tabblad Construction Script.

Hieronder ziet u de toegevoegde code.

Zij die de Side Kick over Materialen gevolgd hebben zullen deze code herkennen, voor de anderen, wat gebeurt er?

  • Het materiaal van de Mesh moet dynamisch gewijzigd worden, dit kan via de functionaliteit Create Dynamic Material Instance met als target de te wijzigen Mesh.
  • We hebben hierboven opgezocht dat de parameter BodyColor moet gewijzigd worden, dit gebeurt via de functionaliteit Set Vector Parameter Value met als Target de net gecreëerde dynamische instantie en als Parameter Name BodyColor.
  • De Value, de kleur, maken we via Make LinearColor waarbij we rood op 1 (de maximale waarde, dus maximaal rood) zetten en de rest op 0 laten voor een zuivere rode kleur.

We zijn klaar met onze Vijand Blueprint.

  • Compile en Save.

Onderstaande video toont, na een introductie over GET en SET, hoe u dynamisch de kleur kunt veranderen.

  • Sleep de Vijand Blueprint 2 keer in het Level om twee vijanden te plaatsen.

We gaan nu onze “vijand” met de “Force” omvergooien. Dit kan door Physics te activeren, net als bij de rots hierboven.

Om dit uit te testen:

  • Selecteer één van de vijanden en vink Simulate Physics aan onder PhysicsMesh in het Details-panel.
  • Klik op Play.

Merk hoe de Vijand met Physics actief neervalt.

  • Vink Simulate Physics opnieuw uit want we gaan dit programmeren.
  • Ga naar de ThirdPersonCharacter Blueprint door bijvoorbeeld in de World Outliner te klikken op Edit ThirdPersonCharacter. Ga naar de Event Graph.

We hebben reeds getest of een PhysicsBox of een DestructibleRots was getraceerd (via een casting). Indien het geen PhysicsBox of geen DestructibleRots is getraceerd gaan we nu checken of het een Vijand is, opnieuw via aan casting, nu een Cast to Vijand.

  • As Vijand vragen we nu de Mesh van ons Character op via Get Mesh.

  • Compile, Save en Play.

Zo, hieronder ziet u de volledige Blueprint Scripting die uitgevoerd wordt bij het drukken op de F-toets.

Don’t underestimate the power of the dark side


Comedy capers

  • Plaats een cilinder in uw level, roteer hem horizontaal op ooghoogte en maak hem breder.

  • In het Detail-panel, vink onder CollisionSimulation Generates Hit Events aan.
  • Klik op Blueprint/Add Script en geef het een naam om er een Blueprint van te maken.
  • Selecteer StaticMeshComponent en zoek naar de event On Component Hit (die is geactiveerd door Simulation Generates Hit Events).

We beperken ons tot ons eigen ThirdPersonCharacter.

  • Sleep een verbindingslijn vanuit Other Actor en zoek Cast to ThirdPersonCharacter.

  • As Third Person Character zoek naar Set Collision Enabled (Mesh) en zet New Type op Collision Enabled (Query and Physics).

  • Set Simulate Physics, eveneens op de Mesh. Vink Simulate aan (indien dit nog niet het geval is).

  • Compile, Save en Play.

Lopen maar en let vooral niet op uw hoofd!

Onderstaande video gaat wat dieper in op het gebruik van de Ragdoll en Physical Animations.

Voor een uitgewerkt Ragdoll systeem verwijs ik u door naar deze handleiding.


Praktische videovoorbeelden

Making a Simple Conveyor Volume

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.