Unity 基础入门-导航系统(导航)-NavMeshAgent 类
描述
导航网格代理。
此组件附加到游戏中的某个移动角色,以允许该角色使用导航网格在场景中导航
一、属性、变量、方法
- 变量
属性名 | 作用 |
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 | 您可以用来指定代理是否应与导航网格的向上轴或者它所在的链接对齐。 |
- 公共函数
属性名 | 作用 |
SetDestination | 设置导航的目标 如:.SetDestination(Vector 3)
|
CalculatePath | 计算到指定点的路径并存储生成的路径(返回ture) 如:nav.CalculatePath(目标位置, NavMeshPath) 。 |
获取拐点 |
|
???? | ???? |
ActivateCurrentOffMeshLink | 启用或禁用当前的网格外链接。 |
CompleteOffMeshLink | 完成在当前 OffMeshLink 上的移动。 |
FindClosestEdge | 找到最近的导航网格边缘。 |
GetAreaCost | 获取在跨越特定类型的区域时的路径计算成本。 |
Move | 将相对移动应用于当前位置。 |
Raycast | 在导航网格中跟踪一条直线路径到达目标位置,而无需移动代理。 |
ResetPath | 清除当前路径。 |
SamplePathPosition | 沿着当前路径对某一位置进行取样。 |
SetAreaCost | 设置遍历此类型区域的成本。 |
SetPath | 为此代理分配一条新路径。 |
Warp | 将代理调整至指定的位置。 |
- 继承的成员公共函数
- 静态函数
二、基本使用
- 引入命名空间:using UnityEngine.AI;
- 勾选静态导航
2. 烘培
3. Player舔加NavMeshAgent组件
4. 创建一个目标位置
5. 设置目标位置:NavMeshAgent.SetDestination(Vector 3);
6. 代码展示:????????????????????????
```代码
public Transform tran;
private NavMeshAgent nav; void Start () { nav = GetComponent<NavMeshAgent>(); } void Update () { nav.SetDestination(tran.position); }
- Player 身上的三个箭头
红色: 指向(阶段性目标)
蓝色: (阶段性期望速度)
黑色: (瞬时速度)
三、分离路面导航????♀️
普通分离路面
设置分离路面静态
设置方法:选中两个Plane路面,然后选中Off Mesh Link Generation(有两种选择的方法);
分离路面跳跃设置
设置方法:选中面板Navigation->Bake->(DorpHeight(只能从高跳到低)/JumpDistance(双向跳跃)(前提是两个地面的高低差不多))
高级分离路面
舔加offMeshLink组件(挂在两点其中一点上)
使用:
创建两个点分别放在地面的两端
然后拖给offMeshLink组件
选择路线导航
选中要导航的路线
- 舔加Areas名称(给两条路选上名称)
- 选择要导航的路线名称
- 选择要导航的路线名称
- 代码实现选导航路线
nav.areaMask获取对应层的编号
编号的计算公式2^n-1 (n为第几层)
如:选中4层 :2^3-1 - 例子:
navs = GetComponent<NavMeshAgent>(); navs.areaMask = 16;
选中的是第五层公式是2^5-1=16
四、堵墙
给障碍物舔加组件:NavMeshObstacle组件
五、Trail组件
六、Line组件
说明:线渲染器用于在 3D 空间中绘制*浮动的线。
变量:
变量 | |
alignment | 选择线是朝向摄像机还是变换组件的方向。 |
colorGradient | 设置颜色渐变,用于描述线在其长度上各个点处的颜色。 |
endColor | 设置线终点处的颜色。 |
endWidth | 设置线终点处的宽度。 |
generateLightingData | 配置线以生成法线和切线。借助此数据,场景光照可以通过法线贴图和 Unity 标准着色器或是您自己的定制着色器来影响线。 |
loop | 将线的起点和终点位置连接在一起,以形成连续循环。 |
numCapVertices | 将它设置为大于 0 的值,可在线的每端上获得圆角。 |
numCornerVertices | 将它设置为大于 0 的值,可在线的每个细分段之间获得圆角。 |
positionCount | 设置/获取顶点数。 |
shadowBias | 应用阴影偏差以防止自我阴影瑕疵。指定的值是每一段的线宽比例。 |
startColor | 设置线起点处的颜色。 |
startWidth | 设置线起点处的宽度。 |
textureMode | 选择线纹理的 U 坐标是进行平铺还是拉伸。 |
useWorldSpace | 如果启用,则在世界空间中定义线。 |
widthCurve | 设置曲线,用于描述线在其长度上各个点处的宽度。 |
widthMultiplier | 设置一个整体乘数,它应用于 LineRenderer.widthCurve 以获取线的最终宽度。 |
公共函数:
使用鼠标在屏幕画线小案例
代码演示:
private bool isDown; private bool isUp; private bool currenIsDown; private bool currenIsUp; private Vector3 curren; private Vector3 startPos; private Vector3 endPos; private LineRenderer line; private int lineDo; private Vector3[] Postion=new Vector3[10]; private float lineTime; void Start() { line = GetComponent<LineRenderer>(); } void Update() { 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(); } } void startMove() { startPos = curren; var a = Camera.main.ScreenToWorldPoint( new Vector3(startPos.x,startPos.y,10)); var b = Camera.main.ScreenToWorldPoint( new Vector3(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; } } void settingOut() { if (lineDo <= 9) { for (int i = lineDo; i <= 9; i++) { Postion[i] = Camera.main.ScreenToWorldPoint(new Vector3(curren.x, curren.y, 10)); } } else { for (int j = 0; j <= 8; j++) { Postion[j] = Postion[j + 1]; } Postion[9] = Camera.main.ScreenToWorldPoint(new Vector3(curren.x, curren.y, 10)); } } /// <summary> /// 将保存的点添加到line上 /// </summary> private void sendLinePosion() { int i = 0; foreach (Vector3 item in Postion) { line.SetPosition(i, item); i++; } }