寻路包CAINav学习

来源:互联网 发布:淘宝网大童店铺 编辑:程序博客网 时间:2024/06/05 15:29
包特性简介

CAINav是用于一个基于windows系统下为.net和unity3d工程提供的导航系统。他提供导航网格生成,寻路,本地操作功能。

 

NMGen:导航网格生成

  可以遍历任何几何模型表面来生成多边形网格。
    分离寻路和操作组件,提供更灵活的工作流程和分配方式。
    构建简单,只需一个配置和一些几何源。
    可根据需要定制构建过程。
    各种网格序列化选项。

  当然它也可以构建三角形网格。

 

NMQuery:寻路

    A *和Dijsktra两种算法搜索路径。
    快速在各种局部环境中查询,没有搜索行为。
    易于管理的路径。
    非标准运动网的不同地区之间的自定义连接。(Off-mesh connections。)
    能为每一个代理(可以看为游戏角色)启动/关闭多边形运动。(Polygonfiltering)。
    可以定义每个代理遍历多边形的运动的消耗。(路径越长消耗越大)

tiling和分层网格来处理巨大/很高的几何模型。
    各种导航网格序列化选项。

 

NMCrowd:本地操作

    为20个以上代理提供本地操作/碰撞回避功能。
   每个代理能对面前的其他代理产生反应。
    跟随和群体运动。

下载安装

一.下载Download,这里有一个例子包,一个正式的开发包,我们下载cai-nav-0.3.0.zip。

解压后找到cai-nav-0.3.0\u3d\cai-nav-pro-0.3.0.unitypackage

二.导入,打开我们的unity项目,Assets->Import Package->Custom Package…找到包所在位置。

三.你会发现菜单里面多了两个子菜单项GameObject-> Create CAI 和Component->CAI.

 

 

导航网格生成

有多种方法来生成一个导航网格。但它们都遵循相同的基本过程:

 

1.      在场景上添加一个几何数据源组件并在上面添加GameObjects。

2.      添加一个NMGenBuildConfig组件到场景上。

3.      添加一个BakedPolyMesh组件到场景上,并指定几何模型和配置。

4.      根据自己的需要调整配置。

5.      烘焙网格

6.      如果需要,调整配置再烘烤,直到得到你想要的。

 

你可以手动添加每个组件到场景上,GameObject->Create CAI菜单项让事情变得简单,PolyMesh菜单项提供需要的NMGen组件来构建多边形和细节网格。Navigation Manger 和 Navmesh则提以使用CAINav导航功能所需要的额外组件。

如果你选择PolyMesh菜单项,你将看到下面的对话框:



如果你想手动指定game objects。选择MeshFilter (Array)。如果希望gameobject的选择基于一个或者多个标签,选择MeshFilter(Tagged)项。无论哪种情况,你只需选择或者创建最上层的game objects然后其所有子game object都会被MeshFilter递归检索到。

会生成类似下面的GameObject结构:

 

 

一个示例场景

 

在这个例子中,包含三个GameObjects,他们则包含了一个室内环境的所有模型。

 

在这种情况下,最好的选择是使用MeshFilter(Array)作为几何源。因此,从菜单中选择GameObject->Create CAI->PolyMesh,并使用默认配置。然后指定gameobjects的几何源。



这个特殊场景是按照正常人类的比例来缩放的,我们调整了一些重要的配置。其余的设置通常是基于源的几何模型的类型和大小。使用DeriveConfiguration 按钮,将得到一个良好的开始。



一切准备就绪,按下Bake Mesh按钮来生成多边形和细节网格。并根据需要修改配置后再烘焙。我们就能得到需要的导航网格。

 

导航的扩展

启动和运行导航的基本步骤如下:

1.      添加一个BakedPolyMesh.

2.      添加一个NavmeshTileBridge组件到场景并且指定BakedPolyMesh给他。

3.      添加一个BakedNavmesh组件到场景并且指定NavmeshTileBridge给他

4.      烘焙导航网格

5.      添加一个NavSource组件到场景并且指定BakedNavmesh给他

在运行时,NavSource提供你的脚本使用下面的对象:

  • U3DNavmeshQuery
  • NavmeshQueryFilter
  • Navmesh
  • CrowdManager (Optional)
  • An extents array. (Used by various query methods.)

选择GameObject->Create CAI->Navigation Source会看到



如果选择默认配置,会得到下面的结构:


导航网格查询

U3DNavmeshQuery是一个非常重要的类,我们生成了导航网格的数据,这个类为我们在这些数据里面寻路提供了几乎所有必需的功能。

 

查询功能分为两大类:寻路和本地搜索。

 

寻路使用标准的A*和Dijkstra算法来找到两点之间的最佳路径。路径由多边形引动列表构成,包含了通道的开始到结束点。路径会被校正成为寻路点列表。

 

局部搜索特性提供了

 

许多查询方法需要一个NavmeshQueryFilter.Filters定义区域id的消耗成本(遍历成本)。

 

理解query类最好的方式就是使用他,Sample Pack包含的Query Explorer demo可以试验所有的查询特性。

 

在导航网格里面寻找一个点

 

不首先在导航网格上找到一个有效点,你将什么也不能做。所以第一步是找到这样一个点。

方法:GetNearestPoly(Vector3,Single[], NavmeshQueryFilter, NavmeshPoint)

 

// 这里的'query'是一个U3DNavmeshQuery 对象,'filter'是一个NavmeshQueryFilter 对象.

 

NavmeshPoint result;

float[] extents = new float[3] { 1, 1, 1 };  // Keep this to the minimum extentspractical.

 

NavStatus status = query.GetNearestPoly(point

        ,extents, filter

        , outresult);

 

if (result.polyRef == 0)

{

        // Handle error.  Could not find a result.

        // 这个状态可以检查下是否有什么错误,如果没有

        // 则可能是搜索区域不在任何多边形内。

}

 

// Use the result point, which includes a vectorposition and the reference id of 

// the polygon that contains the point.

 

基本寻路

 

如果你想使用PathCorridor或者CrowdManager,你总是需要长远规划使用NavmeshQuery的基本特性。首先,找到一条路径,然后,校正他。

 

//这里的'query'是一个U3DNavmeshQuery 对象,'filter'是一个NavmeshQueryFilter 对象.

// 'start' 和 'end' 是 NavmeshPoint 在导航网格上.

 

int pathCount;

// 该路径将是多边形引用列表.

uint[] path = new uint[100];  // 最大路径长度

NavStatus status;

 

if (start.polyRef == end.polyRef)

{

        // Noneed to do any planning.

       pathCount = 1;

       path.path[0] = start.polyRef;

}

else

{

        status= query.FindPath(start

                , end

               , filter

               , path

               , out pathCount);

 

        if(NavUtil.Failed(status)

               || path.pathCount == 0)

        {

               // 寻路失败处理.

        }

        else if(end.polyRef != path[pathCount - 1])

        {

            // 处理一部分路径.

            // 也许查询无法找到终点,

            // 或者路径缓冲太小无法保存整个路径

            //  (检测 'status' 可以发现是否是缓冲太小)

        }

 

}

 

// 如果需要矫正路径...

 

const int MaxStraightPath = 4;  // Just getting the first 4 waypoints.

int wpCount;

 

// The waypoints. (x, y, z) * wpCount;

float[] wpPoints = new float[MaxStraightPath * 3];

 

WaypointFlag[] wpFlags = newWaypointFlag[MaxStraightPath];

 

// A list of polygon references.  (The polygon being entered at the waypoint.)

uint[] wpPath = new uint[MaxStraightPath];

 

status = query.GetStraightPath(start.point

        ,goal.point

        , path

        ,0                // The index of thestart of the path.

        ,pathCount        // The length of thepath.

        ,wpPoints

        ,wpFlags

        ,wpPath

        , outwpCount);

 

if (NavUtil.Failed(status) || wpCount == 0)

{

        //Handle the failure.  There should alwaysbe at least one waypoint, 

        thegoal point, for a valid point/path combination,

}

 

// Use the path and waypoints.

0 0
原创粉丝点击