使用 A* (AStar) 和 Unity 进行敌人寻路
Enemy Pathfinding with A* (AStar) & Unity
如何让敌人停在离玩家一定距离处而不是直接冲过去?我想创建一个远程单位。我可以对敌人进行攻击,我只是不想让敌人直接攻击玩家。我使用 AStar 寻路包对我的敌人进行了自定义 AI 脚本 -
Transform target;
public float speed = 200f;
public float nextWaypointDistance = 3f;
public Transform enemyGFX;
Path path;
int currentWaypoint = 0;
bool reachedEnd = false;
Seeker seeker;
Rigidbody2D rb;
void Start()
{
seeker = GetComponent<Seeker>();
rb = GetComponent<Rigidbody2D>();
target = GameObject.Find("Player").transform;
InvokeRepeating("UpdatePath", 0.0f, 0.5f);
}
void UpdatePath()
{
if(seeker.IsDone()) {
seeker.StartPath(rb.position, target.position, OnPathComplete);
}
}
void OnPathComplete(Path p)
{
if(!p.error)
{
path = p;
currentWaypoint = 0;
}
}
void FixedUpdate()
{
if (path == null) return;
if(currentWaypoint >= path.vectorPath.Count)
{
reachedEnd = true;
return;
}
else
{
reachedEnd = false;
}
Vector2 direction = ((Vector2)path.vectorPath[currentWaypoint] - rb.position).normalized;
Vector2 force = direction * speed * Time.deltaTime;
rb.AddForce(force);
float distance = Vector2.Distance(rb.position, path.vectorPath[currentWaypoint]);
if(distance < nextWaypointDistance) currentWaypoint++;
}
}
非常感谢所有帮助!
正确的做法是不搜索特定的节点,而是搜索距目标一定距离内的任何节点,或者一定距离内且视线直接的任何节点。
看起来 AStar 寻路库应该有类似的功能。例如,有一个 GetNearest 重载,它采用可能有效的约束。或者 maxNearestNodeDistance
字段。但是我不熟悉那个库,所以我很难提供具体的建议。
另一种选择是编写您自己的实现。这不是微不足道的,但也不是太复杂,并且有大量资源解释像 A* 这样的算法。您可能达不到与商业库同等的功能,但您可能只需要相当简单的功能。作为学习练习,它也可能很有用,可以更好地了解 AI 和路径查找的工作原理。
如何让敌人停在离玩家一定距离处而不是直接冲过去?我想创建一个远程单位。我可以对敌人进行攻击,我只是不想让敌人直接攻击玩家。我使用 AStar 寻路包对我的敌人进行了自定义 AI 脚本 -
Transform target;
public float speed = 200f;
public float nextWaypointDistance = 3f;
public Transform enemyGFX;
Path path;
int currentWaypoint = 0;
bool reachedEnd = false;
Seeker seeker;
Rigidbody2D rb;
void Start()
{
seeker = GetComponent<Seeker>();
rb = GetComponent<Rigidbody2D>();
target = GameObject.Find("Player").transform;
InvokeRepeating("UpdatePath", 0.0f, 0.5f);
}
void UpdatePath()
{
if(seeker.IsDone()) {
seeker.StartPath(rb.position, target.position, OnPathComplete);
}
}
void OnPathComplete(Path p)
{
if(!p.error)
{
path = p;
currentWaypoint = 0;
}
}
void FixedUpdate()
{
if (path == null) return;
if(currentWaypoint >= path.vectorPath.Count)
{
reachedEnd = true;
return;
}
else
{
reachedEnd = false;
}
Vector2 direction = ((Vector2)path.vectorPath[currentWaypoint] - rb.position).normalized;
Vector2 force = direction * speed * Time.deltaTime;
rb.AddForce(force);
float distance = Vector2.Distance(rb.position, path.vectorPath[currentWaypoint]);
if(distance < nextWaypointDistance) currentWaypoint++;
}
}
非常感谢所有帮助!
正确的做法是不搜索特定的节点,而是搜索距目标一定距离内的任何节点,或者一定距离内且视线直接的任何节点。
看起来 AStar 寻路库应该有类似的功能。例如,有一个 GetNearest 重载,它采用可能有效的约束。或者 maxNearestNodeDistance
字段。但是我不熟悉那个库,所以我很难提供具体的建议。
另一种选择是编写您自己的实现。这不是微不足道的,但也不是太复杂,并且有大量资源解释像 A* 这样的算法。您可能达不到与商业库同等的功能,但您可能只需要相当简单的功能。作为学习练习,它也可能很有用,可以更好地了解 AI 和路径查找的工作原理。