[Unity3D插件系列]-A* Pathfinding Project 学习(一)
来源:互联网 发布:淘宝正规刷信誉平台 编辑:程序博客网 时间:2024/06/04 19:44
一直想在Demo中使用Unity3D自带的寻路模块,但是遇到一些问题:
需求中要求游戏中的对象可以寻路的同时,成为其他对象的障碍,我就在同一个对象上添加了NavMeshAgent和NavMeshObstacle,但是出现了对象乱动的异常情况,查了官方文档还有论坛,没有对这种同时添加并起作用的情况有明确的解决方案;这时只能求助于其他寻路插件了,A* Pathfinding Project看起来还不错,考虑学习下。
1. 场景准备
先建立一个scene
添加一个plane,让其坐标处于(0,0,0),并三方向scale都为10
添加一个新的layer,命名为Ground,并将上面建立的plane设置为Ground层
在plane上添加若干个box作为障碍物,添加一个新的layer,命名为Obstacles, 将这些box都归为这个Obstacles层
2.加入A*
创建一个空的GameObject,命名为A*, 从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的生成了,可以再编辑窗口中看到辅助线显示的寻路网格,包括了可寻路的区域和障碍区域。
3. 加入AI
以上是对场景寻路相关的基础设置,接下来要加入AI对象进行寻路。在场景里面添加一个Capsule,并给其添加一个Character Controller组件,从Components–>Pathfinding中添加Seeker脚本。Seeker脚本是一个帮助类的脚本,用来将其他脚本的寻路请求进行处理,它也可以处理Path modifier(一般是对寻路结果进行圆滑处理的脚本)。A* pathfinding project自带了两个AI脚本用于挂接到对象上进行寻路:AIPah可适用于任何类型的寻路图;而RichAI只适用于NavMesh类型。
- using UnityEngine;
- using System.Collections;
- //Note this line, if it is left out, the script won't know that the class 'Path' exists and it will throw compiler errors
- //This line should always be present at the top of scripts which use pathfinding
- using Pathfinding;
- public class AstarAI : MonoBehaviour
- {
- //The point to move to
- public Vector3 targetPosition;
- private Seeker seeker;
- private CharacterController controller;
- //The calculated path
- public Path path;
- //The AI's speed per second
- public float speed = 200;
- //The max distance from the AI to a waypoint for it to continue to the next waypoint
- public float nextWaypointDistance = 3;
- //The waypoint we are currently moving towards
- private int currentWaypoint = 0;
- public void Start()
- {
- seeker = GetComponent<Seeker>();
- controller = GetComponent<CharacterController>();
- //Start a new path to the targetPosition, return the result to the OnPathComplete function
- //seeker.StartPath(transform.position, targetPosition, OnPathComplete);
- }
- public void OnPathComplete(Path p)
- {
- Debug.Log("Yay, we got a path back. Did it have an error? " + p.error);
- if (!p.error)
- {
- path = p;
- //Reset the waypoint counter
- currentWaypoint = 0;
- }
- }
- void Update()
- {
- // see if user pressed the mouse down
- if (Input.GetMouseButtonDown(0))
- {
- // We need to actually hit an object
- RaycastHit hit;
- if (!Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit, 100))
- return;
- // We need to hit something (with a collider on it)
- if (!hit.transform)
- return;
- // Get input vector from kayboard or analog stick and make it length 1 at most
- targetPosition = hit.point;
- seeker.StartPath(transform.position, targetPosition);
- }
- }
- public void FixedUpdate()
- {
- if (path == null)
- {
- //We have no path to move after yet
- return;
- }
- if (currentWaypoint >= path.vectorPath.Count)
- {
- Debug.Log("End Of Path Reached");
- return;
- }
- //Direction to the next waypoint
- Vector3 dir = (path.vectorPath[currentWaypoint] - transform.position).normalized;
- dir *= speed * Time.fixedDeltaTime;
- controller.SimpleMove(dir);
- //Check if we are close enough to the next waypoint
- //If we are, proceed to follow the next waypoint
- if (Vector3.Distance(transform.position, path.vectorPath[currentWaypoint]) < nextWaypointDistance)
- {
- currentWaypoint++;
- return;
- }
- }
- }
这就是一个鼠标点击场景,然后AI对象进行寻路的脚本。如果觉得路线还不太平滑,可以在Components–>Pathfinding–>Modifier中添加寻路结果的修改脚本。
好了,这个教程到此结束。
结语:虽然按照这个教程做了一遍,但发现有些障碍会让AI对象停滞,过不去;但如果换成它自带的AIPah就没有这个问题。
- [Unity3D插件系列]-A* Pathfinding Project 学习(一)
- [Unity3D插件系列]-A* Pathfinding Project 学习(一)
- [Unity插件]A* Pathfinding Project:简易教程(一)
- A*Pathfinding Project学习之【2】插件的使用
- [Unity插件]A* Pathfinding Project:简易课程
- A* Pathfinding Project (Unity A*寻路插件) 使用教程
- A* Pathfinding Project (Unity A*寻路插件) 使用教程
- A* Pathfinding Project (Unity A*寻路插件) 使用教程
- unity3d Pathfinding插件使用
- A star pathfinding project插件点到点寻路
- 寻路插件A* Pathfinding Project_Pro的系统学习(一)_Pathfinder组件_扫描功能
- 插件Pathfinding+Project+Pro的使用
- A*Pathfinding Project学习之【1】判断两个三角形是否共边
- Unity3d 学习界面 之 工程浏览器 (Project Browser)(一)
- [Unity] A* pathfinding project integrated with influence map
- 寻路插件A* Pathfinding Project_Pro的系统学习(二)_AI Path组件_Seeker组件_寻路功能
- 写给初学者的A*算法(A*Pathfinding for beginners)
- 启发式搜索和A*算法(Heuristics and A* Pathfinding)
- 怎么实现EDIUS中序列嵌套的快速运用
- mysql 数据库5.7.11免安装版配置
- 二维码的生成与识别
- java Web表示层技术1
- shell脚本----if判断条件
- [Unity3D插件系列]-A* Pathfinding Project 学习(一)
- 查询锁表与解锁
- 去除字符串末尾指定的字符实例
- java bytes & string conversion
- iOS 获取图片某一点的颜色对象UIColor
- 利用百度地图服务发布自己制作图片的地图
- WebRTC的视频传输的大致流程
- 二叉树的下一结点
- STM32F103RE使用SPI3作为从模式