簡體   English   中英

一個尋路AI對象移向移動目標Unity

[英]A* pathfinding AI object moves towards a moving target Unity

我試圖做一個AI對象來追逐我的玩家。 播放器由用戶控制。

當目標處於固定位置不動時,這是我到目前為止針對AI的代碼。 如何更改它以使我的AI對象追逐玩家?

public class AstarAI : MonoBehaviour
{

    //The point to move to
    public Transform target;

    private Seeker seeker;

    //The calculated path
    public Path path;

    //The AI's speed per second
    public float speed = 2;

    //The max distance from the AI to a waypoint for it to continue to the next waypoint
    public float nextWaypointDistance = 3;

    //The waypoint we are currently moving towards
    public int currentWaypoint = 0;


    public bool arrived;

    public void Start()
    {
       seeker = GetComponent<Seeker>();
       arrived = false;    
       seeker.StartPath(transform.position, target.position, OnPathComplete);

    }



    public void OnPathComplete(Path p)
    {
        Debug.Log("Path calculated? " + p.error);
        if (!p.error)
        {
            path = p;
            //Reset the waypoint counter
            currentWaypoint = 0;
        }
    }

    public void FixedUpdate()
    {


        if (path == null)
        {
            //We have no path to move after yet
            return;
        }

        if (currentWaypoint >= path.vectorPath.Count)
        {
            Debug.Log("End Of Path Reached");
            arrived = true;
            return;
        }

        //Direction to the next waypoint
        Vector3 dir = (path.vectorPath[currentWaypoint] - transform.position).normalized;
        dir *= speed * Time.fixedDeltaTime;
        this.gameObject.transform.Translate(dir);

        //Check if we are close enough to the next waypoint

        if (Vector3.Distance(transform.position, path.vectorPath[currentWaypoint]) < nextWaypointDistance)
        {
            currentWaypoint++;
            return;
        }
    }
}

您將需要重新計算的更新路線,像你這樣的建議在你對此有何評論:

public void Update() 
{ 
    GetNewPath(); 
}

然而,這可能把一個大負荷您的機器上是否有很多可能的路徑進行搜索。 我建議您調用一個更新頻率較低的函數。 這是一個每秒鍾重新計算路徑的示例:

private const float _tickInterval = 1f 

public void Start()
{
    // your code
    // ...

    StartCoroutine(AiTick);
}

public IEnumerator AiTick();
{
    while(true)
    {
        seeker.GetNewPath(); 
        yield return new WaitForSeconds(_tickInterval);
    }
}

public void OnDestroy()
{
    StopAllCoroutines();
}

在此示例中,您不需要Update功能。 相反,我們使用協同程序 協程是可以使用yield關鍵字停止執行並在以后恢復的函數。 有關更多信息,請參閱文檔

它的工作方式如下:

  • public IEnumerator AiTick(); 是協程。 可以使用yield延遲執行

  • 在“ Start我們稱為“ StartCoroutine(AiTick);”,這與調用AiTick()函數相同,但允許將其用AiTick()

  • 該AiTick函數將調用seeker.GetNewPath()然后_tickInterval 當它在后面繼續時,如果將到達循環的末尾,請在while的開頭返回並再次調用seeker.GetNewPath ,替換Update函數,但每_tickInterval秒僅執行一次

  • OnDestroy我們停止協程,因為協程永遠不會退出。 我們不需要這樣做,因為無論如何該對象都被破壞了,但這更干凈

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM