当前位置: 首页 > news >正文

Unity A*算法实现+演示

注意:

本文是对基于下方文章链接的理论,并最终代码实现,感谢作者大大的描述,非常详细,流程稍微做了些改动,文末有工程网盘链接,感兴趣的可以下载。

A*算法详解(个人认为最详细,最通俗易懂的一个版本)-CSDN博客

1、效果演示:

2、A*算法流程:

(1)         把起点加入 open list 。

(2)         重复如下过程:

                        a.         遍历 open list ,查找 F 值最小的节点,把它作为当前要处理的节点。

                        b.         对当前方格的 8连通的每一个方格            

                                         ◆     如果它是不可抵达的或者它在 close list 中,忽略它。否则,做如下操作。

                                         ◆     如果它不在 open list 中,把它加入 open list ,并且把当前方格设置为它的父亲,记录该方格的 F , G 和 H 值。

                                         ◆     如果它已经在 open list 中,检查这条路径 ( 即经由当前方格到达它那里 ) 是否更好,用 G 值作参考。更小的 G 值表示这是更好的路径。如果是这样,把它的父亲设置为当前方格,并重新计算它的 G 和 F 值。

                         c.         把这个节点移到 close list 。

                         d.         停止,当你

                                         ◆     把终点加入到了 open list 中,此时路径已经找到了,或者

                                         ◆     查找终点失败,并且 open list 是空的,此时没有路径。

(3)         保存路径。从终点开始,每个方格沿着父节点移动直至起点,这就是你的路径。

3、代码:

逻辑层Node结点定义:
using UnityEngine;public enum GridState
{Empty,Block,
}
public class Node
{public GridState curState;public int X;public int Y;public int F;public int G;public int H;public Node parentNode;public Node(int x, int y){X = x;Y = y;ResetNode();}public void ResetNode(){curState = GridState.Empty;F = 0;G = 0;H = 0;parentNode = null;}public void CalculateValue(Node endNode){if (parentNode == null) return;//计算GG = GetPredictGValue(parentNode);//曼哈顿距离计算HH = Mathf.Abs(endNode.X - X) + Mathf.Abs(endNode.Y - Y);F = G + H;}public int GetPredictGValue(Node targetNode){int predictG = 0;//四连通if (targetNode.X == X || targetNode.Y == Y){predictG = targetNode.G + 10;}//八连通else{predictG = targetNode.G + 14;}return predictG;}}
寻路算法:
using System.Collections.Generic;public partial class PathFind
{private List<Node> openList;private List<Node> closeList;private Node[,] allNodeList;public void AStarInit(Node[,] allNodes){openList = new List<Node>();closeList = new List<Node>();allNodeList = allNodes;}public void FindRoad(Node startNode, Node endNode){openList.Add(startNode);LoopFindRoad(endNode);}private void LoopFindRoad(Node endNode){//找到终点或者不存在路径if (openList.Count == 0||openList.Contains(endNode)){return;}//找到F值最小的Node smallestFNode = null;for (int i = 0; i < openList.Count; i++){if (smallestFNode == null){smallestFNode = openList[i];continue;}if (openList[i].F<=smallestFNode.F){smallestFNode = openList[i];}}//获得八连通格子List<Node> eightAdjacent = GetRoundNode(smallestFNode);//更新代价for (int i = 0; i < eightAdjacent.Count; i++){//不在openList里面if (!openList.Contains(eightAdjacent[i])){eightAdjacent[i].parentNode = smallestFNode;eightAdjacent[i].CalculateValue(endNode);openList.Add(eightAdjacent[i]);}else{//判断是否需要更新F,G,Hif (eightAdjacent[i].GetPredictGValue(smallestFNode) <= eightAdjacent[i].G){eightAdjacent[i].parentNode = smallestFNode;eightAdjacent[i].CalculateValue(endNode);}}}//转移结点openList.Remove(smallestFNode);closeList.Add(smallestFNode);LoopFindRoad(endNode);}/// <summary>/// 获得八连通格子中可达到并且不在closeList中的格子/// </summary>/// <returns></returns>private List<Node> GetRoundNode(Node targetNode){int x = targetNode.X;int y = targetNode.Y;List<Node> tempList = new List<Node>();if (IsReachableNode(x, y + 1)) tempList.Add(allNodeList[x, y + 1]);if (IsReachableNode(x + 1, y + 1)) tempList.Add(allNodeList[x + 1, y + 1]);if (IsReachableNode(x + 1, y)) tempList.Add(allNodeList[x + 1, y]);if (IsReachableNode(x + 1, y - 1)) tempList.Add(allNodeList[x + 1, y - 1]);if (IsReachableNode(x, y - 1)) tempList.Add(allNodeList[x, y - 1]);if (IsReachableNode(x - 1, y - 1)) tempList.Add(allNodeList[x - 1, y - 1]);if (IsReachableNode(x - 1, y)) tempList.Add(allNodeList[x - 1, y]);if (IsReachableNode(x - 1, y + 1)) tempList.Add(allNodeList[x - 1, y + 1]);return tempList;}/// <summary>/// 判断格子是否可到达/// </summary>/// <param name="x"></param>/// <param name="y"></param>/// <returns></returns>private bool IsReachableNode(int x, int y){if (x >= allNodeList.GetLength(0) || x <= 0){return false;}if (y >= allNodeList.GetLength(1) || y <= 0){return false;}if (allNodeList[x, y].curState == GridState.Block){return false;}if (closeList.Contains(allNodeList[x, y])){return false;}return true;}
}

4、补充:

如果希望过障碍时,不允许他斜向过障碍,可以额外加个判断,原理很简单,对于8连通的角落点,判断角落点的4连通是否有障碍,如果有障碍就不算入可到达格子。

代码如下:

演示:

5、工程网盘链接:

通过网盘分享的文件:AStarDemo.unitypackage
链接: https://pan.baidu.com/s/1L_f1DIkqe9Oqm_dnFSSVew 提取码: 1212

相关文章:

Unity A*算法实现+演示

注意&#xff1a; 本文是对基于下方文章链接的理论&#xff0c;并最终代码实现&#xff0c;感谢作者大大的描述&#xff0c;非常详细&#xff0c;流程稍微做了些改动&#xff0c;文末有工程网盘链接&#xff0c;感兴趣的可以下载。 A*算法详解(个人认为最详细,最通俗易懂的一…...

浏览器要求用户确认 Cookies Privacy(隐私相关内容)是基于隐私法规的要求,VUE 实现,html 代码

Cookie Notices and Cookie Consent | Cookiepedia 1. 法律法规要求 许多国家和地区的隐私法律要求网站在存储或处理用户数据&#xff08;包括 Cookies&#xff09;之前必须获得用户的明确同意&#xff1a; GDPR&#xff08;欧盟通用数据保护条例&#xff09; 要求&#xff…...

如何设计高效的商品系统并提升扩展性:从架构到实践的全方位探索

在现代电商、零售及企业资源管理系统中&#xff0c;商品管理无疑是核心模块之一。随着市场的变化与企业规模的扩展&#xff0c;商品系统需要具备强大的功能支持以及高效的扩展能力&#xff0c;以应对日益复杂的业务需求。一个设计良好的商品系统不仅仅是一个商品信息的容器&…...

使用计算机创建一个虚拟世界

创建一个虚拟世界是一项复杂而多方面的工作&#xff0c;它涉及多个领域的知识&#xff0c;包括计算机图形学、编程、物理模拟、声音设计、艺术设计等。以下是创建虚拟世界的基本步骤和工具建议&#xff1a; 1. 确定虚拟世界的目标和范围 目标&#xff1a;明确这个虚拟世界的用…...

datasets笔记:两种数据集对象

Datasets 提供两种数据集对象&#xff1a;Dataset 和 ✨ IterableDataset ✨。 Dataset 提供快速随机访问数据集中的行&#xff0c;并支持内存映射&#xff0c;因此即使加载大型数据集也只需较少的内存。IterableDataset 适用于超大数据集&#xff0c;甚至无法完全下载到磁盘或…...

【ETCD】【Linearizable Read OR Serializable Read】ETCD 数据读取:强一致性 vs 高性能,选择最适合的读取模式

ETCD 提供了两种不同类型的读取操作方式&#xff0c;分别是 Linearizable Read&#xff08;线性化读取&#xff09;和 Serializable Read&#xff08;可串行化读取&#xff09;。这两种方式主要区分在读取数据时对一致性的要求不同。 目录 1. Linearizable Read&#xff08;线…...

【CSS in Depth 2 精译_089】15.2:CSS 过渡特效中的定时函数

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 第五部分 添加动效 ✔️【第 15 章 过渡】 ✔️ 15.1 状态间的由此及彼15.2 定时函数 ✔️ 15.2.1 定制贝塞尔曲线 ✔️15.2.2 阶跃 ✔️ 15.3 非动画属性 文章目录 15.2 定时函数 Timing function…...

不常用命令指南

常用命令网上资料很多&#xff0c;讲的也不错。这里记录下日常工作中用到的&#xff0c;但对于新手又不常用的命令 文章目录 信息相关进程相关htoppgrep&#xff08;根据指定的条件获取进程id&#xff09;lsof 网络相关ssnc&#xff08;netcat&#xff09; 信息相关 进程相关 …...

spring mvc | servlet :serviceImpl无法自动装配 UserMapper

纯注解SSM整合 解决办法&#xff1a; 在MybatisConfig添加 Configuration MapperScan("mapper")...

STM32 HAL库之串口接收不定长字符

背景 在项目开发过程中&#xff0c;经常会使用MCU的串口与外界进行通信&#xff0c;例如两个单片机之间TTL电平型串口通信&#xff0c;单片机与成熟电路模块之间的串口通信等等.... 如何高效的使用串口是开发人员必须关注的问题。 STM32的HAL库为我们提供了三种串口通信机制&am…...

Pyqt6的tableWidget填充数据

代码 from PySide6.QtWidgets import QTableWidget QTableWidgetItemdef tableInit(self):self.tableWidgetself.tableWidget.setSelectionBehavior(QAbstractItemView.SelectRows)module_keyWord readJsonToDict(keyWordFileDir module_name) #读取模块关键字json字典数据s…...

ASP.NET Core - 依赖注入 自动批量注入

依赖注入配置变形 随着业务的增长&#xff0c;我们项目工作中的类型、服务越来越多&#xff0c;而每一个服务的依赖注入关系都需要在入口文件通过Service.Add{}方法去进行注册&#xff0c;这将是非常麻烦的&#xff0c;入口文件需要频繁改动&#xff0c;而且代码组织管理也会变…...

UVM 验证方法学之interface学习系列文章(十一)virtual interface 再续篇

一 前言 并非总是可以将被测单元(DUT)视为一个黑盒,即仅监控和驱动DUT的顶层端口信号。这一点在从模块级测试转向更大规模的系统级测试时尤为明显。有时,我们需要了解实现细节以便访问DUT内部的信号。这被称为白盒验证。 Verilog一直提供从其他作用域访问几乎任何层次结构…...

面试题整理5----进程、线程、协程区别及僵尸进程处理

面试题整理5----进程、线程、协程区别及僵尸进程处理 1. 进程、线程与协程的区别1.1 进程&#xff08;Process&#xff09;1.2 线程&#xff08;Thread&#xff09;1.3 协程&#xff08;Coroutine&#xff09;2. 总结对比 3. 僵尸进程3.1 什么是僵尸进程&#xff1f;3.2 僵尸进…...

OpenTK 中帧缓存的深度解析与应用实践

摘要: 本文深入探讨了 OpenTK 中帧缓存的使用。首先介绍了帧缓存的基本概念与在图形渲染管线中的关键地位,包括其与颜色缓存、深度缓存、模板缓存等各类缓存的关联。接着详细阐述了帧缓存对象(FBO)的创建、绑定与解绑等操作,深入分析了纹理附件、渲染缓冲区附件在 FBO 中的…...

第2节-Test Case如何调用Object Repository中的请求并关联参数

前提&#xff1a; 已经创建好了project&#xff08;File -> New -> Project&#xff0c;Type&#xff1a;API/WebService&#xff09;&#xff0c;object repository中已经创建了RESTful endpoint&#xff08;Object Repository -> New -> Web Service Request&am…...

【HarmonyOS NEXT】Web 组件的基础用法以及 H5 侧与原生侧的双向数据通讯

关键词&#xff1a;鸿蒙、ArkTs、Web组件、通讯、数据 官方文档Web组件用法介绍&#xff1a;文档中心 Web 组件加载沙箱中页面可参考我的另一篇文章&#xff1a;【HarmonyOS NEXT】 如何将rawfile中文件复制到沙箱中_鸿蒙rawfile 复制到沙箱-CSDN博客 目录 如何在鸿蒙应用中加…...

Android学习(六)-Kotlin编程语言-数据类与单例类

假设我们要创建一个表示书籍的数据类 Book&#xff0c;包含书名和作者两个字段。在 Java 中&#xff0c;代码如下&#xff1a; public class Book { String title; String author; public Book(String title, String author) { this.title title; this.author author; } Ove…...

CV-OCR经典论文解读|An Empirical Study of Scaling Law for OCR/OCR 缩放定律的实证研究

论文标题 An Empirical Study of Scaling Law for OCR OCR 缩放定律的实证研究 论文链接&#xff1a; An Empirical Study of Scaling Law for OCR论文下载 论文作者 Miao Rang, Zhenni Bi, Chuanjian Liu, Yunhe Wang, Kai Han 内容简介 本论文在光学字符识别&#xf…...

力扣274. H 指数

给你一个整数数组 citations &#xff0c;其中 citations[i] 表示研究者的第 i 篇论文被引用的次数。计算并返回该研究者的 h 指数。 根据维基百科上 h 指数的定义&#xff1a;h 代表“高引用次数” &#xff0c;一名科研人员的 h 指数 是指他&#xff08;她&#xff09;至少发…...

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...

Python爬虫实战:研究MechanicalSoup库相关技术

一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

微信小程序之bind和catch

这两个呢&#xff0c;都是绑定事件用的&#xff0c;具体使用有些小区别。 官方文档&#xff1a; 事件冒泡处理不同 bind&#xff1a;绑定的事件会向上冒泡&#xff0c;即触发当前组件的事件后&#xff0c;还会继续触发父组件的相同事件。例如&#xff0c;有一个子视图绑定了b…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql

智慧工地管理云平台系统&#xff0c;智慧工地全套源码&#xff0c;java版智慧工地源码&#xff0c;支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求&#xff0c;提供“平台网络终端”的整体解决方案&#xff0c;提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

蓝桥杯 2024 15届国赛 A组 儿童节快乐

P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡&#xff0c;轻快的音乐在耳边持续回荡&#xff0c;小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下&#xff0c;六一来了。 今天是六一儿童节&#xff0c;小蓝老师为了让大家在节…...

令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍

文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结&#xff1a; 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析&#xff1a; 实际业务去理解体会统一注…...

2025盘古石杯决赛【手机取证】

前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来&#xff0c;实在找不到&#xff0c;希望有大佬教一下我。 还有就会议时间&#xff0c;我感觉不是图片时间&#xff0c;因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“&#x1f916;手搓TuyaAI语音指令 &#x1f60d;秒变表情包大师&#xff0c;让萌系Otto机器人&#x1f525;玩出智能新花样&#xff01;开整&#xff01;” &#x1f916; Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制&#xff08;TuyaAI…...

AspectJ 在 Android 中的完整使用指南

一、环境配置&#xff08;Gradle 7.0 适配&#xff09; 1. 项目级 build.gradle // 注意&#xff1a;沪江插件已停更&#xff0c;推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...