[英]Using unity's A* pathfinding plugin but the AI doesn't move or moves in a wrong direction
[英]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.