Starten met programmeren van een 3d omgeving in Unreal Engine – HUD Binding

print
Deze handleiding maakt deel uit van het programmeertraject:


Inhoud


Wat vooraf ging

We bouwen verder op de handleiding rond variabelen.

Er waren reeds variabelen toegevoegd aan de ThirdPersonCharacter Blueprint. Ook was er reeds een Event BeginPlay geprogrammeerd die de waarde van de variabele MaxGezondheid toekend aan Gezondheid.

  • Voeg er nog een Z-Event aan toe zodat bij het drukken op de Z-toets de gezondheid vermindert met 10.


HUD

De waarde van variabelen moeten vaak weergegeven worden op het scherm, de Print String functie is een tijdelijke oplossing maar zeker geen blijvende.

Een blijvende oplossing is de variabelen weer te geven op via de HUD door middel van Binding.

We hebben reeds kennisgemaakt met de HUD, maar ik herneem hier nog even deze kennismaking.

Wat is de HUD?

HUD staat voor Head-Up Display en verzorgt de UI (User Interface).

De UI is een “overlay” die wordt gebruikt om informatie weer te geven, denk aan allerhande informatiebalken (health bar,…), tellers, minimappen, “mikpunten” (crosshairs),… en die interactie van de gebruiker toelaat om het programma te besturen via knoppen, menu’s,…

Unreal Engine gebruikt de tool Unreal Motion Graphics UI Designer (UMG) om deze HUD’s aan te maken.

De kern van UMG zijn Widgets, een reeks vooraf gemaakte functies die kunnen worden gebruikt om de interface te construeren (knoppen, aankruisvakken, schuifregelaars, voortgangsbalken, enz.).

Deze Widgets worden bewerkt in een gespecialiseerde Widget Blueprint, die twee tabbladen gebruikt voor de constructie:

  • het Designer-tabblad maakt de visuele lay-out van de interface en basisfuncties mogelijk,
  • terwijl in het tabblad Graph de functionaliteit achter de gebruikte Widgets kan worden geprogrammeerd.

Laten we als heel eenvoudige kennismaking onze naam bovenaan het scherm plaatsen.

Widget Blueprint

We doen dit via een HUD die werkt via de Unreal Motion Graphics UI Designer op basis van een Widget Blueprint.

  • Klik in de Content Browser, in de gewenste map, met de rechtermuisknop ingedrukt op de achtergrond (of klik op de knop Add New).
  • Kies voor User InterfaceWidget Blueprint.
  • Geef het een gepaste naam.

  • Dubbelklik de net aangemaakte Widget Blueprint.

Merk rechtsboven de 2 modes op, Designer en Graph.

Links ziet u de verschillende UI-objecten die u kunt toevoegen (Button, Image, Text, Tex Box,…).

  • Sleep een Text-object ongeveer naar het midden van het scherm bovenaan.
  • In het Details-panel vult u bij ContentText uw naam in en u druk op Enter.

  • Vink Size To Content aan.
  • Gebruik de Anchors om de Tekst bovenaan te centreren (X = 0.5 en Y = 0), druk op de Ctrl-toest om de centrering te zien.
  • Verhoog Y-positie naar 20 om wat ruimte bovenaan te krijgen.
  • U kunt eventueel ook nog het lettertype, de kleur,… wijzigen.

  • Compile en Save.

Onderstaande video geeft een woordje meer uitleg over het gebruik van het Text-object.

Onderstaande video toont het positioneren binnen UMG.


Binding

Naam

We wensen nu de variabele Naam weer te geven, dit gebeurt door de variabele Naam te verbinden met het Text-object.

Om de Naam van ons ThirdPersonCharacter te pakken te krijgen moeten we een casting naar ons ThirdPersonCharacter uitvoeren en deze dan promoveren tot een variabele (zie hierboven). We kunnen zeggen dat we een referentie naar ThirdPersonCharacter moeten creëren.

Oké, maar waar moeten we deze referentie toevoegen?

  • Vanuit de Widget Blueprint, klik rechtsboven op Graph.

U ziet onderstaande events klaar staan. De event die we nodig hebben is de Event Construct.

  • Vanuit Event Construct maakt u onderstaande casting aan. We hebben dit hierboven reeds gedaan, dus dit zal wel lukken zonder verdere uitleg.

Nu we een referentie hebben naar ons ThirdPersonCharacter, via de variabele MijnKarakter, kunnen we deze gebruiken.

We moeten de Naam van ons karakter weergeven in het Text-object.

  • Keer terug naar de Designer en selecteer het Text-object.
  • Zoek de eigenschap Text (deze eigenschap bepaalt de weer te geven tekst).
  • Achter de eigenschap Text ziet u Bind staan. Hiermee kunt u een Binding maken.
  • Klik op Bind.
  • Selecteer de variabele MijnKarakter.
  • U ziet hier de variabele Naam staan (met de wat ongelukkige Tooltip). Merk op dat u Gezondheid of MaxGezondheid niet ziet, dit komt omdat dit geen teksten zijn (ze zijn van het type Integer) en dus geen voor de hand liggende Binding zijn voor de eigenschap Text.

  • Klik op Naam.

De Binding is gemaakt.

U ziet deze echter nog niet verschijnen in het ontwerpscherm, daarvoor moeten we het programma eerst compileren, bewaren en starten. We doen dit straks maar eerst…

Gezondheid weergeven ten opzichte van de maximale gezondheid

We wensen ook de waarde van de variabele Gezondheid weer te geven ten opzichte van de variabele MaxGezondheid als een percentage.

  • Sleep een Progress Bar in ons ontwerp. Deze Progres Bar biedt de mogelijkheid om een procentuele verhouding weer te geven. Hoeveel is het percentage Gezondheid ten opzichte van de MaxGezondheid. We gaan ons niet bezig houden met een propere lay-out maar eventueel kunt u het via Anchor links verankeren en wat breder maken. U kunt het onderstaande eventueel overnemen.

Onderstaande video toont het gebruik van een Progress Bar.

De Binding dient te gebeuren met de eigenschap Percent. We kunnen nu echter geen directe Binding doen zoals met de variabele Naam, we dienen immers eerst het percentage te berekenen. We moeten dus een nieuwe Binding creëren.

Weet dat percentage wordt weergegeven als een decimale waarde tussen 0 en 1 (0.10 is dus 10%).

  • Klik op Bind achter de eigenschap Percent.
  • Klik op Create Binding.

U komt in de functie Get Percent 0 (u kunt deze naam eventueel wijzigen) en u ziet ook reeds de verbonden Return Node die de waarde voor de Binding zal teruggeven (Returnen).

We gaan nu de nodige programmeercode nog eens stap voor stap uitwerken.

  • Sleep de variabele MijnKarakter in de Widget Blueprint en GET de waarde (de referentie).

  • Sleep een verbindingslijn uit de MijnKarakter-node en zoek naar Get Gezondheid.

  • Doe hetzelfde voor Get MaxGezondheid.

Nu we beiden waarden hebben kunnen we het percentage berekenen door Gezondheid te delen door MaxGezondheid. Dit levert ons een decimale waarde op tussen 0 en 1 (het percentage). Omdat we een decimale waarde moeten krijgen als resultaat moeten we een Float delen door een Float (omdat onze variabelen Gezondheid en MaxGezondheid beiden van het type Integer zijn zal er dus een conversie gebeuren (we hadden misschien beter toch meteen Float als datatype gekozen, maar dan had ik deze opmerking niet kunnen typen)).

  • Type / en kies voor Float / Float.

  • Maak nu de verbinden, en merk de conversie op (die automatisch wordt aangemaakt). Verbindt het resultaat van de deling ook al met de Return Value-node.

De Binding is gemaakt.

Als u terugkeert naar de Designer dan ziet u de Binding met de functie GetPercent_0 staan.

  • Compile en Save.
  • Start het programma en merk op dat …

U ziet de HUD nog niet verschijnen.

Onze Widget Blueprint moet nog gekoppeld worden aan de HUD.


De Widget koppelen aan de HUD

Onderstaande stappen zijn overgenomen uit de handleiding Gameplay Framework. Indien u op dit project verder werkt hoeft u dit niet meer uit te voeren. Anders volgt u onderstaande stappen.

We gaan nu deze Widget koppelen aan de HUD. Dit is één optie en een keuze, ik zou de koppeling ook kunnen maken met bv. de PlayerController (op een gelijkaardige wijze).

  • In de Content Browser, klik op Add NewBlueprint Class (of klik met de rechtermuisknop in de net aangemaakte folder en klik op Blueprint Class).

  • Of, klik in het menu op BlueprintsNew Empty Blueprint Class….

U komt in onderstaand scherm waar u een Parent Class kunt selecteren. Bovenaan vindt u de meest gebruikte Parent Classes, onderaan kunt u eventueel een specifieke klasse zoeken (nadien verschijnt een knop Select om deze specifieke klasse als Parent Class te selecteren).

  • Merk op dat er nog geen HUD-klasse te zien is, we zullen deze moeten zoeken.
  • Zoek naar HUD.

  • Klik HUD aan, klik op Select en geef het een gewenste naam.
  • Dubbelklik de HUD-klasse om ze te openen.
  • Klik op het tabblad Event Graph.

Bij het opstarten van het programma moet de HUD getoond worden, en we moeten specificeren wat de HUD, welke Widget Blueprint, de HUD moet tonen.

Merk op dat in het Details-panel Show HUD reeds aangevinkt is.

  • Vanuit de Event Begin Play sleept u een nieuwe verbindingslijn en u zoekt naar Create Widget.

  • Als Class selecteert u de net aangemaakte Widget Blueprint (hier TestWidget).

  • Vanuit de Exec-pin sleept u een nieuwe verbindingslijn en u zoekt naar Add to Viewport.
  • U verbindt nu de Return Value van de Widget Blueprint met de Target van de Viewport.

Tenslotte moeten we nog weergeven wiens HUD dit is, wie de Owning Player is. We doen dit door de Player Controller (het is de Player Controller die de HUD (of de Widget) controlleert) op te vragen.

  • Sleep een verbindingslijn vanuit Owning Player en zoek naar Get Player Controller.

  • Merk de beeldschermpjes op die aanduiden dat deze informatie op het scherm komt.
  • Compile en Save.
  • Start het programma en merk op dat …

U ziet nog steeds niets verschijnen.

Hoe komt dit?

We hebben een nieuwe HUD-klasse aangemaakt maar ons programma weet nog niet dat hij deze moet gebruiken.

  • Ga naar deze folder.

  • Dubbelklik ThirdPersonGameMode om deze te openen.
  • In het Details-panel onder Classes ziet u alle klassen die gebruikt worden.

Merk op dat de gebruikte klasse voor de HUD de standaard HUD is.

  • Wijzig deze HUD-klasse naar onze eigen HUD (hier TestHUD).

  • Compile en Save.

U krijgt het gewenste resultaat.


De objecten van een Widget wijzigen via programmeercode

Stel, u wilt een object, of meerdere objecten, die u hebt toegevoegd aan een Widget kunnen wijzigen via programmeercode.

U dient daartoe het object tot een variabele te maken.

  • Keer terug naar de Designer van de Widget Blueprint die u hierboven gebruikte.
  • Selecteer het object, bv. het Text-object dat onze naam bevat.
  • Geeft het eerst een gepaste naam, bv. TitelNaam.
  • Vink Is Variable aan.

  • Compile en Save.
  • Ga naar Graph.
  • In het My Blueprint-panel ziet u nu het Text-object als variabele staan.

U kunt dit vervolgens als een gewone variabele gebruiken.

  • Sleep de variabele in de Blueprint en kies voor een Get of Set (hieronder 2 maal een Get).
  • Vervolgens kunt u bv. de Tekst opvragen (GetText) of de tekst voor de Tooltip instellen (Set Tool Tip Text) via Blueprint Visual Scripting.

Merk op dat in bovenstaande afdruk de Progressbar de naam ProgressBar_266 heeft. Misschien toch niet de meest gelukkig naam. Wijzig deze naam, via de Designer, in het Detail-panel van de Progressbar naar iets meer duidend als GezondheidBar.

Let op, een Binding wordt iedere Tick gecontroleerd, dit maakt dat Binding erg belastend is en weegt op de performance. Een Binding dient dus bij voorkeur enkel gebruikt te worden indien de update heel frequent, iedere Tick, dient te gebeuren (bv. een hoogtemeter in de HUD van de cockpit van een vliegtuig in een flight simulator).

Een oplossing ligt in het gebruik van een Event Dispatcher, maar dit bespreken we in een volgende handleiding.


Praktische voorbeelden

Basic Main Menu

Tekst opmaken

Achtergrond blur

Timer

Animated Widgets


Behandelde Basiscompetenties uit de module ICT Programmeren – Specifieke ontwikkelomgeving: complexe functionaliteiten

  • IC BC257 – heeft aandacht voor de gebruiksvriendelijkheid van de toepassing

Behandelde Basiscompetenties uit de module ICT Programmeren – Integratie externe functionaliteiten

  • IC BC256 – kan diverse elementen tot een nieuw betekenisvol geheel samenstellen

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.