在Unity中实现Astar寻路算法

在游戏中,从一点到另一点的操作有时需要游戏系统自动完成,在一些带有rpg元素的游戏中,敌人在发现玩家位置后会自动向玩家的位置移动。这些移动的路线是如何自动确定的?本文将介绍寻路算法中的A*算法,并在unity中用C#脚本来实现寻路功能。

问题描述

现在有两个点:起点A,和终点B,允许向周围的八个方向移动,如图所示。需要找到从起点A到终点B效率最高的路径。
红色为起点,绿色为终点
当不存在任何障碍物时,找到两点之间的最短路径似乎毫无难度:只需要每一步都选择离目标点最近的邻近点即可。
在这里插入图片描述
但是当存在障碍物时,路径上的点与目标点的距离并不是单调变化的,这时如何用一个普适性的思路来找出最优路径?

算法思路

从数据结构的角度来看,网格化的地图是一种带有权值的无向图,而路径可以被视为由图中的结点组成的链表。因此,寻路的实质是在有权的图中,在所有以起点为头结点,终点为尾结点的链表中,选择长度最短的链表

核心思想

A*算法的核心思想是:使图中的每一个结点都处在使其权值最小的那条路径上。

权值的定义

首先,需要确定权值,或者叫代价(cost)的计算方式。点在路径上的代价由两部分组成:从起点到该点的代价从该点到终点的代价

1.从起点到该点的代价
从起点起到该点的代价应当为每一步新增的代价的总和。每向正上、下、左、右方向走一步,代价增加10,每斜向走一步,代价增加14;
在这里插入图片描述

2.从该点到终点的代价
从该点到终点的代价是用来估量这个点到终点还需要的过程长短,可以用该点到目标点的直线距离*10来表示。

搜索过程

依照这个想法,由于每走一步只能移动至8邻域,所以每个点的前置结点必然是其8邻域中的一个。只要对其8邻域的每个点作为前置节点时的最小代价进行比较,选择代价最小的点作为前置结点,依此迭代至终点,再向上提取前置就可以得到最优路径。

那对如何确定所有点的搜索顺序呢?因为仍然需要优先考虑朝终点最近的点,所以依然以点的总代价作为搜索顺序的依据,总代价小的优先被搜索(因为代价最小的点意味着已经处于最优路径)。

总结以上讨论,可以整理出出一个思路:

设置一个待搜索结点的集合open。从起点开始,每搜索到一个点,就以其作为前置结点,计算其所有邻近点在该路径上的代价,并与邻近点已有的前置结点下的代价比较,如果当前点带来的代价更小,则更新前置结点,并使所有邻近点放入待搜索集合open。将该点移除集合open。再在open中选取代价最小的结点,重复以上操作,直至搜索到终点。

当第一次搜索到终点时,此时路径第一次被完成,即为最优路径。
在这里插入图片描述

代码实现

Unity中实现A*算法的代码如下所示。这里将路径和待搜索点集合都用List类来表示;编写结点类Node,存放位置、代价和前置结点,其中起点对应的结点前置节点为null。

    //事先初始化的全局变量
    Vector2 origin, destination;//起点和终点
    int mapWidth, mapHeigth;//地图大小
    bool[,] isBarrier;//判断是否为路障
    List<Node> road;//路径存储
    void Astar()
    {
   
    	List<Node> open = new List<Node>();//待搜索的点
		List<Node> close = new List<Node>();//已经搜索过一次或多次的点
    	Node current;
        int minLocation;
        float min;
        //开始搜索
        open.
  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
故事简介丑小鸭生来就很丑,谁都不喜欢它,从小被其他鸭子欺负。它无奈离开了妈妈,拿上一把猎枪,独自流浪,风餐露宿。每当遇到各种怪物而子弹不够用时,丑小鸭只能通过自己的血肉之躯踩死怪物。路上只能靠水果和蔬菜维持体力,无聊时也能抬头数星星。翻山越岭,逢水架桥,勇闯空栈道和独木桥,踩过蹦床,躲过电锯,钻过加农炮,坐过火箭,穿过枪林弹雨,在极度艰苦的条件下大战终极BOSS。最终,丑小鸭占领了一座豪华城堡,里面住着它心仪的白富美(其实也是个丑小鸭),它在夜色降临之前,轻轻关上门,打开灯,结束了流浪生涯,此时天空绽放绚烂的烟花,拉开幸福生活的序幕......这个故事告诉我们:只要你肯奋斗,我命由我不由天 时长课程分为上下两部,共64节课(21.1小时)其,上部29节课(8.5小时),下部35节课(12.6小时)课程特色对初学者友好,初次遇到新技术会详细讲解全程直播,坚决不在直播外偷偷修改展示所有细节,手把手教学游戏元素完整丰富,共3张地图18个关卡代码和文档开源,github托管地址 https://github.com/sailings/DuckAdventure完善的售后支持涵盖实战常用的知识点Physics,刚体,碰撞,弹簧体Mecanim,动画状态机,动画融合,动画层Animation,动画编辑与录制单例模式协程Dotween粒子特效射线检测键盘和移动端输入Cinemachine相机跟随,Confiner扩展UGUI常见控件,HUD屏幕自适应地图与关卡解锁关卡滑动背景滚动子弹轨迹计算音效管理场景编辑数据及上下文存储大纲丑小鸭历险记——趣味玩转unity2d游戏开发(上)  1.游戏简介及演示2.怎样画一匹骏马3.千里之行始于足下4.修复连续跳跃以及Jump动画融合和播放5.匍匐前进6.星星碰撞以及游戏管理增加积分7.吃水果蔬菜、游戏结束、制作水果蔬菜预设8.相机跟随、口水怪动画9.踩死怪物10.喷火怪11.钢管怪12.飞翔的小鸟怪13.食人鱼14.从天而降怪15.落水逻辑16.空栈道和独木桥17.蹦床和电锯18.加农炮19.强力磁铁20.坐着火箭旅行21.漫天飞舞的电锯22.枪林弹雨23.丑小鸭的反击24.定点保存25.Boss动画、移动、释放怪物、生命值管理26.Boss无敌以及特效27.Boss血条以及坠机冒烟28.Boss射击以及子弹轨道计算29.梦幻城堡
Unity A*寻路算法是一种常用的路径规划算法,它可以帮助我们快速高效地找到两点之间最短路径。A*寻路算法的核心思想是在搜索过程综合利用已知信息和预测信息,以高效地选择下一个最佳节点。 在Unity,可以使用A*相关的插件或者自己实现A*算法实现寻路功能。首先,需要生成一个网格或者地图,将地图划分成一个个小格子。每个格子表示一个节点,节点之间的连接关系可以通过建立链接或者使用权重来表示。 接下来,需要实现A*算法的估价函数、开启列表和关闭列表等数据结构。估价函数用来评估每个节点距离目标的预测代价,开启列表用来保存待搜索的节点,关闭列表用来保存已经搜索过的节点。 然后,从起点开始,将其加入到开启列表,并开始循环搜索。在每一次循环,选择开启列表估价函数最小的节点作为当前节点,然后将其从开启列表删除,并将其加入到关闭列表。接着,对当前节点的邻居节点进行处理,如果邻居节点已经在关闭列表,则忽略;如果邻居节点不在开启列表,则将其加入开启列表,并更新其父节点和估价函数;如果邻居节点已经在开启列表,就更新其父节点和估价函数,但是不改变它在开启列表的位置。 当目标节点被加入到关闭列表时,表示找到了一条最短路径。此时,可以从目标节点开始,依次访问它们的父节点,直到回到起点,这样就可以得到具体的路径。 最后,根据节点的位置信息,将路径可视化展示出来,使人们可以看到实际的路径。 总体来说,Unity A*寻路算法是一种十分高效和常用的路径规划算法,通过合理利用已知信息和预测信息,可以帮助我们找到两点之间最短路径,实现游戏角色的自动导航等功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值