<@乌龟:>[翻译]开放街道下的竞速类游戏人工智能(3)
选择下一条路.当车辆到达了路口结束的地方,下一个需要决定的问题是,车辆应该往哪个方向开?这个问题取决与这辆车当前所在的车道.车辆选择下一个将去的道路取决与下面的规则(见图二,上一篇文章)
-如果车辆在far-left车道,那么它能向左走或直走.
-如果它在far-right车道,它性能向右走或者直走
-如果它在任何一个中车道,那么它必须直走
-如果它在单行道,那么它随机的选择一个可以通行的路
-如果它在高速路与斜坡的路口处,那么它总是右转
-U型的转弯永远不允许出现,主要是因为样条插值后的路径看起来很不自然
当道路按照顺时针排序的时候,车辆简单的选择争取的车道.举个例子来说吧.当选择了向左走的时候,只是在当前的路口处的索引值(路在路口处的道路数组中的索引)加1.当选择直走的时候,加2;选择右转的时候,减1.
更换车道.如果道路足够的长,那么车辆就需要更换车道以使得每个车道的车的数目大致相同.当车辆以及到了更换道路的点上(通常使用道路总长度的25%),那么车辆将会计算样条以使得车辆可以平滑的从当前车道过渡到目标车道.
这个技术的难点是把当前更换车道车辆的指针用来做碰撞检测.解决方案是将车辆的指针放在每个可能的车道上,在这种状态下,这辆车就是在两个分离的车道上,对他们都进行碰撞检测.
当车辆完成车道转换的之后.它将要处理的下个问题是,那个车道它将去以通过路口(译者按:见上面所说的几种通过路口的条件).这个决定是有必要的,因为车辆在新的车道上可能没办法到达所需要去的目的地.
确定车辆的朝向.当车辆们在城市中开来开去的时候,他们通过了各种各样的路口的道路.AI一个很重要的任务是确定车辆的朝向,以使得车辆可以配合道路和开放区域的外星.因为这里有山,立交桥,还有栅栏隔离着人行道和车道和不平坦的坝子.一个很容易的方法来放置车辆的朝向是从左前,右前,左后,右后来扫描竖直方向的Y轴.首先从计算好了的样条上得到XZ轴上车辆的位置.然三个角关于车辆中心点的位置.然后得到他们的Y坐标
当你得到了三个角的位置后,你就能计算车的方向向量了,这个方法运行效果非常好.只是就算只是缓存了最大的多边形也不能处理当前的所有车辆.一个提高性能的办法是把每条路标记为平的或者不平的.如果车辆在平整的道路上前行,他也不需要去运行完整的检测.取而代之的交通工具仅仅使用道路的顶点数据中的Y坐标就能放置赛车了.另外一个提高性能的办法是放置距离玩家过远的车辆仅仅使用道路的法向量,这种方法当远处看起来很小的车辆就算是方向不是那么正确(译者按:说不定车还有部分看起来在地下的),不过你很难发现这种错误.
管理碰撞状态.当车辆撞到了玩家或者其他的动态或者静态的障碍物时,车辆将会切换到部分或者完全模拟的物理模型中.完全模拟的物理模型将会使得车辆在碰撞中保持真实感.
车辆管理器(Vehicle Manager)控制着车辆当前的模型(物理状态/一般状态).由碰撞管理器(Collision Manager)处理碰撞.比如说:只要当车辆停止移动时,这里管理器就将它设置到部分物理模拟模型中,在这个时候,这辆车试图重新根据运算出的样条曲线回到公路中.当它沿着轨迹移动时,它不会运行任何的障碍物检测.所以它会碰撞到它经过路线上的任何东西.那么一次碰撞将作为消息发送给碰撞管理器.这个循环将会运行有限次.如果当这个循环的次数到达定义的最大值时,这辆车将会停在原地,直到车辆密度管理器(Population Manager)将它重新放置到交通工具池中(ambient vehicle pool).
使用一个故障排除网格(obstacle-avoidance).每个AI实体(entity)在游戏中都处于故障排除网格的一个单元中.这种对应方法允许完全物理模型下的交通工具更快的执行故障排除.
由于道路是由一系列的顶点来定义的,这些顶点自然形成了故障排除桶(bucket)中的点(译者注:这里应该把”桶”理解为”桶排序”中的桶.每个网格中可以有多个车辆),这些桶将城市划分为网格(译者注:也就是刚刚提到的故障排除网格),这样使得碰撞检测的范围降低了.当一辆车沿着它的道路前进的时候,穿越两个单元网格边界使得这辆车从前一个”桶”中被删除,并且添加到新的”桶”中.而且,路口也应该被考虑到故障排除桶中.
环境交通的模拟范围(Simulation bubbles for ambient Traffic).一个运行期间的参数定义了当前城市中需要建立的车辆数目.当车辆被创建了以后,每个车辆都会放在一个车辆池(ambient pool)中,这个车辆池是根据玩家当前的位置而改变的.和这个范围(环境交通的模拟范围)相比,其他地方就不完全模拟了.
当玩家从一个裁剪空间(cull room)移动到另一个时候,车辆密度管理器(Population Manager)把新的裁剪空间的顶点列表和原裁剪空间的顶点列表相比较.从这两个列表中.3个新的列表将会被建造出来:新的道路,已废弃的道路,和没有改变的道路.首先,已废弃的道路将会从活动的道路列表中删除.车辆将会被添加到车辆池中.接着,新的道路将会添加密度等于车辆的总数除以总的道路长度.车辆的密度值是由基于道路类型的默认值设置的,或者是由比赛的AI地图文件设置的(译者注:这儿请参考前文).
由于车辆是随机的在城市里面转来转去,他们有的时候会到达模拟范围的边界.当这种情况发生的时候,车辆有两个选择:1) 如果这个道路的类型是双向(two-way)的,那么车辆将会放置在当前道路相反方向的起点上.2) 如果道路的类型是单行道,那么车辆将会从道路中被删除.使得车辆池中会有新的空间.
在伦敦开车:左右颠倒.伦敦的驾驶员把道路的左边当作是右边.为了适应这种情况,道路的原数据需要做一些改变:
1) 道路的左车道的数据必须复制到右边,反之亦然.(左右颠倒)
2)道路的第一个点变为最后一个点(前后颠倒)
3)道路接近于中线的车道将会变成远离于中线的车道(镜像翻转)
当这些改变实现后,AI的其他实体和逻辑将可以忽略掉具体是靠左行驶还是靠右行驶.这种给了我们具体是要靠左行还是靠右行的灵活性.我们可以在任何一个城市中使用它.
-----------
乌龟和毛驴的技术小屋原创,转载请注明出处