Skip to content

matieme/GOAP

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

21 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Maintenance Made With Unity GitHub

GOAP

Goal Oriented Action Planning AI in Unity

Introduction

For the GOAP implementation, I used a Unity template third-person shooter type game that had waves of enemies. There are two classes of enemies which the player have to face, one of them is a Teddy Bear which has the ability to attack melee and range and the other enemy is a Stuffed Elephant that acts as a seeker and attack only in melee. In addition to GOAP, a node system was created where the enemies move through using A* path finding algorithm.

Plan and Objective

The objective of each entity is to kill the player, to achieve this each entity will have a set of actions to perform and will perform them according to this points:

  • Weight of the action
  • Previous action
  • Effect of the previous action in the current state of the game

Zombunny Enemy

Zombunny

This enemy will have the following set of actions:

  • Shooting
  • PositionToShoot
  • Recharge
  • Grab the battery
  • Confused fight
  • Rush
  • GetHealed

Hellephant Enemy

Elephant

This enemy will have the following set of actions:

  • Melee
  • Rush
  • GetHealed

Preconditions and Effects

Description of preconditions and effects

Preconditions Effects
battery The amount of battery charge that the entity has, with more than one charge it can shoot
life The amount of life the entity has
isAttacking Check if the entity is in attack state
isLaserLoaded Before firing, the entity must recharge the laser, this bool is set true when the laser is charged
isInMeleeRange Check if the player is within the melee attack range
batteryNearby Check if there is any battery within the search range
medikitNearby Check if there is any medikit within the search range
playerIsAlive Check if the player has life above 0
haveCriticalLife This value is marked when the life of the entity is below a critical value (configurable)

Implementation

Each entity creates its initial state and its GOAL which is passed to GOAP along with the list of actions and the heuristics so that it can put together the plan to follow. Once the plan is drawn up, the entity is only responsible for executing those corresponding states and rechecking according to its current state which is the best way to go.

Actions

Actions are made up of an interface that defines their name, cost, preconditions, and effects.

public interface IGOAPAction
{
     GOAPActionKeyEnum Name { get; }
     float Cost { get; }
     IEnumerable<KeyValuePair<GOAPKeyEnum, Func<object, bool>>> Preconditions { get; }
     IEnumerable<KeyValuePair<GOAPKeyEnum, Func<object, object>>> Effects { get; }
}

The concrete implementation will have the implementation of the interface and setters for the preconditions, effects and costs since we need them to create the actions

States

Each state is represented by a variable that affects the entity directly, whether it is internal to the entity or the state of the game.

There are two game state variables that will affect the entities:

Medikit

The medikit will heal enemies if they lack life and are close to it.

Battery

On the other hand, the batteries give some entities the possibility of being able to shoot.

However the entities also have internal variables that the controls directly, this is an example of the initial state of one of the entities:

var initialState = new Map<GOAPKeyEnum, object>()
{
    { GOAPKeyEnum.life , Life},
    { GOAPKeyEnum.isAttacking , false},
    { GOAPKeyEnum.isInMeleeRange , IsInMeleeRange() },
    { GOAPKeyEnum.medikitNearby , IsMedikitNearby() },
    { GOAPKeyEnum.playerIsAlive , IsPlayerAlive() },
    { GOAPKeyEnum.haveCriticalLife , IsInCriticalLife() }
};

This state is a Map or Dictionary that contains as a key an Enum representing the type of variable or condition, and as a value an object which can be of any type indicating the value of that condition to compare later in the actions.

GOAP State

Is in charge of checking if the current state meets the GOAL condition and once it changes the variables of the global state of the game with the effects of each action. It implements the IGraphNode interface since this class works as a node to search for the best possible path to GOAL.

GOAP planner

Is in charge of creating the current state and executing its effects on the GOAPState.