1.unity3d Astar pathfinding 第一个例子

2023-05-16

1. 场景准备

        先建立一个scene添加一个plane,让其坐标处于(0,0,0),并三方向scale都为10

        添加一个新的layer,命名为Ground,并将上面建立的plane设置为Ground层

        在plane上添加若干个box作为障碍物,添加一个新的layer,命名为Obstacles, 将这些box都归为这个Obstacles层


 2.创建一个空的GameObject,命名为A*.

 3.从Components–>Pathfinding–>Pathfinder中添加插件脚本AstarPath。可以再AstarPath的观察器中看到它被分为几个部分,其中最重要的区域是Graphs区域和底部的Scan区域,Graphs区域保存了工程中所有的寻路图,最多可以有16个,但是一般1到2个已经足够了。有几类寻路图,其中最主要的有两种:Grid Pattern Graph和Navmesh Graph.

       这次就先添加Grid graph.

       就如名字所述一样,Grid graph会产生一系列的网格,大小为width * height,这个网格可以放在场景中的任何地方,也可以进行旋转。节点尺寸设置了节点所占空间的大小,在这里设置为1;右侧有一个5个点组成的小选取控制,选择左下角的那个点,将其坐标设置为(-50, 0.1, -50), 其中y方向设置为0.1是为了避免产生浮点错误,因为地面plane的y向坐标是0,如果导航网格也是y向为0的话,在进行高度检测的raycast的时候,会产生问题。

高度测试:

      为了把寻路的node放置到场景中的正确位置,一般使用从node向下发射一个射线来进行检测,寻路node会被放置到碰撞点的位置。我们将mask设置为Ground,因为只希望寻路节点与Ground进行检测。

      碰撞测试:

      当寻路节点被放置之后,它就会被用来检测是否可行走,一般可以使用sphere,capsule或ray来进行碰撞检测。一般Capsule会使用和AI对象一样的半径和高度来进行碰撞。为了让AI对象和障碍物有一些边缘,这里将Capsule的半径设置为2.另外将碰撞检测的layer设置为Obstacles,因为不想让地面成为障碍。

      好了,都准备好了,点击底部的Scan,我们就可以看到grid Graph的生成了,可以再编辑窗口中看到辅助线显示的寻路网格,包括了可寻路的区域和障碍区域。

4. 加入AI

      以上是对场景寻路相关的基础设置,接下来要加入AI对象进行寻路。在场景里面添加一个Capsule,并给其添加一个Character Controller组件,从Components–>Pathfinding中添加Seeker脚本。Seeker脚本是一个帮助类的脚本,用来将其他脚本的寻路请求进行处理,它也可以处理Path modifier(一般是对寻路结果进行圆滑处理的脚本)。A* pathfinding project自带了两个AI脚本用于挂接到对象上进行寻路:AIPah可适用于任何类型的寻路图;而RichAI只适用于NavMesh类型。


using System.Collections;

using System.Collections.Generic;
using UnityEngine;
using Pathfinding;


public class AStarPlayer: MonoBehaviour {


//目标位置;  
Vector3 targetPosition;  


Seeker seeker;  
CharacterController characterController;  


//计算出来的路线;  
Path path;  


//移动速度;  
float playerMoveSpeed = 20f;  


//当前点  
int currentWayPoint = 0;  


bool stopMove = true;  


//Player中心点;  
float playerCenterY = 1.0f;  




// Use this for initialization  
void Start ()   
{  
//seeker = GetComponent<Seeker>();  


//characterController = GetComponent<CharacterController> ();
//playerCenterY = transform.localPosition.y; 
}  


void Awake()
{
seeker = GetComponent<Seeker>();
characterController = GetComponent<CharacterController> ();
playerCenterY = transform.localPosition.y;  
}


//寻路结束;  
public void OnPathComplete(Path p)  
{  
Debug.Log("OnPathComplete error = "+p.error);  


if (!p.error)  
{  
currentWayPoint = 0;  
path = p;  
stopMove = false;  
}  


for (int index = 0; index < path.vectorPath.Count; index++)  
{  
Debug.Log("path.vectorPath["+index+"]="+path.vectorPath[index]);  
}  
}  


// Update is called once per frame  
void Update ()   
{  
if (Input.GetMouseButtonDown(0))  
{  
RaycastHit hit;  
if (!Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit, 100))  
{  
return;  
}  
if (!hit.transform)  
{  
return;  
}  
targetPosition = hit.point;// new Vector3(hit.point.x, transform.localPosition.y, hit.point.z);  


Debug.Log("targetPosition=" + targetPosition);  


seeker.StartPath(transform.position, targetPosition,OnPathComplete);  
}  
}  
int i=0;
void FixedUpdate()  
{  
if (path == null || stopMove)  
{  
return;  
}  
i++;
Debug.Log ("i="+i);
//根据Player当前位置和 下一个寻路点的位置,计算方向;  
Vector3 currentWayPointV = new Vector3(path.vectorPath[currentWayPoint].x, path.vectorPath[currentWayPoint].y + playerCenterY, path.vectorPath[currentWayPoint].z); 
//Vector3 currentWayPointV =path.vectorPath[currentWayPoint];


Vector3 dir = (currentWayPointV - transform.position).normalized;
//Debug.Log ("dir1="+dir);
//dir = dir.normalized;


//Debug.Log ("dir2="+dir);
//计算这一帧要朝着 dir方向 移动多少距离;  
dir *= playerMoveSpeed * Time.fixedDeltaTime;  
//Debug.Log ("dir3="+dir);
//dir *= playerMoveSpeed;  
//计算加上这一帧的位移,是不是会超过下一个节点; 






//float offset = Vector3.Distance(transform.position, currentWayPointV);  
float offset = Vector3.Distance(currentWayPointV,transform.position);


if (offset < 0.1f)  
{  
Debug.Log ("----------------------------------------------------------------------");
transform.localPosition = currentWayPointV;  


currentWayPoint++;  


if (currentWayPoint == path.vectorPath.Count)  
{  
stopMove = true;  


currentWayPoint = 0;  
path = null;  
}  
}  
else  
{  
Debug.Log ("dir.magnitude="+dir.magnitude + " " +"offset="+offset  );


if (dir.magnitude > offset) // length  
{  
//Vector3 tmpV3 = dir * (offset / dir.magnitude);  
//dir = tmpV3;  


currentWayPoint++;  


if (currentWayPoint == path.vectorPath.Count)  
{  
stopMove = true;  


currentWayPoint = 0;  
path = null;  
}  
}  
transform.localPosition += dir;  
//characterController.SimpleMove (dir);
}
}  




本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

1.unity3d Astar pathfinding 第一个例子 的相关文章

  • 基于STM32的电机--电机概述

    文章目录 电机直流有刷电机步进电机伺服电机直流无刷电机舵机 电机 电机 xff1a 俗称 马达 xff0c 依据电磁感应定律实现 电能转换或传递 的一种电磁装置 包括 xff1a 电动机和发电机 电动机在电路中是用M表示 xff0c 它的主
  • 免费公测 标贝声音理解,检测声音性别和年龄

    古有听声辨位 xff0c 今有听声 识 人 说到声音 xff0c 其本质是不同频率声音的集合 xff0c 以波的形式振动 xff08 震动 xff09 传播 由于每个人的发声器官 xff08 口腔 鼻腔 声带 xff09 各不相同 xff0
  • 前后端分离Token验证流程

    1 根据header获取token request getHeader Authorization 2 判断token 是否存在 3 token 不存在 过滤器放行 存在 根据token 获取用户名 根据用户名查询用户记录 UserDeta
  • 车载毫米波雷达MIMO阵列的天线发射问题

    说明 关于MIMO Multiple Input Multiple Output xff0c 多发多收 就不做过多介绍了 xff0c MIMO技术用于车载毫米波雷达主要的目的是增加虚拟通道 xff0c 以期使用较少的收发天线数量来达到较大的
  • 毫米波雷达的硬件架构与射频前端

    说明 本篇博文梳理 车载 毫米波雷达的系统构成 xff0c 特别地 xff0c 对其射频前端各部件做细节性的原理说明 本篇博文会基于对这方面知识理解的加深以及读者的反馈长期更新内容和所附资料 xff0c 有不当之处或有其它有益的参考资料可以
  • 串口+DMA 数据收发编程实践

    更多交流欢迎关注作者抖音号 xff1a 81849645041 目标 了解DMA 的工作原理 xff0c 通过配置 STM32F407 芯片的DMA xff0c 实现串口 43 DMA数据收发 原理 基于USART的数据通讯中采用中断方式可
  • W25Q128读写实验

    更多交流欢迎关注作者抖音号 xff1a 81849645041 目的 熟悉W25Q128串行FLASH的特性和操作指令 掌握通过SPI通讯读写W25Q128数据 原理 本章是结合SPI通讯对串行FLASH的读写 xff0c 通过SPI发送指
  • TFTLCD屏幕实验

    更多交流欢迎关注作者抖音号 xff1a 81849645041 目的 了解TFTLCD屏幕和FSMC的驱动原理 xff0c 通过STM32F4的FSMC接口来控制TFTLCD的显示 原理 1 液晶显示器 显示器属于计算机的I O设备 xff
  • STM32F4主板硬件设计与接口

    更多交流欢迎关注作者抖音号 xff1a 81849645041 本专栏的所有程序都在飞航科技 STM32 F407 开发板上测试通过 xff0c 本文介绍一下STM32 F407 开发板硬件设计与接口 xff0c 便于读者学习交流 STM3
  • 基于STM32F0实现人体红外传感器

    目的 了解人体红外传感器 HC SR501 的驱动原理和STM32F030的中断机制 xff0c 通过配置 STM32F030 芯片 GPIO 相关寄存器和外部触发中断实现人体红外传感器检测人体 原理 中断是指当CPU执行程序时 xff0c
  • STM32F0底板硬件架构设计与原理

    STM32F0底板接口明细 xff1a STM32F0底板作为整块节点的核心 xff08 如下图所示 xff09 xff0c 因此其接口相对应来说较多 xff0c 具体的接口有 xff1a 1 xff1a 5V电源输入口 xff0c STM
  • 基于STM32F030驱动SHT10温湿度传感器

    目的 了解温湿度传感器SHT10的驱动原理 xff0c 通过配置 STM32F030 的GPIO来采集温湿度传感器的温度 湿度和露点的 值 原理 SHT1x 包括 SHT10 SHT11 和 SHT15 属于Sensirion温湿度传感器家
  • Mysql整体介绍(适用于5.X版本)(下)(标贝科技)

    标贝科技 https ai data baker com source 61 qwer12 填写邀请码fwwqgs xff0c 每日免费调用量还可以翻倍 Mysql整体介绍 xff08 适用于5 X版本 xff09 下 xff09 xff0
  • 基于STM32F030实现RFID射频识别

    目的 了解MFRC522读写卡芯片和S50非接触IC卡的驱动原理 xff0c 通过配置 STM32F030 的GPIO和外设SPI xff0c 完成MFRC522传感器与卡的数据读写以及扣款充值实验 原理 MFRC522是高度集成的非接触式
  • MCS-51单片机学习之路(1)

    简介 单片机即单片机微型单片机 xff0c 是将单片机主机 CPU 内存和I O接口 集成在一小块硅片上的微型机 单片机又称微控制器 MCU 单片机具有三高优势 集成度高 可靠性高 性价比高 单片机的历史 第一阶段 xff0c 初级单片 机
  • 【Linux C语言查看SD卡大小】

    1 说明 在linux 环境下 xff0c 使用C预言获取SD卡容量信息 2 环境说明 硬件环境 xff1a ARM或者其他任意开发板 软件环境 xff1a Linux 任意版本 3 原理 statfs 函数 xff0c 可以获取磁盘的容量
  • shell 脚本实现的 deamon 守护进程

    1 说明 在linux 环境下 xff0c 使用 shell 脚本编写一个守护进程 xff0c 在后台一直运行 xff0c 监听需要守护的进程名称 xff0c 如app xff08 1 xff09 当检测到app进程停止 xff0c 则将其
  • mips uclibc 交叉编译ffmpeg,支持 G711A 编解码

    1 说明 使用 ffmpeg 源码 xff0c 进行交叉编译 xff0c 支持 H264 和 G711A 编码支持 2 环境说明 硬件环境 xff1a mips 架构芯片 软件环境 xff1a Linux 任意版本 3 原理 xff08 1
  • Linux下USB CDC ACM 驱动简析

    一 硬件平台 xff1a TI AM335X 芯片 二 软件平台 xff1a Ubuntu 10 04 三 USB CDC ACM 驱动简介 USB的CDC类是USB通信设备类 xff08 Communication Device Clas
  • Openwrt增加对 sd card 支持

    一 硬件平台 1 1 控制器 xff1a MT7620 xff08 A9内核 xff09 二 软件平台 2 1 开发环境 xff1a Ubuntu12 04 2 2 软件版本 xff1a openwrt 官方15 05版本SDK开发包 xf

随机推荐

  • linux sed命令删除特殊字符(含斜线、冒号等转义字符)

    简介 sed 是一种在线编辑器 xff0c 它一次处理一行内容 处理时 xff0c 把当前处理的行存储在临时缓冲区中 xff0c 称为 模式空间 xff08 pattern space xff09 接着用sed命令处理缓冲区中的内容 xff
  • makefile 中指定程序运行时加载的库文件路径

    1 问题描述 程序运行时 xff0c 提示找不到库 原因 xff1a 默认运行加载的库路径为 usr lib 2 解决方法 2 1 方法一 xff0c 设置PATH环境变量 如何在加入这些路径呢 xff1f 以PATH变量为例 一种方法是
  • Openwrt 新增平台编译

    1 说明 本文主要介绍 xff0c 如何在openwrt系统中 xff0c 新增一个平台进行编译 如原本的openwrt 包含了adm5120 arc770 ath25 imx6等平台 xff0c 现在需要新增一个sc9820平台的编译 本
  • Docker概述(一)(标贝科技)

    Docker概述 xff08 一 xff09 顺便介绍下 xff1a 我们是一家致力于智能语音交互的AI公司 xff0c 我们提供了语音识别 语音合成 声纹识别 声音复刻 声音转换等技术产品供小伙伴们测试调用 xff0c 感兴趣的 xff0
  • 树莓派网络配置

    1 说明 1 树莓派有线网络配置 1 树莓派系统WIFI 静态IP设置 2 树莓派系统DNS地址 etc resolv conf 开机后被还原为空或者192 168 1 1处理方法 2 环境 软件环境 xff1a 树莓派3 0 系统 硬件环
  • Linux 读写memory操作,devmem直接访问物理内存地址

    1 说明 由于开发需要 xff0c 需要通过memory传输数据 xff0c 所以使用devmem 方式读写数据 xff0c 操作linux 内存数据 devmem的方式是提供给驱动开发人员 xff0c 在应用层能够侦测内存地址中的数据变化
  • Open3D+vs配置以及使用教程

    Open3d 0 8 0 43 Cmake 43 vs2015 1 下载 简要看一下官网 xff1a Open3D Home Page Github主页 xff1a Open3D Github 注意下载版本 xff0c 一定要与vs相匹配
  • 彻底明白ip地址,区分localhost、127.0.0.1和0.0.0.0

    通俗的了解IP地址是什么 对于IP地址 xff0c 大家并不陌生 xff0c 特别是在网络访问中我们会经常使用到 xff08 平时对域名如百度的www baidu com的访问 xff0c 本质就是对域名所绑定的IP地址的访问 xff09
  • C3927 “->“: 非函数声明符后不允许尾随返回类型等错误

    C3927 34 gt 34 非函数声明符后不允许尾随返回类型等错误 xff0c 如下所示 xff1a 解决方法 xff1a 在VS2015版本 Visual Studio 2015 Update 2 xff0c 增加一个编译选项 utf
  • c++ nan或inf

    nan xff1a not a number 非数字 注意事项 xff1a 对负数开方sqrt 1 0 对负数求对数 log 1 0 0 0 0 0 0 0 inf inf inf inf inf这些操作都会得到nan 0 0会产生操作异常
  • 膨胀、腐蚀、开、闭运算——数字图像处理中的形态学

    膨胀 腐蚀 开 闭运算是数学形态学最基本的变换 形态学通常用于二值图像 一 膨胀与腐蚀能够实现以下作用 xff1a 1 消除噪声 2 分割出独立的图像元素 xff0c 在图像中连接相邻的元素 3 寻找图像中的明显的极大值区域或者极小值区域
  • c语言中&与&&区别

    c语言中 amp 与 amp amp 的区别 amp xff1a 按照位与操作 xff0c 例如 xff1a 0010 amp 1101 xff0c 结果为0000 amp 是java中的位逻辑运算 xff1a eg xff1a 2 amp
  • 网格搜索法

    网格搜索法是指定参数值的一种穷举搜索方法 xff0c 通过将估计函数的参数通过交叉验证的方法进行优化来得到最优的学习算法 即 xff0c 将各个参数可能的取值进行排列组合 xff0c 列出所有可能的组合结果生成 网格 然后将各组合用于SVM
  • pytorch模型从训练到LibTorch部署(标贝科技)

    标贝科技 https ai data baker com source 61 qwer12 填写邀请码fwwqgs xff0c 每日免费调用量还可以翻倍 1 pytorch和libtorch安装 标贝科技 PyTorch 是Torch7 团
  • C++Debug Assertion Failed!到底出错在哪里?

    总结来说这种错误存在两种情况 xff0c 其一就是野指针 另一种情况就是内存泄露 在调试的时候一定是在自己编写的函数上找错 xff0c 不要一只跟着调试顺序在库函数里找错 注意事项 单步调试找到错误 xff0c 祝好运 以上为百度出来的结果
  • 截止频率概念

    截止频率 fc xff08 1HZ 100HZ xff09 xff0c 代表什么意思 截止频率fc xff0c 用来描述一个滤波器或一个放大器频率特性的指标 一个滤波器或一个放大器 xff0c 当保持输入信号的幅度不变 xff0c 改变信号
  • C语言中EOF什么意思

    在C语言中 xff0c 或更精确地说成C标准函数库中表示文件结束符 xff08 end of file xff09 在while循环中以EOF作为文件结束标志 xff0c 这种以EOF作为文件结束标志的文件 xff0c 必须是文本文件 在文
  • C++里面的LPBYTE是什么意思

    BYTE 为 unsigned char LPBYTE 为 unsigned char
  • ORACLE 字符串聚合函数 strCat

    create or replace type strcat type as object currentstr varchar2 4000 currentseprator varchar2 8 static function ODCIAgg
  • 1.unity3d Astar pathfinding 第一个例子

    1 场景准备 先建立一个scene 添加一个plane xff0c 让其坐标处于 0 0 0 xff0c 并三方向scale都为10 添加一个新的layer xff0c 命名为Ground xff0c 并将上面建立的plane设置为Grou