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

print
Deze handleiding maakt deel uit van het programmeertraject:


Inhoud


Wat vooraf ging


Inleiding

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 ontwerpen die kunnen worden gebruikt om de interface te construeren met behulp van knoppen, aankruisvakken, schuifregelaars, voortgangsbalken,….

We hebben reeds gezien hoe u een HUD kunt aanmaken. Alles werd echter rechtstreeks toegevoegd aan deze HUD.

We gaan deze kennis nu gebruiken om afzonderlijke Widgets aan te maken en deze als Widget toe te voegen aan de HUD. Dit kan via meerdere wegen, ik bespreek slechts één van deze wegen.

Situering

De situering van deze handleiding binnen het Blueprint Schematisch Overzicht.


Widgets ontwerpen

HUD

We gaan eerst de HUD Widget aanmaken, volgend de gekende werkwijze.

  • Klik in de Content Browser, in de gewenste map (ik heb een mapje UI aangemaakt om alle widgets te verzamelen), met de rechtermuisknop ingedrukt op de achtergrond (of klik op de knop Add New).
  • Kies voor User InterfaceWidget Blueprint.

  • Geef het een gepaste naam (bv. mijnHUD).
  • Dubbelklik de net aangemaakte Widget Blueprint.

De Widget bestaat uit een Canvas Panel, meer is op zich niet nodig voor het aanmaken van de HUD.

  • Compile en Save.

Widget

We herhalen nu de bovenstaande stappen en maken een nieuwe Widget aan met als naam mijnWidget.

  • Klik in de Content Browser, in de gewenste map (ik heb een mapje UI aangemaakt om alle widgets te verzamelen), met de rechtermuisknop ingedrukt op de achtergrond (of klik op de knop Add New).
  • Kies voor User InterfaceWidget Blueprint.

  • Geef het een gepaste naam (bv. mijnWidget).
  • Dubbelklik de net aangemaakte Widget Blueprint.
  • Omdat we deze Widget willen toevoegen aan de canvas van de HUD heeft deze Widget geen eigen canvas nodig, verwijder deze door het Canvas Panel te selecteren en op Delete te drukken.
  • Deze Widget hoeft ook niet het volledige scherm in te nemen. Wijzig rechtsboven in de Viewport Fill Screen naar Desired.

Maak onderstaande eenvoudige Widget aan.

  • Begin met een Size Box toe te voegen met een Width Override van 200 en een Height Override van 100.

  • Voeg binnen de Size Box een Border toe en wijzig de Brush Color naar een grijstint.

  • Voeg binnen de Border een Vertical Box toe.

  • Voeg binnen de Vertical Box een Text Block toe, centreer deze en geef een voorlopig Text Naam en de naam TxtNaam.

  • Voeg binnen de Vertical Box een Button toe, geef het een naam (bv. BtnOK).

  • Voeg binnen de Button een Text Block toe en geef het de Text OK.

  • Compile en Save.

Hiermee is onze Widget klaar.

Widget toevoegen aan HUD

Nu de Widget klaar is kunnen we deze toevoegen aan de HUD.

  • Ga naar de HUD.
  • Onder User Created zoekt u de net aangemaakte mijn Widget en u sleept deze onder het Canvas Panel.
  • Positioneer, via Anchors, centraal in het venster en vink Size to Content aan.


HUD Programmeren

We kunnen aan het programmeren slaan.

HUD oproepen in Game Mode

Het is eerste dat we moeten doen is de HUD op het scherm krijgen.

Waar gaan we dit programmeren?

U kunt dit op verschillende plaatsen, maar aangezien de HUD deel uitmaakt van de volledige game, en ook moet blijven bestaan nadat bv. ons Character overleden is, is de Game Mode de beste plek om de HUD aan te maken.

  • We zouden een eigen, nieuwe Game Mode kunnen aanmaken, ik verkies in deze handleiding de bestaande Game Mode te gebruiken, namelijk de ThirdPersonGameMode die u vindt in de folder ThirdPersonBPBlueprints. Open deze Game Mode.

  • Open Full Blueprint Editor.

Voeg onderstaande code toe. We hebben dit reeds gezien, het enige verschil is dat een referentie naar de HUD wordt bijgehouden in een variabele voor gemakkelijk hergebruik.

  • Bij Event BeginPlay.
  • Create Widget mijnHUD.
  • Promote de Return Value naar een variabele met de naam HUDReference.
  • Voeg de HUD toe aan de Viewport via Add to Viewport.

  • Compile en Save.
  • Start het programma. U ziet de HUD en de Widget.

Maar er zijn nog een aantal problemen.

De Widget staat centraal in beeld en krijgt u niet weg en als u op de OK-knop klikt bent u de cursor “kwijt”. Bovendien wilt u de naam van uw Character zien en niet “domweg” de tekst naam.

Laat ons beginnen met het laatste op te lossen.

Naam (ver)Binden

  • Ga naar de Blueprint van uw ThirdPersonCharacter.
  • Voeg een String variabele Naam toe.
  • Compile en typ uw naam is als Default Value.

  • Ga naar uw Widget mijnWidget.
  • In Graph, bij Event Construct, geef onderstaande code in die toegang verschaft tot uw Character en deze bewaart in een variabele.

  • In Designer, ga naar het object TxtNaam en Bind de eigenschap Text met de Naam van uw Character.

  • Compile, Save en Start.

U ziet nu de naam van uw Character staan.

Misschien maakt u de bedenking of het gebruiken van een Bind wel te verkiezen is, vermits deze iedere Tick wordt uitgevoerd?

Klopt, maar anderzijds wordt deze Widget maar tijdelijk weergegeven en kan het dus ook niet echt kwaad. Deze eenvoudige Binding zal de framerate niet echt beïnvloeden.

Zichtbaar en onzichtbaar maken

Het feit dat we de Widget meteen zien is omdat de eigenschap Visibility op Visible staat binnen de HUD.

  • Ga naar mijnHUD, selecteer mijnWidget en zet de Visibility op Hidden.

De Widget verschijnt niet langer bij het opstarten.

Nu moeten we een stukje programmeren om de Widget zichtbaar of onzichtbaar te maken.

Waar gaan we deze code plaatsen?

Wel, de Widget toont de naam van ons Character, de Widget moet dus enkel maar zichtbaar zijn indien ons Character bestaat. We kunnen dus de code om de Widget zichtbaar/onzichtbaar te maken het best bij ons Character plaatsen.

  • Open uw ThirdPersonCharacter Blueprint.

Eerst en vooral gaan we een referentie naar de HUD toevoegen aan ons Character. We hebben reeds een referentie naar de HUD in de Game Mode. We kunnen deze ophalen en in een variabele van ons Character plaatsen om gemakkelijker toegang te hebben tot de HUD. Doe dit bij Event BeginPlay zodat dit meteen, en enkel, bij het opstarten gebeurt.

  • Voeg onderstaande code bij de Event BeginPlay van het ThirdPersonCharacter.

Hieronder ziet u de code voor het zichtbaar/onzichtbaar maken van de Widget. Ik geef eerst de code en bespreek ze nadien.

  • Kies een toets (hier de I-toets) als event. Beter is nog een Input-event te maken maar om de handleiding niet onnodig langer te maken heb ik dit hier weggelaten.
  • De Flip Flop zorgt ervoor dat de eerste keer de event getriggerd wordt de A-zijde (zichtbaar maken) wordt uitgevoerd. De volgende keer wordt de B-zijde (onzichtbaar maken) uitgevoerd. Nadien weer de A-zijde enz..
  • Haal mijnWidget op vanuit de HUDReference.
  • Zet de Visibility op Visible (A-zijde) of Hidden (B-zijde).
  • Is de Widget zichtbaar (A-zijde) dan wijzigt u de Input mode naar Set Input Mode Game And UI en toon de muiscursor (Show Mouse Cursor aangevinkt). Beide instructies worden aangestuurd door de Player Controller.
  • Is de Widget onzichtbaar (B-zijde) dan wijzigt u de Input mode naar Set Input Mode Game Only en verberg de muiscursor (Show Mouse Cursor uitgevinkt). Beide instructies worden aangestuurd door de Player Controller.

Klik op de OK-knop

Om te klikken op een Button u de Iteraction eigenschappen in het Detail-panel  als volgt instellen.

We gaan de Button BtnOK, op de Widget, eveneens gebruiken om de Widget zichtbaar/onzichtbaar te maken.

  • Voeg, via Add Custom Event, een Event (met bv. de naam SluitWidget) toe en verbindt deze met de reeds geschreven code voor het onzichtbaar/zichtbaar maken van de Widget.

  • Ga, in mijnWidget, na of de Visibility voor de Button BtnOK op Visible (and hit-testable) staat. Dit is nodig om de Button te kunnen aanklikken.
    Belangrijk, controleer eventueel ook bovenliggende niveau de Widget op deze instelling moest het klikken op de Button niet werken!

  • Voeg een OnPressed Event toe aan de Button BtnOK.

  • Binnen Graph, voeg onderstaande code toe aan de Event On Pressed (BtnOK). De code roept de aangemaakte Event SluitWidget aan die zich bevindt binnen ons Character. We hebben reeds een referentie naar ons Character aangemaakt en bewaard in de variabele mijncharacter.

  • Compile, Save en Play. U zou nu de Widget moeten kunnen openen met de I-toets en sluiten met dezelfde I-toets of de OK-knop.

We zouden het hier kunnen bij laten maar het kan nog beter. We hebben nu de Widget meteen, handmatig, toegevoegd aan de HUD en maken deze enkel zichtbaar/onzichtbaar.

Oké dit werkt, maar dit betekent wel dat deze Widget van bij het opstarten in het geheugen zit, ook al wordt deze nooit aangeroepen. Hebt u veel Widgets die moeten opgeroepen worden dan is deze techniek zeker niet efficiënt.

Het kan dus beter.

De Widget toevoegen en verwijderen

  • Eerst en vooral, zorg ervoor dat het Canvas Panel, binnen mijnHUD, een variabele is door Is Variable (rechtsboven) aan te vinken.

  • Vervang de huidige code voor het zichtbaar/onzichtbaar maken door onderstaande code.

  • Maak een variabele WidgetRef aan van het type van de Widget (mijnWidget).
  • Is de Widget geopend dan zal deze variabele Valid zijn, anders niet. We testen dus op het Is Valid zijn van de Widget.
  • Is de variabele WidgetRef Valid dan moet deze verwijderd worden via de instructie Remove from Parent (de Parent is het Canvas van de HUD).
  • Zet vervolgens de variabel Widget Ref op niets en maak ze zo NOT Valid.
  • Is de variabele WidgetRef niet Valid dan wordt deze gecreëerd met Create Widget en sla deze vervolgens op in de variabele WidgetRef zodat deze Valid wordt.
  • Voeg de Widget toe aan het Canvas van de HUD via Add Child to Canvas. Zorg ervoor dat de canvas een variabele is, anders hebt u er geen toegang toe (we hebben dit normaal net gedaan).
  • Vervolgens Set Anchors en Set Auto Size om de Widget te positioneren.
  • Zet tenslotte, net als bij het zichtbaar/onzichtbaar maken de Input Mode en toon al dan niet de muiscursor. Let op dat u deze correct verbindt!

  • Compile, Save en Play.

Alles zou eveneens moeten werken maar nu iets efficiënter. U kunt nu de handmatig toegevoegde Widget in de HUD opnieuw verwijderen, de Widget wordt immers dynamisch, via programmeercode, toegevoegd.


Menusysteem

Ik verwijs naar onderstaande links en video’s voor een stap voor stap uitwerking. Ik geef hier de belangrijkste code.

De nodes voor het openen van een level en het verlaten en pauzeren van het programma.

Resume en Quit

De level wordt geopend en de HUD wordt verwijderd.

Pause

Merk op, er wordt eerst gekeken of de menu reeds bestaat, indien wordt die aangemaakt.

Console Commando’s

Onderstaande Console commando’s stellen de resolutie in.

Onderstaande links en video’s werken dit stap voor stap uit:

Basic Main Menu

Menusysteem (Start, Quit, Pause, Resume, Are you sure?)

Menu en submenu’s


Widget Interaction Component

Een Widget Interaction Component kunt u toevoegen, als een component, aan een Blueprint Class, bv. uw Character Class. Dit component maakt het mogelijk interactie te hebben met Widgets in 3D.

  • U voegt het Widget Interaction Component toe via Add Component van de Class.

De Widget Interaction Component komt met een hele reeks functies en variabelen om de interactie met een Widget tot stand te brengen.

Onderstaande videotutorial maakt gebruik van een Widget Interaction Component om een deur te openen met een keypad. De tutorial maakt ook gebruik van Event Dispatchers die we in een vorige tutorial besproken hebben.


Project Twin Stick Shooter – HUD

De video’s vindt u op Twin Stick Shooter with Blueprint (unrealengine.com).

Bekijk de video’s:

  • Creating a HUD with UMG
  • Character Animation Blueprint

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.