Unity基础到入门-导航系统(Navigation)

简介: Unity基础到入门-导航系统(Navigation)

前言


Unity 3D导航系统(Navigation) Unity 3D Navigation(导航)是用于实现动态物体自动寻路的一种技术,它将游戏场景中复杂的结构关系简化为带有一定信息的网格,并在这些网格的基础上通过一系列相应的计算来实现自动寻路

过去,游戏开发者必须自己打造寻路系统,特别是在基于节点的寻路系统中,必须手动地在 AI 使用的点之间进行导航,因此基于节点系统的寻路非常烦琐。

Unity 3D 不仅具有导航功能,还使用了导航网格(navigation meshes),这比手动放置节点更有效率而且更流畅。

更重要的是,还可以一键重新计算整个导航网格,彻底摆脱了手动修改导航节点的复杂方法。


提示:以下是本篇文章正文内容

Unity AI(Navigation)导航系统🤖🤖🤖


种类


image.png

NavMeshAgent类


描述


导航网格代理。

此组件附加到游戏中的某个移动角色,以允许该角色使用导航网格在场景中导航

一、属性、变量、方法


  1. 变量
属性名 作用
desiredVelocity 代理的期望速度,包括来自规避的任何潜在贡献。(只读)
velocity✔ 获取 NavMeshAgent 瞬时速度,或者设置一个速度来手动控制代理。
velocity.magnitude 打印向量的膜。
nav.velocity.sqrMagnitude 返回该向量的平方长度。(只读)
speed 遵循路径时的最大移动速度。
isStopped 导航停止还是恢复。
destination 获取目标点。
stoppingDistance 停止距离。
remainingDistance ✔ 剩余距离。(只读)
areaMask 指定走哪条路,-1(全选),(2^(选几个-1))
isOnOffMeshLink 是否处于分离式导航?(只读)
updatePosition 获取或设置变换位置是否与模拟的代理位置同步。默认值为 true(通过导航更新的位置)。
updateRotation 代理是否应该更新变换方向(通过导航更新的旋转)?
acceleration 代理遵循某一路径时的最大加速度,以单位/秒^2 表示。
agentTypeID 代理的类型 ID。
angularSpeed 遵循路径时的最大回转速度(以 deg/s 为单位)。
autoBraking 代理是否应自动制动以避免越过目标点?
autoRepath 如果现有路径失效,代理是否应尝试获取新的路径?
autoTraverseOffMeshLink 代理是否应自动跨越 OffMeshLink?
avoidancePriority 规避优先级别。
baseOffset 拥有 GameObject 的相对垂直位移。
currentOffMeshLinkData 当前的 OffMeshLinkData。
hasPath 代理当前是否有路径?(只读)
height 代理高度(为了从障碍物下穿过,等)。
isOnNavMesh 代理当前是否绑定到导航网格?(只读)
isPathStale 当前路径过时了吗?(只读)
navMeshOwner 返回当前放置代理的导航网格所属的对象(只读)。
nextOffMeshLinkData 当前路径上的下一个 OffMeshLinkData。
nextPosition 获取或设置导航网格代理的模拟位置。
obstacleAvoidanceType 规避品质级别。
path 获取和设置当前路径的属性。
pathPending 是正在计算过程中而尚未就绪的路径吗?(只读)
pathStatus 当前路径的状态(完整、部分或无效)。
radius 代理的规避半径。
steeringTarget 获取路径中的当前转向目标。(只读)
updateUpAxis 您可以用来指定代理是否应与导航网格的向上轴或者它所在的链接对齐。
  1. 公共函数


属性名 作用
SetDestination 设置导航的目标 如:.SetDestination(Vector 3)
CalculatePath 计算到指定点的路径并存储生成的路径(返回ture) 如:nav.CalculatePath(目标位置, NavMeshPath)

NavMeshPath.corners
获取拐点
💤 💤
ActivateCurrentOffMeshLink 启用或禁用当前的网格外链接。
CompleteOffMeshLink 完成在当前 OffMeshLink 上的移动。
FindClosestEdge 找到最近的导航网格边缘。
GetAreaCost 获取在跨越特定类型的区域时的路径计算成本。
Move 将相对移动应用于当前位置。
Raycast 在导航网格中跟踪一条直线路径到达目标位置,而无需移动代理。
ResetPath 清除当前路径。
SamplePathPosition 沿着当前路径对某一位置进行取样。
SetAreaCost 设置遍历此类型区域的成本。
SetPath 为此代理分配一条新路径。
Warp 将代理调整至指定的位置。
  1. 继承的成员公共函数

image.png

  1. 静态函数

image.png

二、基本使用


  1. 引入命名空间:using UnityEngine.AI;
  2. 勾选静态导航

image.png

2. 烘培

image.png

3. Player舔加NavMeshAgent组件

4. 创建一个目标位置

5. 设置目标位置:NavMeshAgent.SetDestination(Vector 3);

6. 代码展示:🛬🛬🛬🛬🛬🛬

```代码

public Transform tran;

privateNavMeshAgentnav;
voidStart () {
nav=GetComponent<NavMeshAgent>();
}
voidUpdate () {
nav.SetDestination(tran.position);
}
  1. Player 身上的三个箭头
    红色: 指向(阶段性目标)
    蓝色: (阶段性期望速度)
    黑色: (瞬时速度)
  2. image.png

三、分离路面导航🤾‍♀️


普通分离路面

设置分离路面静态

设置方法:选中两个Plane路面,然后选中Off Mesh Link Generation(有两种选择的方法);

分离路面跳跃设置

设置方法:选中面板Navigation->Bake->(DorpHeight(只能从高跳到低)/JumpDistance(双向跳跃)(前提是两个地面的高低差不多))

高级分离路面

舔加offMeshLink组件(挂在两点其中一点上)

使用:

创建两个点分别放在地面的两端

然后拖给offMeshLink组件

选择路线导航

选中要导航的路线

image.png

  1. 舔加Areas名称(给两条路选上名称)

image.png

image.png

  1. 选择要导航的路线名称

image.png

  1. 选择要导航的路线名称

image.png

  1. 代码实现选导航路线
    nav.areaMask获取对应层的编号
    编号的计算公式2^n-1 (n为第几层)
    如:选中4层 :2^3-1
  2. image.png
  3. 例子:
navs=GetComponent<NavMeshAgent>();
navs.areaMask=16;

选中的是第五层公式是2^5-1=16

image.png

四、堵墙


给障碍物舔加组件:NavMeshObstacle组件

image.png

五、Trail组件


4.png

image.png

六、Line组件


说明:线渲染器用于在 3D 空间中绘制自由浮动的线。

变量:

变量
alignment 选择线是朝向摄像机还是变换组件的方向。
colorGradient 设置颜色渐变,用于描述线在其长度上各个点处的颜色。
endColor 设置线终点处的颜色。
endWidth 设置线终点处的宽度。
generateLightingData 配置线以生成法线和切线。借助此数据,场景光照可以通过法线贴图和 Unity 标准着色器或是您自己的定制着色器来影响线。
loop 将线的起点和终点位置连接在一起,以形成连续循环。
numCapVertices 将它设置为大于 0 的值,可在线的每端上获得圆角。
numCornerVertices 将它设置为大于 0 的值,可在线的每个细分段之间获得圆角。
positionCount 设置/获取顶点数。
shadowBias 应用阴影偏差以防止自我阴影瑕疵。指定的值是每一段的线宽比例。
startColor 设置线起点处的颜色。
startWidth 设置线起点处的宽度。
textureMode 选择线纹理的 U 坐标是进行平铺还是拉伸。
useWorldSpace 如果启用,则在世界空间中定义线。
widthCurve 设置曲线,用于描述线在其长度上各个点处的宽度。
widthMultiplier 设置一个整体乘数,它应用于 LineRenderer.widthCurve 以获取线的最终宽度。

公共函数:

image.png

使用鼠标在屏幕画线小案例

image.png

代码演示:

privateboolisDown;
privateboolisUp;
privateboolcurrenIsDown;
privateboolcurrenIsUp;
privateVector3curren;
privateVector3startPos;
privateVector3endPos;
privateLineRendererline;
privateintlineDo;
privateVector3[] Postion=newVector3[10];
privatefloatlineTime;
voidStart()
{
line=GetComponent<LineRenderer>();
}
voidUpdate()
{
curren.x=Input.mousePosition.x;
curren.y=Input.mousePosition.y;
currenIsDown=false;
currenIsUp=false;
isDown=Input.GetMouseButton(0);
if (isDown&&!isUp) currenIsDown=true;
if (!isDown&&isUp) currenIsUp=true;
isUp=isDown;
if (currenIsDown||isDown)
    {
startMove();
    }
}
voidstartMove()
{
startPos=curren;
vara=Camera.main.ScreenToWorldPoint( newVector3(startPos.x,startPos.y,10));
varb=Camera.main.ScreenToWorldPoint( newVector3(endPos.x, endPos.y,10));
if (Vector3.Distance(a, b) >0.1f)
    {
lineDo++;
settingOut();
sendLinePosion();
    }
endPos=curren;
lineTime-=Time.deltaTime;
if (lineTime<0)
    {
lineDo++;
settingOut();
lineTime=0.1f;
    }
}
voidsettingOut()
    {
if (lineDo<=9)
        {
for (inti=lineDo; i<=9; i++)
            {
Postion[i] =Camera.main.ScreenToWorldPoint(newVector3(curren.x, curren.y, 10));
            }
        }
else        {
for (intj=0; j<=8; j++)
            {
Postion[j] =Postion[j+1];
            }
Postion[9] =Camera.main.ScreenToWorldPoint(newVector3(curren.x, curren.y, 10));
        }
    }
///<summary>///将保存的点添加到line上///</summary>privatevoidsendLinePosion()
{
inti=0;
foreach (Vector3iteminPostion)
    {
line.SetPosition(i, item);
i++;
    }
}

NavMesh类


描述


用于访问烘焙导航网格的单例类。

NavMesh 是一个类,可用于执行空间查询(如寻路和步行性测试)、设置特定区域类型的寻路成本以及调整寻路和规避的整体行为。

静态变量:

变量名 作用
SamplePosition 在指定范围内找到导航网格上最近的点。P1
AllAreas 包含所有导航网格区域的区域遮罩常量。
avoidancePredictionTime 描述代理在未来多久后预测碰撞,以便进行规避。
onPreUpdate 设置一个要在执行帧更新期间且在导航网格更新之前调用的函数。
pathfindingIterationsPerFram 异步寻路过程中每帧处理的最大节点数。
静态函数
AddLink 向导航网格添加链接。此链接由 NavMeshLinkData 结构描述。
AddNavMeshData 戏添加指定的导航网格数据。
CalculatePath 两点之间的路径并存储生成的路径。
CalculateTriangulation 计算当前导航网格的三角形剖分。
CreateSettings 创建并返回可用于运行时导航网格构建操作的导航网格构建设置新条目。
FindClosestEdge 从导航网格上的一点找到最近的导航网格边缘。
GetAreaCost 获取区域类型几何体的寻路成本。
GetAreaFromName 返回名为导航网格区域类型的区域索引。
GetSettingsByID 返回导航网格构建设置的现有条目。
GetSettingsByIndex 按其有序索引返回导航网格构建设置的现有条目。
GetSettingsCount 返回已注册的导航网格构建设置的数量。
GetSettingsNameFromID 返回与导航网格构建设置(与提供的代理类型 ID 匹配)关联的名称。
Raycast 在导航网格上的两点之间找出一条线。
RemoveAllNavMeshData 从游戏中删除所有导航网格表面和链接。
RemoveLink 从导航网格中删除链接。
RemoveNavMeshData 从游戏中删除指定的 NavMeshDataInstance,使其无法用于代理和查询。
RemoveSettings 删除与代理类型 ID 匹配的构建设置。
SetAreaCost 设置所有代理上的区域类型几何体的寻路成本。

委托:

image.png

代码:

P1NavMeshHithit;
NavMesh.SamplePosition(目标点, outhit, 范围, layer) ?enemyRandomPoint : transform.position;
作用说明:在指定范围内找到导航网格上最近的点,如果找到就就执行enemyRandomPoint函数(自己创建的🙃)返回一个随机的坐标继续导航,如果没找到就是他自己的位置,就不会导致卡障碍物的旁边。


相关文章
|
3月前
|
定位技术 C# 图形学
Unity和C#游戏编程入门:创建迷宫小球游戏示例
Unity和C#游戏编程入门:创建迷宫小球游戏示例
73 2
|
4月前
|
算法 图形学
Unity——导航系统补充说明
Unity——导航系统补充说明
|
4月前
|
人工智能 算法 BI
Unity——脚本与导航系统
Unity——脚本与导航系统
|
4月前
|
C# 图形学
Unity的几个入门小常识
Unity的几个入门小常识
|
4月前
|
人工智能 C# 图形学
Unity入门
Unity入门
|
10月前
|
前端开发 C# 图形学
unity入门必备的案例2.0
unity入门必备的案例你还不知道?
63 0
|
10月前
|
前端开发 C# 图形学
unity入门必备的案例你还不知道?
unity入门必备的案例你还不知道?
131 0
|
人工智能 图形学
Unity Rain Ai 插件的使用入门(三)
Unity Rain Ai 插件的使用入门
185 0
Unity Rain Ai 插件的使用入门(三)
|
人工智能 图形学
Unity Rain Ai 插件的使用入门(二)
Unity Rain Ai 插件的使用入门
93 0
Unity Rain Ai 插件的使用入门(二)
|
人工智能 图形学
Unity Rain Ai 插件的使用入门(一)
Unity Rain Ai 插件的使用入门
535 1
Unity Rain Ai 插件的使用入门(一)