AI Arrive行为原理与代码

作者: LeoYangXD | 来源:发表于2016-12-11 16:22 被阅读16次
    若水GIF截图_2016年12月11日16点13分14秒.gif
    ](https://img.haomeiwen.com/i3975796/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,当物体到达目标点位的时候他不会自己主动去停止,需要我们加代码去控制,在我上边的代码中有写到

    第二种方法

    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行为原理与代码

        本文链接:https://www.haomeiwen.com/subject/dikpmttx.html