通道是围绕 NavMesh 中从一个地点到另一个地点的路径的可导航空间的简化表示。可以将其当作一种厚路径,如道路。
通道具有直观的结构,以简单方式表示可导航空间。可以轻松访问通道中的信息来计算轨迹,这些轨迹注重人物旋转能力方面的约束以预测即将到来的旋转。
通道是栅门的阵列。两个相邻栅门之间的四边形或三角形称为通道部分。每个部分都完全没有任何 NavMesh 障碍物。请参见以下图:
穿过 NavGraph 的路径与多个通道关联。如果路径周围没有足够空间可获取有效通道,则该通道将在 NavMesh 上拆分。因此,每个存在于 NavMesh 部分的路径可以具有多个通道。所有这些通道将收集到在路径中聚合的 ChannelArray 中。请参见以下图:
通道具有前置部分和后置部分。使用逆时针开放的多段线限定前置通道和后置通道部分。逆时针开放的多段线使用第一个浇口或最后一个浇口闭合。前置通道部分和后置通道部分分别为第一部分和最后一部分的延伸。这些部分是从 NavMesh 边界提取的简化多段线,因此,前置通道部分或后置通道部分中的各个位置都可以看到闭合浇口上的正交投影。请参见以下图:
在没有通道的路径上,根据 NavMesh 上的动态更改计算边界下限和上限以划定路径的可通行部分。下限和上限位于浇口位置,以确保下限和上限间的所有路段无障碍物。如果任何障碍物出现在一个路段,将导致所有路段无效。障碍物出现于前置通道部分和后置通道部分时将分别导致第一部分和最后一部分无效。
可以在寻径查询内创建通道。当使用 Kaim::Bot 中的函数(例如,Kaim::Bot::ComputeNewPathToDestination 或 Kaim::Bot::InitAStarQueryForBot)启动寻径查询时,通道会在人物轨迹模式为 Kaim::TrajectoryMode_Spline 时进行自动计算。如果您初始化并启动寻径查询,可以使用 SetComputeChannelMode 函数启用通道计算。查询将进入 ChannelArray 计算阶段,围绕 NavMesh 上的每个优化路径部分构建新通道。然后,原始路径将被替换为通道聚合和基于 NavGraph 的未更改原始路径部分。
通道是通过收集围绕原始优化路径的自由空间计算的。在找到可用的自由空间之后,半径自适应的线拉伸将在考虑这些角点中最大自由空间的情况下找到强制旋转。这将确定通道的旋转栅门。当旋转之间距离较长时,然后将添加中间栅门,以扩大所有可能位置的可用空间,用于在轨迹中找到更宽的旋转。
SDK 与维护和跟随基于圆弧的样条线(与通道相适应)的 SplineTrajectory 组件一起发行。此 CircleArcSpline 包含圆弧(洋红色)和线段(青色)。请参见以下图:
样条线进行优化以允许在每个侧面上到角点的优选距离,并放置在优选半径的圆上。但是,当通道受到过多约束时,将释放这些约束,而样条线将在这些地点保持不变(次优化)。
若样条线处于降级模式 (SplineComputation_Degraded),则需重新计算样条线。如果不重新计算,在给定的距离内(默认为 5 M)更新通道轨迹时,不会修改当前样条线的尾部。这将提供帧到帧的稳定轨迹,可预测即将到来的旋转。通过 SplineTrajectory 获得精确稳定的信息,使动画系统能够使人物进行动画驱动运动。
您可以访问样条线以了解该样条线上当前人物位置,以及样条线的计算方式。请参见以下示例:
Kaim::ITrajectory* trajectory = m_bot->GetTrajectory(); //The bot has no trajectory, if it does not have a path. Kaim::FollowedCircleArcSpline* followedSpline = trajectory-> GetFollowedCircleArcSpline(); // Give the following information. followedSpline->m_spline;// Previously, trajectory->GetSpline() followedSpline->m_positionOnSpline; //Previously, trajectory->GetPositionOnSpline() followedSpline->m_computationMode
要知道如果必须重新计算路径,您不需要检查样条线的计算模式。可以调用 m_bot->IsPathRecomputationNeeded() 以了解路径是否必须重新计算。
您可以使用 DistanceToInnerCorner () 函数定义狭窄通道内样条线距旋转内角的最短距离。
以前,浮动参数 (distToBorder) 用于计算距边界的距离。当 channelWidth 值过小(小于 distToBorder 的两倍)时,该距离很宽松,因此,样条线可以通过狭窄通道的中部。现在,您可以通过定义分段连续仿射函数自定义此松弛,这可如 channelWidth 函数那样,得出样条线与旋转内侧各个角之间的距离。此函数表示从 (0, 0) 开始的多段线经过几个点,到最后一个点后变为恒定。通过提供多段线点 [p0 to pn] 来进行参数化。不提供 (0, 0) 点,因为第一个分段将自动从 (0, 0) 到 p0 获取。该默认值仅有一个点 (0.4, 0.2),其作用类似于单浮点 distToBorder 参数(默认值为 0.2)。当 channelWidth 为 [0, 0.4] 时,该线性具有的线性系数为 0.5;当 channelWidth 大于 0.4 M 时,其线性系数恒定为 0.2 M。
通常,其用于定义 channelWidth 为较小值时线性系数值较低(例如 y=x/10)的部分,然后在最大距离位置再连接至 y=x/2 的部分。请参见下图: