首页 > 其他分享 >Unity Navigation导航系统

Unity Navigation导航系统

时间:2024-02-07 18:13:30浏览次数:28  
标签:NavMesh 导航 代理 agent 组件 Unity 导航系统 Navigation

一、Navigation导航系统基本介绍

Navigation导航系统是unity的寻路组件,将静态或动态的复杂场景烘焙简化为简单的(NavMesh)导航网格用于AI寻路计算。值得注意的是,这个组件的NavMesh系统存在一些性能和使用场景上的缺陷,如很难在运行时修改navmesh、场景过大会造成内存上的开销,以及不支持垂直面的导航。以上问题可以被新的脚本组件式的NavMesh系统所解决,不过根据需要可以适当使用旧版的系统,接下来我们先介绍旧版的navigation系统打基础,之后再讲解新版的系统。

笼统的来讲,navigation系统包含了四个部分

NavMesh、NavMeshAgent、Off-MeshLink、NavMeshObstacle

即 导航网格、导航网格代理(寻路代理)、离散网格链接、障碍物(多用于动态)

二、旧版组件式Navigation系统

Navigation窗口在window->AI->Navigation处打开
image

1.Navigation组件面板

Navigation组件是用于创建可导航的环境的工具。它包括创建和编辑NavMesh、设置导航代理和路径等功能。
image
Agents:NavMesh Agent setting 导航网格代理

agent即代理,主要是为需要导航的游戏物体生成一个对应的圆柱体以用来在navmesh上进行导航计算(如上图)。

不同的Name属性代表不同的代理,比如游戏中有玩家有怪物,则所需的代理也不同,“+”按钮即可添加新代理。

radius属性、Height属性记录了代理的体积,即规定了代理能够通过的最小宽度和高度。

StepHeight属性记录代理能够通过的最高阶梯上限,MaxSlope属性记录能够通过的坡面角上限。

需要注意的是,Agents设置中的参数不参与NavMesh的生成,Agents的参数影响的是运行时agent的活动,例如躲避其他agent和动态的障碍

image
Area : NavMesh Area setting 导航网格区域

代理在不同的导航区域有不同的行为,例如有Walkable区域,即可以行走UnWalkable区域即不能行走,Jump区域即是跳跃区域。

用户可以自定义导航区域类型,即可以自定义代理在某一区域的行为。

最右侧的数字即是每个区域所对应的权重,权重越接近于0优先级也就越高。优先级高的区域就会在生成导航路径时被优先考虑。
image
Bake:NavMesh Bake Setting 导航网格烘焙

这一栏与Agents的设置有相似的地方,但Bake不同于Agents的地方在于,Bake中的Radius、Height等等参数是用来生成NavMesh的也就是导航网格。

最终的导航路线生成是在NavMesh的基础上计算的,所以在烘焙NavMesh时,参数的选择就要考虑到不同的agent(如果有的话),否则有可能就会出现一些agent穿模的情况。

总之NavMesh是固定的,生成NavMesh与Agents的设置无关。

Generated Off Mesh Links 是生成NavMesh时自动生成离散链接的选项,DorpHeight决定可以从一个到另一个连续或非连续的NavMesh跳跃下来的最大高度,JumpDistance决定从一个NavMesh平面跳跃到另一个等高NavMesh平面的最大距离。如果要自动生成OffMeshLink就要在Navigation的Object面板或Inspector面板的static下拉选项中当中勾选Generate OffMeshLinks。
image
Object:Bake setting of currently selected object 当前选择物体的烘焙设置

这个页面显示了你当前选择物体的烘焙设置。

Navigation Static:只有勾选了此选项当前物体才参与到生成NavMesh中。

Generate OffMeshLinks:只有勾选了此选项当前物体才会生成OffmeshLink。

Navigation Area:当前导航区域的类型。

2.NavMesh Agent组件面板

NavMesh Agent是Unity中用于导航的组件之一,它可以使游戏对象在NavMesh上移动
image

Agent Type:代理的类型,在Agents面板中定义1

Base Offset:代理的高度偏移

Speed:代理的最大移动速度。

Angular Speed:代理的最大旋转速度。

Acceleration:代理的最大加速度。

Stopping Distance:代理需要到达目标点时停止的距离。

Auto Braking:是否自动刹车以避免超过目标点。

Radius:代理的半径。

Height:代理的高度。

Quality:代理的避障质量

Priority:代理的优先级,用于控制多个代理之间的相对重要性。

Auto Traverse Off Mesh Link:是否允许代理自动穿过断开的NavMesh。可以选择手动控制代理通过OffMeshLink,以控制玩家通过不同offmeshlink的行为。

这些参数可以用于控制代理在NavMesh上的移动和行为,其中一些参数如半径、高度和避障类型对代理的碰撞和障碍物避免非常重要。

3.Off-Mesh Link组件面板

Off-meshLink用于创建穿越可行走导航网格之外的路径
表面。例如,跳过沟渠或栅栏,或在穿过一扇门之前打开一扇门,都可以使用Off-meshLink。
image
Start:开始位置

End:结束位置

Cost Override:可以理解为寻路时被选中的权重值,越低越容易被选择

Activated:是否启用

Auto Update Position:是否在端点移动时自动更新

值得注意的是,手动放置OffMeshLink的时候要注意将其放置在生成的NavMesh上,如果没有放置到位那么Agent在计算路线时会将其忽略。

定义了Off-MeshLink后可以通过手动的方式控制agent通过,总的来说就是在脚本中手动控制agent从start点到end点最后在告诉agent我手动控制完了你可以接管了,具体实现看官方手册。

4.NavMesh Obstacle组件面板

这个组件用于移动的障碍物,在运行时agent计算路径时会将运动的障碍物考虑进去。
image
Shape:障碍物的形状,可以理解为碰撞体的形状,有box和capsule两种

Center、Size:与Collider的设置相似

Carve:只有将这个选项激活这个障碍物才能参与到生成NavMesh中并根据shape的数据在NavMesh上创建孔洞。

Move Threshold:判定这个障碍物在移动的阈值(Threshold )障碍移动超过移动阈值设置的距离时,Unity将其视为移动

Time To Stationary(静止的):障碍物静止时间超过了设定的时间后会被视为静止。

Carve Only Stationary:当启用时,障碍物只有在静止时才会参与NavMesh的生成。

5.手动控制Agent通过Off-MeshLink区域

代码中一些重要的字段及方法

isOnOffMeshLink、currentOffMeshLinkData、autoTraversOffMeshLink、baseOffset、CompleteOffMeshLink();

以上字段及方法都是NavMeshAgent组件上的。

对于不同的OffMeshLink Area,可以通过OffMeshLinkData.offMeshLink.area访问到当前的area类型,进而进行不同的通过操作。

//在offMeshLink的climb区域手动操作agent通过

if(agent.isOnOffMeshLink){

    OffMeshLinkData linkData = agent.currentOffMeshLinkData;

    if(linkData.offMeshLink == null)return;

    //如果当前offmeshlink区域的类型是climb类型

    if(linkData.offMeshLink.area == 3){

        //就暂停agent的自动通过offmeshlink

        agent.autoTraverseOffMeshLink = false;

    }

    if(!agent.autoTraverseOffMeshLink){

        Vector3 startPos = linkData.startPos+Vector3.up*agent.baseOffset;

        Vector3 endPos = linkData.endPos+Vector3.up*agent.baseOffset;

        //先控制agent到startPos

         if(!isOnOffMeshLinkStartPos){

            transform.position = Vector3.MoveTowards(transform.position,startPos,agent.speed*Time.deltaTime);

            if(transform.position.Equals(startPos))isOnOffMeshLinkStartPos = true;

        }

        //再从startPos到endPos

        else{

            climbTimer+=Time.deltaTime;

            transform.position = Vector3.Slerp(startPos,endPos,climbTimer/climbTime);

            if(transform.position == endPos){

                //让agent做最后一点收尾工作彻底通过offmeshlink

                agent.CompleteOffMeshLink();

                //调用CompleteOffMeshLink之后isOnOffMeshLink就为false

            }

        }

    }

}

else{

    //相关变量初始化为下一次通过做准备

    climbTimer = 0.0f;

    agent.autoTraverseOffMeshLink = true;

    isOnOffMeshLinkStartPos = false;

}

三、新版脚本式Navigation导航系统

具体如何使用参考官方手册
一般使用旧版系统就够用了

标签:NavMesh,导航,代理,agent,组件,Unity,导航系统,Navigation
From: https://www.cnblogs.com/HalfDog/p/18011136

相关文章

  • Unity接入 KimiChat 代码示例
    代码usingSystem.Runtime.CompilerServices;usingSystem.Threading.Tasks;usingUnityEngine;usingUnityEngine.Networking;publicclassTestKimi:MonoBehaviour{privatestringapiKey="YourKey";//替换为你的API密钥privatestringapiUrl=......
  • 限制Unity帧率的方式
    1)限制Unity帧率的方式2)只在编辑器内,纹理不开启Read&Write情况下,如何获取纹理所有颜色值3)如何在FBX剔除Lit.shader依4)如何在iPhone12mini设备上禁止竖屏这是第373篇UWA技术知识分享的推送,精选了UWA社区的热门话题,涵盖了UWA问答、社区帖子等技术知识点,助力大家更全面地掌握和学习......
  • 【Unity】记一次卡顿优化(由3D资源面数过多引起)
    这个优化方法可能仅对我有效,我只是做一个记录条件:模型很大,并且shader中使用了Smoothness优化方法打开Mesh引用的模型修改模型Normal为calculate修改SmoothnessSource为fromAngle修改SmoothingAngle降到你可以接收的值,我设置的是20。在unity文档中说的是,通常SmoothingAn......
  • Unity Mono单例(MonoSingleton)C#脚本
    什么是单例模式?单例模式是设计模式的一种,一般来说,使用单例模式的类,在程序中全局只会存在一个实例,并且一般来讲其是全局可被访问的。在unity游戏开发中,单例模式广泛应用于GameManager和各种Controller这种只需要一个实例的脚本。以下就是UnityMono单例的泛用脚本usingSystem.......
  • Unity打包Android报错:Target Android SDK not installed Android SDK does not includ
    1.需要查看当前unity版本中安装的SDKVersion2.找到对应路径下的文件,打开build-tools文件,其中就是对应的SDKVersion4.修改Unity中对应的配置 ......
  • Unity Animation动画系统概述
    一、UnityAnimation动画系统基本介绍unity提供了一套非常强大灵活且成熟的动画系统,不论是2d还是3d动画都有相应的组件和接口提供给开发者使用,不过这篇文章主要还是讲解3D部分的动画系统。我们在游戏开发时时常需要角色动起来,除了位置上的移动之外,我们还需要匹配角色的行为或玩......
  • Unity 基于群体寻路的解决方案
    群体寻路是一种模拟群体行为的技术,它使得游戏中的角色能够以一种有组织的方式移动。在群体中,每个角色都有自己的目标位置,并且会根据周围的情况决定如何移动。群体寻路可以帮助我们实现一些有趣的场景,比如鸟群飞行、鱼群游动等。在Unity中实现群体寻路,我们可以使用NavMeshAgent组......
  • Unity基于C#事件委托机制
    事件委托是一种用于实现观察者模式的设计模式,它允许对象在发生特定事件时通知其他对象。在Unity中,事件委托机制为开发者提供了一种简单而有效的方式来处理游戏中的事件和交互。一、事件委托的基本概念事件委托是一种特殊的类型,它可以持有一个或多个方法的引用。当某个事件发生时......
  • 很好用的python游戏环境(续):强化学习算法走迷宫游戏环境(导航问题 navigation):分享一个pyt
    前文分享了一个python下的maze游戏环境,本文再给出一个不错的实现项目,这个项目的实现更加的简单,并且可视化界面做的很好看,是用tkinter框架做的可视化:相关:迷宫游戏python实现Github地址:https://github.com/wonanut/Maze-Game/tree/Maze-game-v1.0.7......
  • 很好用的python游戏环境:强化学习算法走迷宫游戏环境(导航问题 navigation):分享一个pyth
    项目的GitHub地址(作者:莫凡):https://github.com/MorvanZhou/mmaze运行的示例代码:importmmazestart=(0,0)end=(10,10)m=mmaze.generate(width=11,height=11,symmetry="horizontal")solutions=m.solve(start=start,end=end)m.plot(solution=solutions[0],star......