Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Unity 2018 Artificial Intelligence Cookbook

You're reading from   Unity 2018 Artificial Intelligence Cookbook Over 90 recipes to build and customize AI entities for your games with Unity

Arrow left icon
Product type Paperback
Published in Aug 2018
Publisher
ISBN-13 9781788626170
Length 334 pages
Edition 2nd Edition
Languages
Tools
Arrow right icon
Authors (2):
Arrow left icon
Jorge Palacios Jorge Palacios
Author Profile Icon Jorge Palacios
Jorge Palacios
Jorge Elieser P Garrido Jorge Elieser P Garrido
Author Profile Icon Jorge Elieser P Garrido
Jorge Elieser P Garrido
Arrow right icon
View More author details
Toc

Table of Contents (12) Chapters Close

Preface 1. Behaviors - Intelligent Movement 2. Navigation FREE CHAPTER 3. Decision Making 4. The New NavMesh API 5. Coordination and Tactics 6. Agent Awareness 7. Board Games and Applied Search AI 8. Learning Techniques 9. Procedural Content Generation 10. Miscellaneous 11. Other Books You May Enjoy

Creating a jump system

Imagine that we're developing a cool action game where the player is capable of escaping using cliffs and rooftops. In that case, the enemies need to be able to chase the player and be smart enough to discern whether to take the jump and gauge how to do it.

Getting ready

We need to create a basic matching-velocity algorithm and the notion of jump pads and landing pads in order to emulate velocity math so that we can reach them.

The following is the code for the VelocityMatch behavior:

using UnityEngine; 
using System.Collections; 
 
public class VelocityMatch : AgentBehaviour { 
     
    public float timeToTarget = 0.1f; 
 
    public override Steering GetSteering() 
    { 
        Steering steering = new Steering(); 
        steering.linear = target.GetComponent<Agent>().velocity - agent.velocity; 
        steering.linear /= timeToTarget; 
        if (steering.linear.magnitude > agent.maxAccel) 
            steering.linear = steering.linear.normalized * agent.maxAccel; 
 
        steering.angular = 0.0f; 
        return steering; 
    } 
} 

Also, it's important to create a data type called JumpPoint:

using UnityEngine; 
using System.Collections; 
 
public class JumpPoint  
{ 
    public Vector3 jumpLocation; 
    public Vector3 landingLocation; 
 
    //The change in position from jump to landing 
    public Vector3 deltaPosition; 
 
    public JumpPoint () : this (Vector3.zero, Vector3.zero) 
    { 
    } 
 
    public JumpPoint(Vector3 a, Vector3 b) 
    { 
        this.jumpLocation = a; 
        this.landingLocation = b; 
        this.deltaPosition = this.landingLocation - this.jumpLocation; 
    } 
} 

How to do it...

  1. Create the Jump script along with its member variables:
using UnityEngine; 
using System.Collections; 
 
public class Jump : VelocityMatch 
{ 
    public JumpPoint jumpPoint; 
    public float maxYVelocity; 
    public Vector3 gravity = new Vector3(0, -9.8f, 0); 
    bool canAchieve = false; 
}

  1. Implement the SetJumpPoint function:
public void SetJumpPoint(Transform jumpPad, Transform landingPad) 
{ 
    jumpPoint = new JumpPoint(jumpPad.position, landingPad.position); 
} 
  1. Add a function to calculate the target:
protected void CalculateTarget() 
{ 
    target = new GameObject(); 
    target.AddComponent<Agent>(); 
    target.transform.position = jumpPoint.jumpLocation; 
    //Calculate the first jump time 
    float sqrtTerm = Mathf.Sqrt(2f * gravity.y * jumpPoint.deltaPosition.y + maxYVelocity * agent.maxSpeed); 
    float time = (maxYVelocity - sqrtTerm) / gravity.y; 
    //Check if we can use it, otherwise try the other time 
    if (!CheckJumpTime(time)) 
    { 
        time = (maxYVelocity + sqrtTerm) / gravity.y; 
    } 
} 
  1. Implement the CheckJumpTime function, to decide whether it's worth taking the jump:
private bool CheckJumpTime(float time) 
{ 
    //Calculate the planar speed 
    float vx = jumpPoint.deltaPosition.x / time; 
    float vz = jumpPoint.deltaPosition.z / time; 
    float speedSq = vx * vx + vz * vz; 
    //Check it to see if we have a valid solution 
    if (speedSq < agent.maxSpeed * agent.maxSpeed) 
    { 
        target.GetComponent<Agent>().velocity = new Vector3(vx, 0f, vz); 
        canAchieve = true; 
        return true; 
    } 
    return false; 
}

  1. Finally, define the GetSteering function:
public override Steering GetSteering() 
{ 
    Steering steering = new Steering(); 
    if (target == null) 
    { 
        CalculateTarget(); 
    } 
    if (!canAchieve) 
    { 
        return steering; 
    } 
    //Check if we've hit the jump point 
    if (Mathf.Approximately((transform.position - target.transform.position).magnitude, 0f) && 
        Mathf.Approximately((agent.velocity - target.GetComponent<Agent>().velocity).magnitude, 0f)) 
    { 
        // call a jump method based on the Projectile behaviour 
        return steering; 
    } 
    return base.GetSteering(); 
} 

How it works...

The algorithm takes into account the agent's velocity and calculates whether it can reach the landing pad or not. If it judges that the agent can, it tries to match the vertical velocity while seeking the landing pad's position.

lock icon The rest of the chapter is locked
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime