Steering Behaviours

https://github.com/GandhiGames/autonomous_agents

What is it?

A repository of steering behaviours that will help you create autonomously moving game characters. Behaviours include alignment, avoidance, cohesion, pursue, flee, path following, hiding, separation, wall avoidance, and wandering.

See this link for more information on the topic of steering behaviours.

How do you use it?

1. Add your model or sprite to the scene. For this example I am using a sprite from here.

Ship sprite added to scene view in Unity.

2. Add the Entity Script to your new character (this will also add the BehaviourManager script). In the entity script you can edit:

  • The max velocity: higher numbers mean the character can move faster.
  • The mass of the object: higher objects require a larger force to move at the same speed. Be careful not to set the mass too high as they can cause behaviours to not be able to move the character.
  • The sight radius: this determines how far the character can see. This is used when applying different behaviours. For example if you are using the Alignment behaviour the character will only align its heading with characters that are within this radius.
  • Smoothing: this averages a characters movement over a number of time steps. This is useful if the force of the behaviour causes your character to become “jittery”.
autonomous_agents_screenshot_2
Entity script added to Spaceship Gameobject.

3. You are now ready to add any behaviour scripts of your choosing. For this example, I want my ship to avoid obstacles (asteroids in this case) and to wander so I have added the Obstacle Avoidance, Wander and Separation (helps to steer the spaceship away from asteroids that are not directly in front).

autonomous_agents_screenshot_3
Wander, seperation, and wall avoidance behaviours added to agent.

4. The last step is to adjust the behaviours weights. The weight is a multiplier applied to the force. You should set higher weights to higher priority behaviours. I want to ensure my spaceship knows that avoiding obstacles is more important than wandering so I have set the weight for obstacle avoidance to 30 and I have left Wander at 10 (the default weight). Sometimes trial and error is necessary to select the correct weights for behaviours.

The ship will wander around the scene and avoid the asteroids.

Now I have a ship that navigates around the environment and avoid asteroids. Hopefully this will show you how easy it is to implement the behaviours now you can create something a bit more interesting!

Creating Your Own Behaviour

It is also easy to create your own behaviours. For the purposes of this example I’ll be adding a Flee behaviour. I want to include an enemy spaceship that flees from the player. The actual implementation of fleeing behaviour is very simple however it showcases how to extend the scripts.

1.Create a new script. I’ve called mine Flee.

Flee.cs
using UnityEngine;
using System.Collections;
namespace Automation
{
public class Flee : MonoBehaviour
{
}
}

I’ve added the class to the Automation namespace (all classes in this project are part of that namespace to keep them separate from your own project files).

2. Inherit from AIBehaviour. This is the base class for individual behaviours.

Flee.cs
public class Flee : AIBehaviour

AIBehaviour provides helper methods to retrieve other characters that are in sight range. It also provides access to tags that are used in the project. All behaviours should inherit from this class as the BehaviourManager gets all instances of AIBehaviour when applying a force.

If you try to build the project now you’ll encounter an error: “Automation.yourclassname does not implement inherited abstract member Automation.AIBehaviour.GetForce()”, this leads us to the next step.

3. Implement GetForce() (surprise surprise)

This is where we place our behaviour code. We want to return a Vector2, which is the force that will be applied to our character.

Flee.cs
using UnityEngine;
using System.Collections;
namespace Automation
{
public class Flee : AIBehaviour
{
private static readonly string SCRIPT_NAME = typeof(Flee).Name;

public override Vector2 GetForce ()
{
var player = GetEntityInSight (entity.SightRadius, PLAYER_TAG_NAME, SCRIPT_NAME, LOGGING_ENABLED);

if (!player)
{
return Vector2.zero;
}

return transform.position - player.transform.position;
}
}
}

This simply attempts to find any objects with the tag “Player” (set in AIBehaviour) that are in its sight range (also provided by AIBehaviour). If the player is found then a force steering away from the player is returned.

Now all I have to do is ensure that the player has the correct tag and any objects with this script attached will flee when the player enters its sight range.

Behaviour Overview

Class Action
Alignment.cs Aligns characters heading with those of other characters in its sight range. Use this to keep a group of characters heading in the same direction.
AvoidPlayer.cs Attempts to keep an object with the player tag out of the characters sight radius.
AvoidProjectile.cs Attempts to keep an object with the projectile tag out of the characters sight radius.
Cohesion.cs Moves the character towards the centre of the group of characters within its sight range. Use this to keep a group of characters together.
Encircle.cs Creates a circle around the player. Enable “Tight Circle” on the script to enable the character to swarm closely to the player.
Flee.cs Moves character away from player when player is in sight range.
FollowPath.cs Moves the character towards a series of waypoints. Once a waypoint is reached the character seeks to the next. Use the waypoint object in the Resources folder to set a waypoint on screen (ensure you set the waypoint number on the attach script).
GravitationalPull.cs With this script attached any object with the black hole tag will pull the character towards it and therefore act as a black hole.
Hide.cs Attempts to position the character so that an obstacle is between the character and the player.
PursuePlayer.cs Attempts to head off the player. The character does not just seek to the player’s position but takes into account the players heading.
Separation.cs Steers the character away from other characters in its sight range. Use this to keep characters apart.
Wander.cs Makes the character wander through the environment.
WallAvoidance.cs Steers the character to avoid collisions with walls or obstacles. Useful when combined with other steering behaviours.

Combining Behaviours

Complex interactions can be created by combining different behaviours. For example, in the demo scene, the first example “Flock” is a type of group behaviour. The character takes into consideration the movement of the other characters within its sight range. Flocking is achieved by adding three separate behaviours to the entity: separation, cohesion, and alignment. This is a good example of how combining individual behaviours can produce complex group behaviour.

As always, thank you for reading 🙂