Unity 2018 Artificial Intelligence Cookbook(Second Edition)
上QQ阅读APP看书,第一时间看更新

How to do it...

We need to create three classes, Steering, AgentBehaviour, and Agent:

  1. Steering serves as a custom data type for storing the movement and rotation of the agent:
using UnityEngine; 
public class Steering 
{ 
  public float angular; 
  public Vector3 linear; 
  public Steering () 
  { 
    angular = 0.0f; 
    linear = new Vector3(); 
  } 
} 
  1. AgentBehaviour is the template class for most of the behaviors covered in this chapter:
using UnityEngine; 
public class AgentBehaviour : MonoBehaviour 
{ 
  public GameObject target; 
  protected Agent agent; 
  public virtual void Awake () 
  { 
    agent = gameObject.GetComponent<Agent>(); 
  } 
  public virtual void Update () 
  { 
      agent.SetSteering(GetSteering()); 
  } 
  public virtual Steering GetSteering () 
  { 
    return new Steering(); 
  } 
} 
  1. Finally, Agent is the main component, and it makes use of behaviors in order to create intelligent movement. Create the file and its bare bones:
using UnityEngine; 
using System.Collections; 
public class Agent : MonoBehaviour 
{ 
    public float maxSpeed; 
    public float maxAccel; 
    public float orientation; 
    public float rotation; 
    public Vector3 velocity; 
    protected Steering steering; 
    void Start () 
    { 
        velocity = Vector3.zero; 
        steering = new Steering(); 
    } 
    public void SetSteering (Steering steering) 
    { 
        this.steering = steering; 
    } 
} 
  1. Next, we code the Update function, which handles the movement according to the current value:
public virtual void Update () 
{ 
    Vector3 displacement = velocity * Time.deltaTime; 
    orientation += rotation * Time.deltaTime; 
    // we need to limit the orientation values 
    // to be in the range (0 - 360) 
    if (orientation < 0.0f) 
        orientation += 360.0f; 
    else if (orientation > 360.0f) 
        orientation -= 360.0f; 
    transform.Translate(displacement, Space.World); 
    transform.rotation = new Quaternion(); 
    transform.Rotate(Vector3.up, orientation); 
} 
  1. Finally, we implement the LateUpdate function, which takes care of updating the steering for the next frame according to the current frame's calculations:
public virtual void LateUpdate () 
{ 
    velocity += steering.linear * Time.deltaTime; 
    rotation += steering.angular * Time.deltaTime; 
    if (velocity.magnitude > maxSpeed) 
    { 
        velocity.Normalize(); 
        velocity = velocity * maxSpeed; 
    } 
    if (steering.angular == 0.0f) 
    { 
        rotation = 0.0f; 
    } 
    if (steering.linear.sqrMagnitude == 0.0f) 
    { 
        velocity = Vector3.zero; 
    } 
    steering = new Steering(); 
}