Unity 官方 A*Pathfinding Project 插件的使用学习笔记
A* Pathfinding Project 是基于Unity扩展编辑器开发的一款寻路插件,寻路原理是基于AStar寻路新算法,,也称作A* 寻路算法。
一、A* 寻路 VS 导航网格NavMesh寻路:
- A*寻路:
动态寻路,适用于场景状态变化大的,比如游戏,但CPU消耗高 - NaveMesh:
静态寻路,适用于场景状态不怎么变化的,CPU消耗低
二、插件的使用
- 创建Ground ,指定Layer层:Ground (地面)
- 创建Obstacles,指定Layer层:Obstacles (障碍物)
- 创建Empty,命名AStarPathfinder,添加脚本组件Pathfinder(Astar Path)
- 选择Grid Graphs 网格寻路:
* Width/Depth(nodes):网格节点数(网格范围大小)
* Aspect Ratio:单位网格的长宽比
* Center:设置网格的位置,若发现网格位置不理想,没关系,点击Snap Size 即可
* Erosion iterations:默认值为0,调整该值避免人穿障碍物,亲测值为 1 即可 - Collision testing:Mask >> 选择Obstacles,指定障碍物
- Height testing:Mask >> 选择Ground,指定地面
- 点击Scan 按钮,生成可行走区域
- 创建Capsule(或者指定模型),命名Player, 代表AI角色,添加脚本组件 Seeker 用于计算路径
- Player对象添加 SimpleSmoothModifier 脚本组件,用以平滑Player的移动路线(默认的路线曲曲折折的,人物移动时不平滑)
- 创建 AstarPlayer 脚本,编辑代码控制Player寻路:
三、代码示例
using Pathfinding;
public class AstarPlayer:MonoBehaviour
{
private float _moveSpeed = 10.0f; //AI角色移动速度
private Seeker _seeker; //A*寻路路径计算组件
private Vector3 _targetPoint; //寻路目标点
private Path _path; //寻路计算出的路径
private Vector3 _playerCenterY; //AI角色Y轴坐标值
private Vector3
private int _curPathPoint; //当前路径点数
private bool _stopMove = true; //标记AI角色停止移动
void Start()
{
_seeker = GetComponent<Seeker>();
if(_seeker == null)
{
Debug.Log("Seeker Component is null!");
return;
}
}
private void FixedUpdate()
{
if(_path != null && !_stopMove)
{
//计算Player当前位置到下一个目标点的方向
Vector3 temp = _path.VectorPath[_curPathPoint];
Vector3 nextPoint = new Vector3(temp.x, temp.y + _playerCenterY, temp.z);
Vector3 dir = (nextPoint - transform.position).normalized;
//计算Player当前位置到下一个目标点的距离
float offset = Vector3.Distance(transform.position, nextPoint);
if(offset < 0.1f)
{
transform.position = nextPoint;
_curPathPoint++;
//检查Player是否走到最后一个目标点,是,完成移动
CheckLastPoint();
}
else
{
//计算一帧移动多少距离
Vector3 distance = dir * _moveSpeed * Time.deltTime;
if(distance.magnitude > offset)
{
//重新计算移动距离
distance = dir * offsest;
_curPathPoint++;
//检查是否到达最后一个节点
CheckLastPoint();
}
transform.localPosition += distance;
}
}
}
private void Update()
{
//监听鼠标左键按下
if(Input.GetMouseButtonDown(0))
{
//用射线创建 TargetPoint
Ray ray = Camera.main.ScreenPointToRay(Input.GetMousePosition);
RaycastHit hit;
//利用物理引擎发射一条射线,返回true,说明射线与物体发生碰撞
if(Physics.RaycastHit(ray,out hit,100))
{
_targetPoint = hit.point;
//计算路径
_seeker.StartPath(transform.position, _targetPoint, OnPathCompeleted);
}
}
}
//检查到达最后一个目标点
private void CheckLastPoint()
{
if(_curPathPoint == _path.VectorPath.Count)
{
_curPathPoint = 0;
_path = null;
_stopMove = true;
}
}
//寻路路径计算完成时回调
private void OnPathCompeleted( Path path)
{
_path = path;
_curPathPoint = 0;
_stopMove = false;
}
}
这篇博客介绍了Unity的A* Pathfinding Project插件,对比了A*寻路和导航网格NavMesh寻路的适用场景,并详细阐述了插件的使用步骤,包括设置网格参数、生成可行走区域、添加角色组件以及实现代码控制AI角色寻路。

1万+

被折叠的 条评论
为什么被折叠?



