Book Image

Unity 2018 Artificial Intelligence Cookbook - Second Edition

By : Jorge Palacios
Book Image

Unity 2018 Artificial Intelligence Cookbook - Second Edition

By: Jorge Palacios

Overview of this book

Interactive and engaging games come with intelligent enemies, and this intellectual behavior is combined with a variety of techniques collectively referred to as Artificial Intelligence. Exploring Unity's API, or its built-in features, allows limitless possibilities when it comes to creating your game's worlds and characters. This cookbook covers both essential and niche techniques to help you take your AI programming to the next level. To start with, you’ll quickly run through the essential building blocks of working with an agent, programming movement, and navigation in a game environment, followed by improving your agent's decision-making and coordination mechanisms – all through hands-on examples using easily customizable techniques. You’ll then discover how to emulate the vision and hearing capabilities of your agent for natural and humanlike AI behavior, and later improve the agents with the help of graphs. This book also covers the new navigational mesh with improved AI and pathfinding tools introduced in the Unity 2018 update. You’ll empower your AI with decision-making functions by programming simple board games, such as tic-tac-toe and checkers, and orchestrate agent coordination to get your AIs working together as one. By the end of this book, you’ll have gained expertise in AI programming and developed creative and interactive games.
Table of Contents (12 chapters)

Targeting a projectile

Just as it's important to predict a projectile's landing point, it's also important to develop intelligent agents capable of aiming projectiles. It wouldn't be fun if our rugby-player agents weren't capable of passing the ball.

Getting ready

Just as in the previous recipe, we only need to expand the Projectile class.

How to do it...

Thanks to our previous hard work, this recipe is a real piece of cake:

  1. Create the GetFireDirection function:
public static Vector3 GetFireDirection (Vector3 startPos, Vector3 endPos, float speed) 
{ 
    // body 
}

  1. Solve the corresponding quadratic equation:
Vector3 direction = Vector3.zero; 
Vector3 delta = endPos - startPos; 
float a = Vector3.Dot(Physics.gravity, Physics.gravity); 
float b = -4 * (Vector3.Dot(Physics.gravity, delta) + speed * speed); 
float c = 4 * Vector3.Dot(delta, delta); 
if (4 * a * c > b * b) 
    return direction; 
float time0 = Mathf.Sqrt((-b + Mathf.Sqrt(b * b - 4 * a * c)) / (2*a)); 
float time1 = Mathf.Sqrt((-b - Mathf.Sqrt(b * b - 4 * a * c)) / (2*a)); 
  1. If shooting the projectile is feasible given the parameters, return a non-zero direction vector:
float time; 
if (time0 < 0.0f) 
{ 
    if (time1 < 0) 
        return direction; 
    time = time1; 
} 
else 
{ 
    if (time1 < 0) 
        time = time0; 
    else 
        time = Mathf.Min(time0, time1); 
} 
direction = 2 * delta - Physics.gravity * (time * time); 
direction = direction / (2 * speed * time); 
return direction; 

How it works...

Given a fixed speed, we solve the corresponding quadratic equation in order to obtain the desired direction (when at least a single one-time value is available), which doesn't need to be normalized because we already normalized the vector while setting up the projectile.

There's more...

Take account of the fact that we are returning a blank direction when the time is negative; it means that the speed is not sufficient. One way to overcome this is to define a function that tests different speeds and then shoot the projectile.

Another relevant improvement is to add an extra parameter of the type bool for those cases when we have two valid times (which means two possible arcs), and we need to shoot over an obstacle such as a wall:

if (isWall) 
    time = Mathf.Max(time0, time1); 
else 
    time = Mathf.Min(time0, time1);