unity navigation 2d怎么设置两点之间巡逻

2916人阅读
Unity(12)
Navigation系统的使用原理
NavMesh(导航网格)是3D游戏世界中用于实现动态物体自动寻路的一种技术,将游戏中复杂的结构组织关系简化为带有一定信息的网格,在这些网格的基础上通过一系列的计算来实现自动寻路。
在场景中搭建一个斜坡。例如:
创建好后,选中三个对象,这时在检视面板里面的选择Navigation Static(只有被选中为Navigation Static才有网格导航系统)就行。选定Navigation Static之后在Window 菜单下面点击Navigation这时你会发现在检视面板里面增加了一个视图窗口。是Navigation视图窗口。看看官方的解释
首先看下Object选项卡。
Navigation Static &上面说了只有选中了Navigation Static之后才能进行网格导航。
Generate OffMeshLinkes &处于勾选状态的话,网格导航可以Jump和Drop。
Navigation Area 导航网格层(在4.6版本中默认是Default)
接着是Bake选项卡
Agent Radius &烘焙半径,值越小越好
Agent Height &角色所要通过的高度。
Max Slope 最大的坡度。当大于这个坡度时,会被丢弃
Step height 台阶高度。低于这个高度,导航网格地区为连接。
Drop Height 如果这个属性的值是证书,相邻的导航网格表面高度差低于此值,将进行网格连接
Jump distance 跳跃巨鹿。如果这个属性的值是正数,响铃导航网格表面的水平距离低于此值,将进行网格连接。
Min Region Area 最小区域面积 。 如果低于此临界值的区域将被丢弃。
最后,Areas选项卡。
里面存放的是各个层的信息。跟Object选项卡里面的Navigation Area挂钩。
接下来就是在Bake选项卡里面点击Bake,就会发现有如下的场景。
在场景中分别在Plane上添加一个名为Player的对象,在正方体上添加一个名为Target的对象。并在Player上添加NavMeshAgent组件和自动寻路的脚本。在脚本里面写上: GetComponent&NavMeshAgent&().destination = target.之后,一个简单的寻路就完成了。
我们在前面的介绍中讲到了,Jump和Drop的属性(即自动Off Mesh Link)。接下来,我们来实现它们的功能。
在上面的基础上我们只需将Bake选项卡中的Drop Height高度高于Agent Height高度,且在Cube站台上放置Player对象,在Plane的任意位置上放置Target对象即可。运行起来之后我们就可以看到Player从站台上跳下来并跑向Target.
Off Mesh Link组件
上面呢,我们讲到了自动的Off Mesh Link的用法,这下我们来讲解一下手动的Off Mesh Link的用法
首先创建如图的场景,并对场景中的两个Plane和站台Cube进行烘焙,这时也要将Drop Height和Jump Distance的值分别填上。
左边的平面上是Player对象,站台上面的小球是Target对象。连个红色的Cube是用来手动Off Mesh Link的中间变量。地面上的是名为Start的Cube,站台上的是名为End的Cube。给Start Cube添加一个Off Mesh Link组件,并将Start,End &Cube分别拖到组件里面的Start和End位置。在Player身上加个NavMeshAgent 和自动寻路的脚本。脚本的代码跟上面的一样。这时你运行游戏后会发现。小球会跨越两个平面之间的间隙,利用Start &Cube来到达站台上的Target目标。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:30953次
排名:千里之外
原创:19篇
(2)(2)(3)(1)(2)(1)(1)(1)(1)(1)(4)(4)(4)(1)(1)
(window.slotbydup = window.slotbydup || []).push({
id: '4740881',
container: s,
size: '200,200',
display: 'inlay-fix'在寻路计算中,每个连通点都有个代价属性,在实施A*时根据代价估算决定这个这点是否丢进个行走路点队列中。
For examples:
如果陆地网格的代价是1,河流代价是5,从 A点 到 B点,同时可以同过连通点 C点(在陆地)和 D点(在河流),那么计算时代价估算时 C点 小于 D点,那么 C点 就会丢进行走路点队列中
如果有道门是禁止通过的,可以标记这个区域 Door,在 行走对象 的寻路代理中设置计算区域忽略这个 Door,则计算连通点的时候,直接忽略到这个区域所有连通点。
的效果可以通过 1 的代价值调到很大来达到
红色区域 代价值为100
红色区域 代价值为1,等于 蓝色区域 的代价值
1. 增加自定区域 Door 和 对应的代价值
在 Navigation 窗口中,增加个 Door,代价值 100
前三个是系统內建值,获取这些值需要 位移 一下才能获取到正确的值,下面有说
问题参考:
2. 创建对象,标记为 Door
在场景中创建一个Cube对象,并 选中
在 Navigation 窗口的 Object 中标记该区域为 Door
完成,然后就通过调整代价值来看到不同的寻路效果
如果想 行走对象中,禁止行走 Door 区域,可以在 行走对象 的 Nav Mesh Agent 组件中不够选这个 Door,默认是 Everything
获取当前的区域是否是 Door 区域
public void Update()
NavMeshHit navMeshHit
if (NavMesh.SamplePosition(agent.transform.position, out navMeshHit, 0.8f,
1 && NavMesh.GetAreaFromName("Door")))
Debug.LogFormat("--- agent currMask:{0}", navMeshHit.mask)
本文已收录于以下专栏:
相关文章推荐
如果你满足以下条件,我建议你阅读这篇教程:
你想知道如何在表面着色器中进行混色(blend colour)你想实现一个更加真实的积雪效果
我觉得有雪区域向无雪区域过渡的有些突兀...
现在的大部分mmo游戏都有了自动寻路功能。点击场景上的一个位置,角色就会自动寻路过去。中间可能会有很多的障碍物,角色会自动绕过障碍物,最终达到终点。使用Unity来开发手游,自动寻路可以有很多种实现方...
现在的大部分mmo游戏都有了自动寻路功能。点击场景上的一个位置,角色就会自动寻路过去。中间可能会有很多的障碍物,角色会自动绕过障碍物,最终达到终点。今天我们来学习Unity官方内置的寻路插件-Navm...
写这篇文章是以后用到的时候能够快速有效的实现自己的需求,毕竟自己曾经实现过
Unity中的Navigation为我们开发游戏的寻路功能提供了很大的方便。
有以下几个注意点:
设置了 navme...
使用 Render Texture 和 Camera 制作小地图(MinMap)
效果图 思路:
增加一个 摄像机A(Camera),将 摄像机A 所看到的画面 绘制在一张 贴图B(Render T...
在两个 不连通 的寻路网格间,如果想在这两个网格间行走,就需要添加跳跃的连接 Off-mesh Link
官网地址:/Manual/nav-Crea...
Unity自带了摇杆组件,能实现基本的功能。但是要完全实现现在流行的mmo手游的摇杆,需要做比较大的改动。今天我们来学习一个更加强大的组件Easy Touch3.它能方便地更好素材;能指定在某个区域显...
騰讯活动咨询电话是↗7554全国免费专线》王经理接听:活动简介:騰讯官网咨询电话是【0755↗↗3303↗↗7554】《全国免费专线》王经理接听11月11日,騰讯迎来了自己的10岁生...
类似于AOI,在超过范围的物体不绘制,也不同步。
减少客户端不必要的绘制和计算
1. 简单使用在UNET中使用很简单,只需要在不销毁的实例中挂上一个 NetworkProximit...
他的最新文章
讲师:王哲涵
讲师:韦玮
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)24417人阅读
unity(12)
在之前的几篇总,我们已经系统学习了自动寻路插件Navmesh的相关概念和细节。然而,如果要做一个场景精美的手游,需要用到各种复杂的场景地形,而不仅仅是平地上的自动寻路。今天我们将通过一个完整的复杂的实例,来贯穿各个细节。我们将实现一个复杂的场景,角色可以在里面攀爬,跳跃,爬坡。是不是感觉很像当年的CS游戏呢?本案例将会用得一些基本的动画函数,大家可以先结合文档有个大概的了解。本实例是在官方的范例上加工而成。
(转载请注明原文地址)
1.在场景中摆放各种模型,包括地板,斜坡,山体,扶梯等
2.为所有的模型加上Navigation Static和OffMeshLink Generatic(这个根据需要,例如地板与斜坡相连,斜坡就不需要添加OffMeshLink)
3.特殊处理扶梯,需要手动添加Off Mesh Link,设置好开始点和结束点
4.保存场景,烘焙场景
5.添加角色模型,为其加Nav Mesh Agent组件
6.为角色添加一个新脚本,AgentLocomotion.cs,用来处理自动寻路,已经角色动画变换。代码比较长,大家可以结合注释来理解
using UnityE
using System.C
public class AgentLocomotion : MonoBehaviour
private Vector3//目标位置
private NavMeshA
private A//动画
private string locoState = &Locomotion_Stand&;
private Vector3 linkS//OffMeshLink的开始点
private Vector3 linkE//OffMeshLink的结束点
private Quaternion linkR//OffMeshLink的旋转
//是否开始寻路
// Use this for initialization
void Start()
agent = GetComponent&NavMeshAgent&();
//自动移动并关闭OffMeshLinks,即在两个隔离障碍物直接生成的OffMeshLink,agent不会自动越过
agent.autoTraverseOffMeshLink =
//创建动画
AnimationSetup();
//起一个协程,处理动画状态机
StartCoroutine(AnimationStateMachine());
void Update()
//鼠标左键点击
if (Input.GetMouseButtonDown(0))
//摄像机到点击位置的的射线
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit))
//判断点击的是否地形
if (hit.collider.tag.Equals(&Obstacle&))
//点击位置坐标
target = hit.
//每一帧,设置目标点
if (begin)
agent.SetDestination(target);
IEnumerator AnimationStateMachine()
//根据locoState不同的状态来处理,调用相关的函数
while (Application.isPlaying)
yield return StartCoroutine(locoState);
IEnumerator Locomotion_Stand()
UpdateAnimationBlend();
yield return new WaitForSeconds(0);
} while (agent.remainingDistance == 0);
//未到达目标点,转到下一个状态Locomotion_Move
locoState = &Locomotion_Move&;
IEnumerator Locomotion_Move()
UpdateAnimationBlend();
yield return new WaitForSeconds(0);
//角色处于OffMeshLink,根据不同的地点,选择不同动画
if (agent.isOnOffMeshLink)
locoState = SelectLinkAnimation();
return (true);
} while (agent.remainingDistance != 0);
//已经到达目标点,状态转为Stand
locoState = &Locomotion_Stand&;
IEnumerator Locomotion_Jump()
//播放跳跃动画
string linkAnim = &RunJump&;
Vector3 posStart = transform.
agent.Stop(true);
anim.CrossFade(linkAnim, 0.1f, PlayMode.StopAll);
transform.rotation = linkR
//计算新的位置
float tlerp = anim[linkAnim].normalizedT
Vector3 newPos = Vector3.Lerp(posStart, linkEnd, tlerp);
newPos.y += 0.4f * Mathf.Sin(3.14159f * tlerp);
transform.position = newP
yield return new WaitForSeconds(0);
} while (anim[linkAnim].normalizedTime & 1);
//动画恢复到Idle
anim.Play(&Idle&);
pleteOffMeshLink();
agent.Resume();
//下一个状态为Stand
transform.position = linkE
locoState = &Locomotion_Stand&;
IEnumerator Locomotion_Ladder()
//梯子的中心位置
Vector3 linkCenter = (linkStart + linkEnd) * 0.5f;
string linkA
//判断是在梯子上还是梯子下
if (transform.position.y & linkCenter.y)
linkAnim = &Ladder Down&;
linkAnim = &Ladder Up&;
agent.Stop(true);
Quaternion startRot = transform.
Vector3 startPos = transform.
float blendTime = 0.2f;
float tblend = 0f;
//角色的位置插值变化(0.2内变化)
transform.position = Vector3.Lerp(startPos, linkStart, tblend / blendTime);
transform.rotation = Quaternion.Lerp(startRot, linkRotate, tblend / blendTime);
yield return new WaitForSeconds(0);
tblend += Time.deltaT
} while (tblend & blendTime);
//设置位置
transform.position = linkS
//播放动画
anim.CrossFade(linkAnim, 0.1f, PlayMode.StopAll);
agent.ActivateCurrentOffMeshLink(false);
//等待动画结束
yield return new WaitForSeconds(0);
} while (anim[linkAnim].normalizedTime & 1);
agent.ActivateCurrentOffMeshLink(true);
//恢复Idle状态
anim.Play(&Idle&);
transform.position = linkE
pleteOffMeshLink();
agent.Resume();
//下一个状态Stand
locoState = &Locomotion_Stand&;
private string SelectLinkAnimation()
//获得当前的OffMeshLink数据
OffMeshLinkData link = agent.currentOffMeshLinkD
//计算角色当前是在link的开始点还是结束点(因为OffMeshLink是双向的)
float distS = (transform.position - link.startPos).
float distE = (transform.position - link.endPos).
if (distS & distE)
linkStart = link.startP
linkEnd = link.endP
linkStart = link.endP
linkEnd = link.startP
//OffMeshLink的方向
Vector3 alignDir = linkEnd - linkS
alignDir.y = 0;
//计算旋转角度
linkRotate = Quaternion.LookRotation(alignDir);
//判断OffMeshLink是手动的(楼梯)还是自动生成的(跳跃)
if (link.linkType == OffMeshLinkType.LinkTypeManual)
return (&Locomotion_Ladder&);
return (&Locomotion_Jump&);
private void AnimationSetup()
anim = GetComponent&Animation&();
// 把walk和run动画放到同一层,然后同步他们的速度。
anim[&Walk&].layer = 1;
anim[&Run&].layer = 1;
anim.SyncLayer(1);
//设置“跳跃”,“爬楼梯”,“下楼梯”的动画模式和速度
anim[&RunJump&].wrapMode = WrapMode.ClampF
anim[&RunJump&].speed = 2;
anim[&Ladder Up&].wrapMode = WrapMode.ClampF
anim[&Ladder Up&].speed = 2;
anim[&Ladder Down&].wrapMode = WrapMode.ClampF
anim[&Ladder Down&].speed = 2;
//初始化动画状态为Idle
anim.CrossFade(&Idle&, 0.1f, PlayMode.StopAll);
//更新动画融合
private void UpdateAnimationBlend()
//行走速度
float walkAnimationSpeed = 1.5f;
//奔跑速度
float runAnimationSpeed = 4.0f;
//速度阀值(idle和walk的临界点)
float speedThreshold = 0.1f;
//速度,只考虑x和z
Vector3 velocityXZ = new Vector3(agent.velocity.x, 0.0f, agent.velocity.z);
float speed = velocityXZ.
//设置Run动画的速度
anim[&Run&].speed = speed / runAnimationS
//设置Walk动画的速度
anim[&Walk&].speed = speed / walkAnimationS
//根据agent的速度大小,确定animation的播放状态
if (speed & (walkAnimationSpeed + runAnimationSpeed) / 2)
anim.CrossFade(&Run&);
else if (speed & speedThreshold)
anim.CrossFade(&Walk&);
anim.CrossFade(&Idle&, 0.1f, PlayMode.StopAll);
}效果图如下,点击任何一个地点,角色都可以自动寻路过去。中间可能经过不同的障碍物,我们可以看到角色如我们所预料的一样,可以跳跃下来,可以爬楼梯,最终到达目标点。
今天的这个例子比较复杂,要根据寻路网格的类型,来处理角色的动作是普通寻路,还是攀爬,抑或跳跃。这个例子应该是比较接近真实项目了。大家在实际项目中如果还有更加复杂的寻路,欢迎探讨。
2.http://liweizhaolili./
3./Components/class-NavMeshAgent.html
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:513972次
积分:2775
积分:2775
排名:第13638名
原创:14篇
评论:146条
有任何问题欢迎交流
(1)(1)(11)(1)
(window.slotbydup = window.slotbydup || []).push({
id: '4740881',
container: s,
size: '200,200',
display: 'inlay-fix'上次讲解了下Navigation的简单使用, 这次来看看Navigation面板的一些参数
NavigationStatic 勾选后表示该对象参与导航网格的烘培。
OffMeshLink Generation 勾选后可跳跃(Jump)导航网格和下落(Drop)。
NavigationArea 物体烘焙网格属于那个图层,可通过代码让游戏人物走不同的路 & ==================================================================== 来看看烘焙地形的一些相关参数(比如你想地形太突出部分不需要烘焙到自动寻路网格里面等等)
AgentRadius 具有代表性的物体半径,半径越小生成的网格面积越大
AgentHeight 具有代表性的物体的高度
Max Slope 斜坡的坡度
Step Height 台阶高度
Drop Height 允许跳跃最大下落距离
Jump Distance 允许最大的跳跃距离
Manual Voxel Size 不明
Min Region Area 最小范围区域
Height Mesh 不明 设置过参数之后你可以烘焙成这样
& ================================================================ Areas代表烘焙网格所在的图层,共31个图层
阅读(...) 评论()29448人阅读
unity(12)
之前我们一起学习了如何使用Navmesh组件来实现最基本的角色自动寻路。今天我们再继续深入探索Navigation组件的高级功能。在本文中,你将了解到如何在两个隔离层自动生成寻路网格?如何手动指定寻路网格的路线?以及寻路网格层的应用。(本文所用到的模型皆来自Unity3d官网)。
(转载请注明原文地址)
隔离层自动生成寻路网格
(源码scene1.unity)
1.创建Plane实例P1,P2,两者之间出现一条鸿沟。直接控制角色位移是无法通过的。
2.打开Navigation窗口,分别选中P1,P2,分别设置Navigation Static 和OffMeshLink Generatic
3.保存场景,点击场景烘焙按钮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.unity
1.scene1.unity的基础上,将P1,P2的OffMeshLink Generatic去除
2.在P1上新建一个空的GameObject Start,P2上新建一个空的GameObject End
3.选中start,为它添加Off Mesh Link组件 Component-&Navigation-&OffMeshLink
4.设置Off Mesh Link组件的属性,Start Point 为 start,End Point为end
5.烘焙场景。我们可以看到有一条纽带从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设置为Blue
4.添加两个角色,设置他们的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特性,敬请期待!
2.http://liweizhaolili./
3./Components/class-NavMeshAgent.html
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:513974次
积分:2775
积分:2775
排名:第13638名
原创:14篇
评论:146条
有任何问题欢迎交流
(1)(1)(11)(1)
(window.slotbydup = window.slotbydup || []).push({
id: '4740881',
container: s,
size: '200,200',
display: 'inlay-fix'}

我要回帖

更多关于 unity3d navigation 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信