Unity人工智能学习—确定性AI算法之追踪算法四

来源:互联网 发布:php面向对象接口 编辑:程序博客网 时间:2024/06/01 08:47

在追踪算法三中已经提到了它的缺陷之处:到达目标点的时候并不会马上停下来,而是不停的来回穿梭在目标点。这一篇其实就是第三篇优化这个缺陷的算法。它的效果图如图所示:

它的核心算法代码如下:

  Vector2 Track_AIAdvancedArrive()    {        Vector2 toTarget = AimTarget.transform.position - pObject.transform.position;//这里我偷懒了,最好还是采用明确的转换到2维向量        float dist = PointDistance_2D(toTarget.x, toTarget.y);        //让它大于10而不是0是为了在导弹到达目标位置时候停止下来不抖动        if (dist > 10)        {            Vector2 DesiredVelocity = toTarget / DecelerationTweaker;            return DesiredVelocity - pObject.Velocity;        }        return Vector2.zero;    }
多次测试得到代码里面的dist在大于10的时候是最好的,太小了比如说1回使得抖动太大,太大了回根本到不了目标点。在目标很远的时候这个算法和算法三是一样的,只有当接近目标的时候时,才有减速的效果。

完整的代码如下:

using UnityEngine;using System.Collections;using UnityEngine.UI;public class AIArrivedTargetPos : MonoBehaviour{    public Image AimTarget;    public float m_weight;//最小的追踪向量改变率,这个值越大转向越快,同时也会导致更大的抖动    public PlayObject pObject;    private float DecelerationTweaker = 0.9f;//这个值越大到达目标就越慢,而且越小跟踪越不准    // Use this for initialization    void Start()    {    }    // Update is called once per frame    void Update()    {        SetAimTargetPos();        Move();    }    void Move()    {        Vector2 moveVec = Track_AIAdvancedArrive();        //加了一下修正代码就会使得导弹平滑的转身而不是生硬的直接转身        float length = PointDistance_2D(moveVec.x,moveVec.y);        //防止为0的时候计算溢出        if (length != 0)        {            pObject.Velocity += m_weight * moveVec / length;            pObject.Move(1, true);        }        else        {          //  pObject.Velocity = Vector2.zero;        }    }    void SetAimTargetPos()    {        if(Input.GetMouseButton(0))        {            AimTarget.transform.position = Input.mousePosition;        }    }    /// <summary>    /// 计算从零点到这个点的距离    /// </summary>    /// <param name="x"></param>    /// <param name="y"></param>    /// <returns></returns>    float PointDistance_2D(float x, float y)    {        float result = Mathf.Sqrt(x * x + y * y);        return result;    }    Vector2 Track_AIAdvancedArrive()    {        Vector2 toTarget = AimTarget.transform.position - pObject.transform.position;//这里我偷懒了,最好还是采用明确的转换到2维向量        float dist = PointDistance_2D(toTarget.x, toTarget.y);        //让它大于10而不是0是为了在导弹到达目标位置时候停止下来不抖动        if (dist > 10)        {            Vector2 DesiredVelocity = toTarget / DecelerationTweaker;            return DesiredVelocity - pObject.Velocity;        }        return Vector2.zero;    }}


0 0
原创粉丝点击