Wednesday, 11 June 2014

Prototype - Enemies Functionality

At least I can work on enemies. This topic will be big so I will try to move slowly. 

What I want to create first is just some AI moving to me and attacking. I don't have any experience using UE4 AI features so don't count on my solutions. 

This post will be about AI and Behavior Trees:
  • Main AI class,
  • Navmesh,
  • Behavior Tree (find target, move, attack, if you can't attach search for good spot)
I won't be doing any spawn system now, but later on I will need some spawn manager. I wan to do them first to learn how to use UE4 AI systems.

Spawn Point 
Player won't be able to move so we will create some routes near player.

Create new blueprint and extend from TargetPoint name it Target

Create new blueprint and extend from TargetPoint name it SpawnPoint.
Open SpawnPoint and add those variables:

  • IsBusy: bool, 
  • Target: our created Target
Those variables should be editable. Place them on level and assign Targets to SpawnPoints.

Main AI Character Class and Controller Class
Basically try to always focus on object oriented "blueprinting". I will create main classes that will have core functions, and my enemies will extend from them.

Create new blueprint, extend from AIController name it AI_MainController.
Create new blueprint, extend from Character and name it: AI_MainPawn.

Open AI_MainPawn and create couple of variables:
  • Health (float)
  • Damage_Max (int),
  • Damage_Min (int),
  • RateOfFire (float),
  • CurrentSpawnPoint (our SpawnPoint),
  • HasTarget (bool),
All variables should be editable.

Open Components and add Scene Component, name it: StartTrace and move it forward to cylinder component like here:

Select CapsuleComponent and change Collisions to Custom and block Visibility. Disable HiddenInGame as well. (for collision do the same for MyCharacter - it's needed to get proper traces to our player)
Select CharacterMovement and enable Use RVOAvoidance and set Weight to 0.5. This will cause AI to avoid others AIs. Will be useful.

Still in AI_MainPawn, open Graph and Create new functions:
  • MyAIMoveTo, (inputs: "Target" type Actor)
    Add AIMoveTo block:

  • MyAIStop,
    Add StopMovement
    We won't be using those functions now but I've a feeling that we will need them later.


  • MyAIAttack (inputs: "Target" type Actor)
    Add print function just to know that actor is attacking.
Now go to Event Graph and add Begin Play event: spawn default controller and set IsBusy for Current Spawn Point. So later we won't be spawning anything in that spawnpoint before killing this enemy.
Go to defaults and change Controller Class from AIController to AI_MainController.
That's all what's needed for Pawn and Controller. Let's move forward.

Blackboard Data - Data Asset
Create new DataAsset with type BlackboardData, name it MainAIData.
Add Keys:
  • CanAttack - Type_Bool,
  • Target - Type_Vector,
  • SelfActor - Type_Object
  • ReAttackTime - Type_Float.
Close MainAIData. 

Creating new Tasks
Create new Task and name it PickLocation.
Open it. And create something like this:
What we are doing here:
  • Event Receive Execute is something like Begin Play - when this task will be executed from Behavior Tree (which we don't have yet) this will popup,
  • We are casting to our classes,
  • We are picking location from SpawnPoint to Target, (RandomFloat means from 30% to 100% of the length)
  • Location is assigned to our Blackboard data asset, so it can be readable by Behavior Tree,
  • Finish Execute is telling Behavior Tree that this task is completed,
Create another Task and name it Attack.
This will just fire our MyAIAttack function from our MainAIPawn.

Create another Task and name it CheckIfWeCanAttack. Open it and create something like this:
This looks complicated but it's easy:
  • We are doing trace from StartTrace to Player,
  • If we hit our Player then we can change CanAttack bool from Blackboard Data Asset,
  • If we won't hit Player then pick location from AIPawn to Player - so it will try to come more near player. We are assigning Target vector and CanAttack bool as well,
Behavior Tree
Now open Editor Properties go to Experimental and enable Behavior Tree Editor. Create new Behavior Tree and name it MainAIBTree.
Open it. This is my Behavior Tree:
When adding sequences or selections you can add Services and Decorations. You can add Blackboard data as well:
Behavior Tree editor isn't complicated take some time and try to create the same Tree as I have created. Just experiment!

There is one problem (I have it) when you close your editor and open it again you will need to add your custom Tasks to Tree again. (Here's the Bug)

Test in game.
Open level blueprint and create this test spawning function:
Before you lunch you need to add Navigation Bounds volume into the level and scale it to fit your scene. You can press "P" to show the navigation and in game you can use "show navigation". If nothing appear you should restart the editor and place it again.


Here's how it's looking (sorry for the audio;/):

I know that they are just cylinders, but trust me - core functionality is there :)
In next post I will create robotic spider that will use that system, he will shoot you and you will be able to shoot him as well.