Starten met programmeren van een 3D omgeving in Unreal Engine – Eenvoudige Artificiële Intelligentie

print
Deze handleiding maakt deel uit van het programmeertraject:


Inhoud


Wat vooraf ging


Inleiding

Deze handleiding is een korte, eerste kennismaking met Artificiële Intelligentie.

Situering van deze handleiding binnen Unreal Engine


Eenvoudige AI Tracking

Tot nu toe stond onze Vijand stil, we willen het wat spannender maken door de Vijand ons te laten achtervolgen.

Hiertoe is, heel eenvoudige, Artificiële Intelligentie nodig. We moeten immers de Vijand de intelligentie geven om ons te achtervolgen (tracing).

AIController toevoegen

  • Ga in de Content Browser naar de map waar uw Blueprints staan.
  • Klik rechts om een nieuwe Blueprint Class aan te maken.
  • We willen een nieuwe klasse aanmaken gebaseerd op de klasse AIController. Deze staat niet meteen beschikbaar, u zal er moeten naar zoeken. Zoek naar AIController.

  • Selecteer AIController, klik op Select en kies een passende naam (bv. VijandAI).
  • Dubbelklik op de nieuwe Blueprint te openen.

De Viewport is leeg maar er zijn wel een aantal specifieke componenten toegevoegd zoals PathFollowingComponent.

  • Ga naar de Event Graph om te programmeren.

We wensen AI die de vijand beweegt in de richting van ons eigen karakter.

We kunnen hiertoe gebruikmaken van AI Move To.

AI Move To laat een Pawn bewegen in de richting van een Target (of een Destination) tot een Acceptance Radius bereikt wordt en stopt dan eventueel.

  • De Pawn wordt opgevraagd via Get Controlled Pawn (we moeten, zo dadelijk, nog deze AIController toekennen aan de gewenste Pawn (Vijand)).
  • De Target is ons eigen karakter dat kan worden opgevraagd via Get Player Character.
  • De andere Invoer-pins laten we standaard staan.

We gaan deze AI Move To koppelen aan een Custom Event (u ziet meteen waarom).

  • Voeg een Custom Event toe en geef het een passende naam (bv. TrackPlayer) en verbindt deze Custom Event met AI Move To.
  • We moeten bepalen om de hoeveel tijd deze Custom Event moet worden uitgevoerd. Dit kan via Set Timer by Function Name. De Function Name is de naam van onze Custom Event (vandaar de noodzaak om een Custom Event aan te maken). Time krijgt bv. de waarde 1 (1 seconde) en vink Looping aan (zodat dit iedere seconde herhaald wordt).
  • Verbind Set Timer by Function Name met Event BeginPlay.

De, heel eenvoudige, AI is klaar.

  • Compile en Save.

AIController verbinden

De aangemaakte AIController moet gekoppeld worden aan de Pawn waar deze op van toepassing is, in ons geval aan de Vijand.

  • Open de Blueprint Vijand.
  • In het Details-panel, koppel AI Controller Class aan onze aangemaakte AIController (VijandAI).

  • Compile en Save.

Nav Mesh Bounds Volume

AI kan enkel navigeren binnen een Nav Mesh Bounds Volume.

  • Voeg een Nav Mesh Bounds Volume toe vanuit het Modes-panel.

  • Schaal en plaats de Nav Mesh Bounds Volume zodat het het volledige speloppervlakte omvat (ook een beetje onder de vloer).
  • Met de P-toets kunt u de Nav Mesh zichtbaar en opnieuw onzichtbaar maken.

  • Compile en Save.

Eenvoudige Zombie AI

Bovenstaande Artificiële Intelligentie is niet meer dan een Tracking. Van zodra de Vijanden gespawned worden beginnen ze aan de Tracking van de speler.

We gaan nu iets meer, maar nog steeds heel eenvoudige, Artificiële Intelligentie toevoegen.

We willen dat de Vijand zich gedraagt als een Zombie.

Statussen

Een Zombie heeft 2 statussen:

  • Idle – de zombie doet niets en staat gewoon wat te staan.
  • Achtervolgen – de zombie jaagt op de speler. Concreet, verplaatst zich in de richting van de speler.

De Zombie gaat van status Idle naar status Achtervolgen wanneer de speler te dicht in de buurt van de Zombie komt.

De Zombie gaat van status Achtervolgen naar status Idle wanneer de speler zich opnieuw verwijderd uit de buurt van de Zombie.

Om de verschillende statussen bij te houden maken we een Enumeration aan, die alle mogelijke statussen bevat.

  • Klik met de rechtermuisknop in de gewenste folder in de Content Browser en kies voor BlueprintsEnumeration.

  • Geef het een gepaste naam (bv. ZombieAIState) en dubbelklik om de Enumeration te openen.
  • Geef de twee statussen in door te klikken op New en de Display Name in te vullen zoals hieronder.

  • Klik op Save en sluit dit venster.

AI onderdelen

Standaard moet u twee onderdelen toevoegen om Artificiële Intelligentie te implementeren.

  • Behaviour Tree – Een boomstructuur die het eigenlijke gedrag om Artificiële Intelligentie bepaalt.
  • Blackboard – de te gebruiken Keys (variabelen).

Om deze twee onderdelen toe te voegen:

  • Klik met de rechtermuisknop in de gewenste folder in de Content Browser en kies voor Artificial Intelligence.

  • Voeg een Behaviour Tree toe en geef het een gepaste naam (bv. BT_Zombie).
  • Voeg een Blackboard toe en geef het een gepaste naam (bv. BB_Zombie).

AIController

Artificiële Intelligentie heeft een AIController nodig.

We vertrekken van de reeds hierboven aangemaakte AIController.

Let op, als je heel veel zombies wilt toevoegen kunt u in plaats van de standaard AIController opteren voor de DetourCrowdAIController. de DetourCrowdAIController is een Child van de AIController uitgebreid met extra functionaliteiten om grote menigten te controleren.

Ik werk verder op de reeds aangemaakte AIController.

Hieronder ziet u de 4 bestanden die we gaan gebruiken voor onze Zombie AI. Ik heb ze in een eigen folder AI geplaatst.

De AIController wordt nu gebruikt om de gewenste Behaviour Tree en Blackboard te activeren.

  • Open de AIController, omdat we een reeds bestaande AIController gebruiken ziet u reeds de hierboven aangemaakte code staan.

  • Verbreek de link naar Set Timer by Function Name.

  • Aan Event Begin Play voeg de node Run Behavior Tree en selecteer de gewenste Behavior Tree.

  • Verbind vervolgens met de node Use Blackboard en kies de gewenste Blackboard. Let op, deze stap is strikt genomen niet nodig omdat de Behavior Tree gekoppeld wordt aan de gebruikte Blackboard maar fout is het niet en sommige tutorials voeren deze stap uit..

De volledige code van de AIController.

  • Compile en Save.

Vergeet niet dat de AIController moet worden toegevoegd aan het gewenste Character, maar dit hebben we reeds gedaan. Ik herneem nog even de relevante schermafdruk.

Blackboard

De Blackboard is de verzamelplaats van de Keys (variabelen) die u gebruikt in de Behavior Tree.

  • Open de net aangemaakte Blackboard door deze te dubbelklikken.

Er staat al standaard één Keys (SelfActor).

  • U kunt een nieuwe Keys  toevoegen met de knop New Key, vervolgens kiest u het gewenste type.

We hebben twee Keys nodig:

  • AITarget – de target van de zombie, de de speler zelf. Dit is van het type Object (en kan eventueel gespecifieerd worden als Base Class HeroCharacter in de TwinStickShooter).

  • AIState – de hierboven aangemaakte Enumeration.

  • De Keys zijn aangemaakt. Klik op Save

Behavior Tree

De Behavior Tree bevat de opbouw van de eigenlijke Artificiële Intelligentie als een boomstructuur.

Merk eerst op dat de Behavior Tree gekoppeld moet zijn aan een Blackboard. Omdat er maar één Blackboard aangemaakt is is deze koppeling automatisch gebeurd.

De Root-node staat reeds klaar.

  • Sleept u vanuit de Root-node dan hebt u de keuze uit 3 mogelijke Composites.

  • Selector – loopt van links naar rechts tussen de “subtrees” en stopt met zicht te verplaatsen wanneer een “subtree” succesvol uitgevoerd is. Nadien keert de Selector terug naar de Parent. Er kan dus maar één “subtree” uitgevoerd worden voor er terug wordt gekeerd naar de Parent.

  • Sequence – loopt van links naar rechts tussen de “subtrees” en voert alle “subtrees” uit tot een “subtree” faalt. Dan keert hij terug naar de Parent. Er kunnen dus meerdere “subtrees” uitgevoerd worden voor er terug wordt gekeerd naar de Parent.

  • Simple Parallel – laat toe dat een “Main Task” en een “Background branch” gelijktijdig uitgevoerd worden.

De AI van onze Zombie kan kiezen uit 2 statussen, we gaan dus een Selector toevoegen.

Services

Een selectie gebeurt op basis van een conditie. De zombie is Idle als de afstand tot de speler groter is dan een bepaalde afstand. De afstand tussen de speler en de zombie bepaalt dus de status van de zombie en is dus de conditie voor de Selectie.

Deze conditie kunnen we instellen met behulp van een Task. Een Service is een Task die, volgens een bepaald tijdsinterval, waarden checkt en update. Een Decorator is als een conditie en bepaalt of de conditie waaronder een Task al dan niet uitgevoerd wordt.

Omdat we de status van de zombie willen checken/instellen kiezen we voor een Service.

  • Klik op de knop New Service. Er wordt een nieuw venster geopend maar ga misschien eerst opnieuw naar de Content Browser om een passende naam te geven (bv. UpdateTarget).

Een Service wordt ieder tijdsinterval uitgevoerd. U kunt dit tijdsinterval eventueel wijzigen onder ServiceInterval (deze staat standaard op 0.5) en eventueel een afwijking (Random Deviation) instellen.

De code moet uitgevoerd worden om de zoveel tijd, het Interval, via een Tick-event dus, meer specifiek een Receive Tick AI-event.

  • Overschrijf de Event Receive Tick AI. U vindt deze bij de Functions.

We schrijven nu een stukje code dat bepaalt of de afstand tussen de locatie van de zombie (de AI Controlled Pawn) en de locatie van de speler kleiner is dan een waarde bepaald door de variabele Perception Distance. De ^2 zorgt voor een nauwkeurigere berekening.

Als de zombie binnen de gewenste afstand is moet zijn status gewijzigd worden en moet de locatie van de actor, die hij moet achtervolgen, bepaald worden. Daartoe hebben we Blackboard-Keys aangemaakt.

  • We gaan hier nu ook variabelen (AITarget en AIState, dit zijn toevallig dezelfde namen als de Keys van de Blackboard maar dit hoeft niet zo te zijn) aanmaken van het type Blackboard Key Selector.

  • Zorg ervoor dat alle variabelen Instace Editable zijn (oogje open)!

De waarde van deze Blackboard Key Selector-variabelen zetten we via de node Set Blackboard Value as en kies het gewenste type (Object voor AITarget).

  • Indien ons Character zich binnen de gewenste afstand van de zombie bevindt moet ons Character toegekend worden als AITarget van de zombie.

  • Vervolgens moet de status van de zombie op “Achtervolgen” worden gezet. We gebruiken hiervoor de aangemaakte Enumeration. U kunt de waarden van een Enumeration vinden door te zoeken naar Literal Enum gevolgd door de naam van de Enumeration.

  • De volledige code voor als de speler binnen het bereik van de zombie is:

  • Werk nu analoog de code uit voor als ons Character niet binnen het bereik is van de zombie (merk op dat de AITarget leeg is).

  • Compile en Save.

Service toevoegen aan de Behavior Tree

Nu we de Service gemaakt hebben gaan we deze toekennen aan de Behavior Tree.

  • Open de Behavior Tree.
  • Klik met de rechtermuisknop ingedrukt op de Selector en kies voor Add Service, selecteer vervolgens de net aangemaakte Service (Update Target).

  • U kunt nu de Service aanklikken en in het Details-panel de gewenste waarde geven voor de variabelen, hier worden ook de Blackboard Keys toegewezen aan de hiertoe voorziene variabele van de Service. Ziet u een variabele niet dan hebt u wellicht het oogje (Instance Editable) niet geopend voor deze variabele binnen de Service. U kunt ook hier nog eventueel het Interval waarin de Service wordt uitgevoerd bepalen.

Tasks

We gaan nu de twee Tasks (één of meerdere opeenvolgende acties die moeten worden uitgevoerd) toevoegen die de zombie kan uitvoeren.

  • De eerste Tasks is Wait.
  • De tweede Task is Move To.

En we hebben geluk, deze basistaken zijn reeds voorzien door Unreal Engine, we hoeven ze dus niet zelf te schrijven (wat natuurlijk altijd kan indien het nodig zou zijn).

  • Sleep vanuit de Selector en zoek naar de Task Wait.

  • De Task Wait is toegevoegd. Wijzig eventueel eigenschappen zoals Wait Time.

  • Voor de tweede taak zoekt u naar Move To.

  • De Task Move To is toegevoegd, wijzig eventueel de eigenschappen.

Decorator

Een Decorator is een conditie die u kunt toevoegen en die bepaalt onder welke conditie de Task moet worden uitgevoerd.

Zo moet de Task Wait uitgevoerd worden als de Blackboard AIState de waarde “Idle” heeft.

  • Klik rechts op de Task Wait en kies voor Add DecoratorBlackboard (merk dat u nog tal van andere opties hebt).

  • Stel de eigenschappen in zoals hieronder:

Observer Aborts = Self (dit wil zeggen dat als de taak beëindigd is (aborded), de taak, en eventuele sub-taken beëindigd worden maar niet de taken rechts, in de boomstructuur, van deze taak.

Key Query = Is Equal to

Key Value = Idle

Blackboard Key = AIState

De Taks Move To moet uitgevoerd worden als de Blackboard AIState de waarde “Achtervolgen” heeft.

  • Voeg net als hierboven zo’n Decorator toe.

  • Eventueel kunt u nog de Node Names wijzigen om het wat te verduidelijken in de Behavior Tree.

Hiermee is onze heel eenvoudige zombie AI afgewerkt.

  • Save en test uit.

Chase and Patrol AI

Bekijk onderstaande Behavior Tree en probeer te begrijpen wat er gebeurt.

Om dit uit te werken verwijs ik u door naar de officiële help, daar wordt deze AI stap voor stap uitgewerkt.

Artificiële Intelligentie is een cursus op zich en is niet voor ieder project belangrijk. Wie zich verder wil verdiepen raad ik sterk aan te starten met deze officiële Unreal Engine Learning cursus.


Project Twin Stick Shooter

Building the Enemy Character

Building the Projectile & Weapon

Weapon Firing Behavior


Masterclasses

Ik heb lang moeten zoeken naar goede inleidende videotutorials over Artificiële Intelligentie. Niet omdat er niet veel te vinden zijn, maar er zijn weinig goede te vinden (of ik heb ze nog niet gevonden).

Onderstaande video kan ik wel aanraden.

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.