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

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(); 
}