除了unity自身NavMeshObstacle 以外的动态unity3d 跑酷 障碍物寻路解决方案??

之前我们一起学习了如何使用Navmesh组件来实现最基本的角色自动寻路。今天我们再继续深入探索Navigation组件的高级功能。在本文中,你将了解到如何在两个隔离层自动生成寻路网格?如何手动指定寻路网格的路线?以及寻路网格层的应用。(本文所用到的模型皆来自Unity3d官网)。(转载请注明原文地址)隔离层自动生成寻路网格(源码scene1.unity)1.创建Plane实例P1,P2,两者之间出现一条鸿沟。直接控制角色位移是无法通过的。2.打开Navigation窗口,分别选中P1,P2,分别设置Navigation Static 和OffMeshLink Generatic3.保存场景,点击场景烘焙按钮Bake。结束后我们可以看到P1,P2除了自身生产寻路网格外,它们直接还生成了连接纽带。4.添加角色模型Solder,为其添加NavMeshAgent(Component-&Navigation-&NavMeshAgent)5.给Solder添加PlayerController脚本using UnityE
using System.C
public class PlayerController : MonoBehaviour
private NavMeshA
public bool setAgentWalkM//是否需要动态修改寻路层,在scene4的实例中要用到
void Start()
//获取寻路组件
agent = GetComponent&NavMeshAgent&();
void Update()
//鼠标左键点击
if (Input.GetMouseButtonDown(0))
//摄像机到点击位置的的射线
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit))
//判断点击的是否地形
if (!hit.collider.tag.Equals("Plane"))
//点击位置坐标
Vector3 point = hit.
transform.LookAt(new Vector3(point.x, transform.position.y, point.z));
//设置寻路的目标点
agent.SetDestination(point);
//播放动画
if (agent.remainingDistance == 0)
animation.Play("Idle");
animation.Play("Run");
}5.点击任意的位置,可以看到角色都能自动寻路过去效果图手动指定寻路网格方向源码scene2.unity1.scene1.unity的基础上,将P1,P2的OffMeshLink Generatic去除2.在P1上新建一个空的GameObject Start,P2上新建一个空的GameObject End3.选中start,为它添加Off Mesh Link组件 Component-&Navigation-&OffMeshLink4.设置Off Mesh Link组件的属性,Start Point 为 start,End Point为end5.烘焙场景。我们可以看到有一条纽带从start指向end点击地图,可以看到角色如果要跨越P1和P2,一定是沿着我们手动创建的路径导航网格障碍物 Navmesh Obstacle之前我们都是用固定的物体作为障碍物,然后烘焙场景。Unity还提供了动态的障碍物。任何一个GameObject都可以添加Navmesh Obstacle组件,变成一个障碍物。具体步骤是Component-&Navigation-&Navmesh Obstacle.它有两个属性:半径和高度,可以设置跟你的物品差不多的体积大小。寻路网格层的应用源码scene3.unity玩过“3c”,“dota”这类游戏的同学都知道:地图上有上中下三条大道,不同的兵可能去的路不同。今天我们也做个类似的实例。1.新建P1,P2,P3,P4等4个Plane,具体摆设形状见效果图2.在Navigation窗口中,添加两个层Layers:Blue层和Red层3.P1,P2的Navigation Layer设置为Default,P4的Navigation层设置为Red,P3设置为Blue4.添加两个角色,设置他们的NavMeshAgent寻路层(NavMesh Walkable)。一个将Red层去掉,一个将Blue层去掉5.点击P2的坐标,可以看到他们沿着不同的路径去目标点,一个走上层路线,一个走下层路线了。效果图动态改变寻路网格层源码scene4.unity在游戏中,我们很多时候都是需要根据不同的条件,选择不同的寻路路径。1.在scene3.unity基础上做一下修改。只保留一个角色2.新增两个按钮,“走上层”和“走下层”,在游戏运行时,可以改变Agent的寻路层。//动态设置寻路路径层
void OnGUI()
if (!setAgentWalkMask)
if (GUI.Button(new Rect(0, 0, 100, 50), "走下层"))
agent.walkableMask = 65;
if (GUI.Button(new Rect(0, 100, 100, 50), "走上层"))
agent.walkableMask = 129;
}3.重新点击寻路,可以看到,选择不同的寻路层,角色的寻路路径也不同看到代码中的agent.walkableMask = 65和129,大家会比较迷惑,其实寻路层每一层都是2的幂,见下图所以上层的mask = Default(1)+Blue(128) = 129,下层的mak = Default(1)+Red(64) = 65总结本文将寻路组件的各个细节都做了一次梳理,详细能帮大家熟练掌握各个特性,在实际项目中根据不同的需求熟练选择应用相关的特性。接下来我还会有一个更加详细的实例来贯穿所以的Navmesh特性,敬请期待!源码地址参考资料1./2.http://liweizhaolili./3./Components/class-NavMeshAgent.html
如果您想留下此文,您可以将其发送至您的邮箱(将同时以邮件内容&PDF形式发送)
相关文章推荐
(Ctrl+Enter提交) &&
已有0人在此发表见解
&在& 00:28收藏到了
&&在信息爆炸的时代,您的知识需要整理,沉淀,积累!Lai18为您提供一个简单实用的文章整理收藏工具,在这里您可以收藏对您有用的技术文章,自由分门别类,在整理的过程中,用心梳理自己的知识!相信,用不了多久,您收藏整理的文章将是您一生的知识宝库!
· 蜀ICP备号-1使用Unity自带寻路:NavMesh - 简书
使用Unity自带寻路:NavMesh
NavMesh是Unity中的寻路系统,如果开发的是3D游戏,使用它很合适.里面常用到的几个组件
Navigation面板:烘培场景的寻路网格
OffMeshLink
NavMeshAgent组件:寻路角色
NavMeshObstacle组件:阻挡物(可动态修改)
RaycastHit:射线,用于点击操作
Navigation面板
打开Window-&Navigation面板
在场景中选择需要烘培的Mesh物体
Navigation-&Object中,把物体设置为NavigationStatic
Generate OffMeshLinks选项是设置是否生成和其他物体之间的链接寻路关系(例如跳跃)
点击右下角的Bake按钮,就能看到场景中生成的寻路网格.
unity_xl1.png
OffMeshLink
给一个需要烘培物体添加额外通过的链接(如楼梯,门,传送带)
unityxl2.png
BiDirectional:可以往返寻路如图,红色楼梯区域:角色可以从Start走到End
unityxl3.png
NavMeshAget组件
在一个角色上添加了NavMeshAgent组件之后,角色就可以遵循地图上烘培好的寻路网格进行移动,移动代码在后面使用RaycastHit捕捉鼠标点击的例子.
unityxl4.png
NavMeshObstacle组件
NavMeshObstacle是用来设置阻碍物,当它开启时会在寻路网格上生成一个网孔,以防止移动.
unityxl5.png
一个物体不能同时开启NavMeshAget和NavMeshObstacle,但是可以在运行时实时修改其开关.
RaycastHit
最后使用RaycastHit在场景中拾取移动的坐标,配合NavMesh等组件进行移动
using UnityE
using System.C
public class MovePick : MonoBehaviour {
void Start () {
agent = GetComponent&NavMeshAgent& ();
obstacle = GetComponent&NavMeshObstacle& ();
obstacle.enabled =
void Update () {
if (Input.GetMouseButtonDown (0)) {
if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit, 100)) {
agent.enabled =
obstacle.enabled =
agent.SetDestination(hit.point);
if (agent.enabled && agent.remainingDistance & 1 && agent.remainingDistance & 0.5) {
agent.Stop(true);
agent.enabled =
obstacle.enabled =
产品经理+交互设计师+视觉设计师+ios开发者+unity开发者+React+Nodejs

我要回帖

更多关于 unity 寻路绕过障碍物 的文章

 

随机推荐