一、导入A* Pathfinding插件7nmc
创建一个空物体 给物体添加Astar Path脚本(插件核心脚本),点击grahs,选择新建一个grid graph
Node size:数值越小 网格越密集
Aspect Ratio:长宽比例
二、简单搭建场景,新建一层,把障碍物标记层,在Astar Path中Collision testing–Mask选择mask层,最后点击snap size更新网格
需要找寻目标的的物体添加Seeker脚本 之后创建一个新脚本,AStarTest也挂在该物体上,也可以添加一个Simple Smooth Modifier(能使行走路线更加平滑)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Pathfinding;
using System.Diagnostics;
[RequireComponent(typeof(Seeker))]
//当某个脚本必须依赖其他脚本或者组件共同使用时,为了避免人为添加过程的操作失误,
//可以在代码中使用RequireComponent,它的作用就是添加该脚本时,
//会自动将所依赖的各个组件添加至gameobject上,避免人为操作的失误。
public class AStarTest : MonoBehaviour
{
public GameObject target;
private Seeker seeker;
public Path path;
public float MoveSpeed;
public float RotateSpeed;
public int currentPoint = 0; //正朝向移动的当前点
public float nextpointDistance;//距离下一点的距离
void Start()
{
seeker = GetComponent<Seeker>();
seeker.pathCallback += OnCallFunc;
seeker.StartPath(this.transform.position, target.transform.position);
}
//回调函数
public void SeekFunc()
{
if (path==null)
{
print("path=========null");
return;
}
if (currentPoint>=path.vectorPath.Count)//如果接下来没有路径的话
{
print("currentPoint>path.vectorPath.Count+到达终点");
return;
}
Vector3 dir = (path.vectorPath[currentPoint] - this.transform.position).normalized;
dir *= MoveSpeed * Time.deltaTime;
this.transform.Translate(dir, Space.World);
Quaternion targetRotation = Quaternion.LookRotation(dir);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * RotateSpeed);
if (Vector3.Distance(transform.position,path.vectorPath[currentPoint])<nextpointDistance)
{
currentPoint++;
return;
}
}
void OnCallFunc(Path p)
{
if (!p.error)
{
path = p;
}
}
// Update is called once per frame
void Update()
{
SeekFunc();
}
}
- A 算法*
与贪婪算法不一样,贪婪算法适合动态规划,寻找局部最优解,不保证最优解。
A*是静态网格中求解最短路最有效的方法。也是耗时的算法,不宜寻路频繁的场合。一般来说适合需求精确的场合。
与启发式的搜索一样,能够根据改变网格密度、网格耗散来进行调整精确度。
使用的地方:
a. 策略游戏的策略搜索
b. 方块格子游戏中的格子寻路
A型算法主要还是运用到2d游戏寻路。后续发一些A星寻路2d