AI Arrive行为原理与代码

若水GIF截图_2016年12月11日16点13分14秒.gif

]( http://upload-images.jianshu.io/upload_images/3975796-0ffa152c43ce6ba6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

  • 整个黑圈表示的就是减速范围,而此时的速度velocity向量我们可以获取,toTarget向量也可以获得,我们此时要让他有一个减速效果,那就给他一个反向的toTarget的作用力就好。上代码
    public class ArriveSecond : MonoBehaviour
    {
    //目标位置
    public Transform targetPosition;
    //减速半径
    float distance;
    //速度向量(方向,大小)
    public Vector3 velocity;
    void Start()
    {
    distance = 2f;
    }
    void Update()
    {
    //物体到目标的向量
    Vector3 toTarget = targetPosition.position - transform.position;
    if (Vector3.Distance(transform.position, targetPosition.position) > distance)
    {
    //当物体没有进入减速半径的时候,物体朝向目标移动
    //Seek行为
    Vector3 controlForce = (toTarget - velocity).normalized * velocity.magnitude;
    velocity += controlForce * Time.deltaTime;
    }
    else if (Vector3.Distance(transform.position, targetPosition.position) < distance && Vector3.Distance(transform.position, targetPosition.position) > 0.001f)
    {
    //当物体进入到减速半径后,给物体一个方向的toTarget的力
    //当物体里目标越近那这个减速的力就越小
    Vector3 controlForce = -toTarget.normalized * velocity.magnitude * (Vector3.Distance(transform.position, targetPosition.position) / distance);
    velocity += controlForce * Time.deltaTime;
    }
    else
    {
    //当物体到达目标点后我们,让他的速度变为0
    velocity = Vector3.zero;
    }
    if (velocity.magnitude > 0.1f)
    {
    //目标转向
    transform.forward = Vector3.Lerp(transform.forward, velocity, Time.deltaTime);
    }
    transform.position += velocity * Time.deltaTime;
    }
    }
    但是这种方法有个BUG,当物体到达目标点位的时候他不会自己主动去停止,需要我们加代码去控制,在我上边的代码中有写到

第二种方法

AI Arrive行为原理与代码_第1张图片
Paste_Image.png

这种方法有点难理解

  • 减小当前速度,就是 -velocity
  • 控制物体最终还是朝向物体移动 controForce
    最后把这两个力相加也就是controlForce-velocity就得到我们想要的那个控制速度的最终方向
    public class ArrivefIRST : MonoBehaviour
    {
    //目标位置
    public Transform targetPosition;
    //减速半径
    float distance;
    //速度向量(方向,大小)
    public Vector3 velocity;
    void Start()
    {
    distance = 2f;
    }
    void Update()
    {
    //物体到目标的向量
    Vector3 toTarget = targetPosition.position - transform.position;
    //操纵力,改变物体的速度方向
    Vector3 controlForce = (toTarget - velocity).normalized * velocity.magnitude;
    if (Vector3.Distance(transform.position, targetPosition.position) > distance)
    {
    //当物体没有进入减速半径的时候,物体朝向目标移动
    //Seek行为
    velocity += controlForce * Time.deltaTime;
    }
    else
    {
    //当进入减速半径的时候物体开始减速,并最终到达目标点
    velocity += (controlForce - velocity) * Time.deltaTime;
    }
    if (velocity.magnitude > 0.1f)
    {
    //目标转向
    transform.forward = Vector3.Lerp(transform.forward, velocity, Time.deltaTime);
    }
    transform.position += velocity * Time.deltaTime;
    }
    }
    两种方法的对比我们可以看到,第一种只是给他一个减速的力,如果当目标物体过近,就可能不能停在目标点位,让他在进入减速区域减速,而第二种我们就是让他除了减速还给他一个向目标点移动的力,两个种力的结合让物体可以更好的打到目标点,所以我们经常采取第二种方法。
    下边我们看下,这个是第二种方法


    若水GIF截图_2016年12月11日16点6分49秒.gif

这个是第一种方法

若水GIF截图_2016年12月11日16点16分12秒.gif

你可能感兴趣的:(AI Arrive行为原理与代码)