【翻译搬运】协调多个运动单元的移动 Coordinated Unit Movement【二】

Coordinated Unit Movement
by Dave Pottinger
原文地址:https://www.gamasutra.com/view/feature/131720/coordinated_unit_movement.php

找到一篇译文 [译] 协调的单位运动 Dalton’s Dev Blog

在该篇译文的评论区 找到了原文刊登物的PDF版本
http://twvideo01.ubm-us.net/o1/vault/GD_Mag_Archives/GDM_January_1999.pdf
Page 42 开始


正文


位置预测 Predicted Positions

Paragraph 1

Now that we have a simple movement algorithm and a list of unit collisions, what else do we need to get decent unit cooperation? Position prediction.

现在我们已经有了一个移动算法,也有一个碰撞列表。那么我们还需要为运动个体协作做什么呢?位置预测

Paragraph 2

Predicted positions are simply a set of positions (with associated orientations and time stamps) that indicate where an object will be in the future (see Figure 4 below). A movement system can calculate these positions using the same movement algorithm that’s used to move the object. The more accurate these positions are, the more useful they are. Position prediction isn’t immediately free, though, so let’s look at how to offset the additional CPU usage.
这里写图片描述
Figure 4. A closer look at the predicted positions.

位置预测是一组位置点(包括相关的方向和时间戳)用来表述将来运动个体在何处(参见下图4)。运动系统可以使用运动个体移动的相同算法来计算出位置预测的点。预测出的位置越准确,用处越大。位置预测并不是没有消耗的,所以我们来看一下如何消除这些额外的CPU使用。
这里写图片描述
图4:预测位置的详细情况

Paragraph 3

The most obvious optimization is to avoid recalculating all of your predicted positions at every frame. A simple rolling list works well (see Figure 5 below); you can roll off the positions that are now in the past and add a few new positions each frame to keep the prediction envelope at the same scale. While this optimization doesn’t get rid of the start-up cost of creating a complete set of prediction positions the first time you move, it does have constant time for the remainder of the movement.
这里写图片描述
Figure 5. Rolling list of predicted positions.

最明显的优化办法是避免每一帧的重复计算预测的位置。一个简单的滚动List可以很好的派上用场(参见图5),可以在每一帧把对于当前来讲过去的位置滚动出列表,并且添加一些新的预测位置点,把预测的列表的长度维持在同一尺度。虽然这个优化方法并不能消除第一次创建整套预测List时的消耗,但是在余下的运动之中消耗时间恒定。
这里写图片描述
图5:预测位置的滚动列表

Paragraph 4

The next optimization is to create a prediction system that handles both points and lines. Because our collision determination system already supports points and lines, it should be easy to add this support to our prediction system. If a unit is traveling in a straight line, we can designate an enclosed volume by using the current position, a future position, and the unit’s soft movement radius. However, if the object has a turn radius, things get a little more complicated. You can try to store the curve as a function, but that’s too costly. Instead, you’re better off doing point sampling to create the right predicted points (see Figure 6 below). In the end, you really want a system that seamlessly supports both point and line predictions, using the lines wherever possible to cut down on the CPU cost.
这里写图片描述
Figure 6. Using predicted positions with a turn radius.

下一项优化是要创建包含点和线的预测系统。因为碰撞检测系统已经支持了点和线,把这些支持扩展到预测系统也不难。如果一个运动个体是直线运动,我们可以用当前位置,将来的位置以及个体移动的软半径制定出一个封闭的体积。然而,如果个体运动是旋转的,事情将会变得更复杂一些。你可以尝试把曲线存储成一个函数,但是这样做的消耗太大。相反,最好使用点采样来创建正确的预测点(参见图6)。最后,如果真的期望无缝支持点和线的预测,那么尽可能的使用线来削减CPU的成本。
这里写图片描述
图6:存在旋转半径时,预测点的状况

Paragraph 5

The last optimization we’ll cover is important and perhaps a little nonintuitive. If we’re going to get this predicted system with as little overhead as possible, we don’t want to duplicate our calculations for every unit by predicting its position and then doing another calculation to move it. Thus, the solution is to predict positions accurately, and then use those positions to move the object. This way, we’re only calculating each move once, so there’s no extra cost aside from the aforementioned extra start-up time.

最后一个优化方案十分重要,但是有些不直观。我们希望通过预测系统尽可能多的预测,但是并不希望每个个体在预测时进行一次计算,移动时再进行一次计算来倍增计算。因此,解决方案是准确的预测位置,使用这些预测位置来移动。这样,我们每一次移动只计算一次,除了上文提到的启动时间无需额外的消耗。

Paragraph 6

In the actual implementation, you’ll probably just pick a single update length to do the prediction. Of course, it’s fairly unlikely that all of the future updates will be consistent. If you blindly move the unit from one predicted position to the next without any regard to what the actual update length currently is, you’re bound to run into some problems. Some games (or some subset of objects in a game) can accept this inaccuracy. Those of us developing all the other games will end up adding some interpolation so that can quickly adjust a series of predicted points that isn’t completely accurate. You also need to recognize when you’re continually adjusting a series of predicted positions so that you cut your losses and just recalculate the entire series.

在实际的实现中,可能只选取一个单独的Update的时长来做预测的根据。当然,想让未来的Update时长全部一致是不太可能的。所以如果盲目的不考虑当前Update的时长而把个体从预测位置移动到下一个位置,将必然遇到一些问题。某些游戏(或者游戏中的对象的子集)可以接受这样的不确定性。除此之外的其他游戏,都会使用插值来调整一系列不完全准确的预测点。也需意识到需要持续调整一系列的预测点,以便减少损失和重新计算整个系列。

Paragraph 7

Most of the rest of the implementation difficulties arise from the fact that we use these predicted positions in collision detection just as we do for the object’s actual current position. You should easily see the combinatorial explosion that’s created by comparing predicted positions for all units in a given area. However, in order to have good coordinated unit movement, we have to know where units are going to be in the near future and what other units they’re likely to hit. This takes a good, fast collision determination system. As with most aspects of a 3D engine, the big optimizations come from quickly eliminating potential interactions, thus allowing you to spend more CPU cycles on the most probable interactions.

其余大部分的实现困难都源于这样一个事实,我们是用那些预测点做碰撞检测,就像是对运动个体当前位置所做检测。很容易就会见到在某个区域为了比照预测位置发生连环爆炸。然而,为了更好的协调各单位的运动,我们必须知道运动个体即将前往的位置以及其他可能碰到的运动单位。这需要一个好而快速的碰撞检测系统。以大多数3D引擎而言,最显著的优化来源于快速消除潜在的互动影响,这样就可以使用更多的CPU来处理大概率发生的互动影响。


单位之间的协作 Unit to Unit Cooperation

Paragraph 1

We’ve created a complex system for determining where an object is going to be in the future. It supports 3D movement, it doesn’t take up much more CPU time than a simple system, and it provides an accurate list of everything we expected a unit to run into in the near future. Now we get to the fun part.

我们已经创建了一个复杂的系统,用来确定一个某个对象未来的状态。他支持三维运动,相比一个简单的系统不会消耗更多的CPU,会为一个个体的未来运动提供出一个准确的列表。现在我们到了有趣的地方。

Paragraph 2

If we do our job well, most of the collisions that we must deal with are future collisions (because we avoid most of the immediate collisions before they even happen). While the baseline approach for any future collision is to stop and repath, it’s important to avoid firing up the pathfinder as much as possible.

如果做好我们的工作,大部分我们要处理的碰撞是发生在未来的碰撞(因为我们已经把大部分可能碰撞发生之前避免掉了)。尽管对于发生在未来的碰撞处理的基本方法是停止和重新制定路线,但是尽可能少的触发寻路器是很重要的。

Paragraph 3

This set of collision resolution rules is a complete breakdown of how to approach the problem of unit-to-unit collision resolution (from a unit’s frame of reference).

这一组碰撞解决规则是单位之间碰撞问题的的完整解析(参考自单位的框架)

未解决的碰撞 Unresolved collisions

Case 1. If both units are not moving:

1. If we’re the lower-priority unit, don’t do anything of our own volition.
2. If we’re the higher-priority unit, figure out which unit (if any) is going to move and tell that unit to make the shortest move possible to resolve the hard collision. Change the collision state to resolving.

案例1. 如果两个单位都不动:

  1. 如果我们是优先级较低的一方,那么不要根据自己的决定做出任何事。
  2. 如果我们是优先级较高的一方,找出将要移动(如果有)的单位,并且告诉这个移动单位找出避免碰撞的最短路径。将这个碰撞的状态变为解决(Resolving)。

Case 2. If we’re not moving, and the other unit is moving, we don’t do anything.

案例2. 如果我们这个单元不动,另一个单元移动,那么我们什么都不做。

Case 3. If we’re moving and the other unit is stopped:

1. If we’re the higher-priority unit, and the lower priority unit can get out of the way, calculate our “get-to point” (the point we need to get to in order to be past the collision) and tell the lower-priority unit to move out of our way (see Figure 7 below). Change the collision state to resolving.
这里写图片描述
Figure 7. Resolving a collision between a moving unit and a stopped unit.
2. Else, if we can avoid the other unit, avoid the other unit and resolve the collision.
3. Else, if we’re the higher-priority unit and we can push the lower-priority unit along our path, push the lower priority-unit. Change the collision state to resolving.
4. Else, stop, repath, and resolve the collision.

案例3. 如果我们这个个体移动,另一个个体停止:

  1. 如果我们是高优先级的个体,并且低优先级的个体容许让路,计算我们的“目的”(我们可以跨过这个碰撞的位置点)位置,并且告诉低优先级的个体移动到我们移动路径之外(参见图7)。将这个碰撞的状态变为解决(Resolving)。
    这里写图片描述
    图7. 解决移动物体和静止物体之间的碰撞问题
  2. 否则,如果我们可以绕开其他物体,绕开并且将这个碰撞的状态变为解决(Resolving)。
  3. 否则,如果我们是高优先级个体,并且可以在我们的路径上运动时推开低优先级的个体,推开低优先级个体,碰撞的状态变为解决(Resolving)。
  4. 否则,停止,重新制定路径,碰撞的状态变为解决(Resolving)。

Case 4. If we’re moving and the other unit is moving:
1. If we’re the lower-priority unit, don’t do anything.
2. If collision with hard radius overlap is inevitable and we’re the higher-priority unit, tell the lower-priority unit to pause, and go to Case 3.
3. Else, if we’re the higher-priority unit, calculate our get-to point and tell the lower-priority unit to slow down enough to avoid the collision.

案例4. 如果我们正在移动,另一个单元也在移动:

  1. 如果我们是优先级较低的一方,那么不做任何事。
  2. 如果“硬质”半径重叠的碰撞不可避免,并且我们是优先级较高的个体,通知低优先级的个体“暂停“,然后跳转到案例3.
  3. 否则,如果我们是高优先级个体,计算我们的“目的”点,并且通知低优先级的个体进行“减速”,来避免碰撞的发生。

标记为解决(Resolving)的碰撞 Resolving Collisions


- If we’re the unit that’s moving in order to resolve a Case 1 collision and we’ve reached our desired point, resolve the collision.
- If we’re the Case 3.1 lower-priority unit and the higher- priority unit has passed its get-to point, start returning to the previous position and resolve the collision.
- If we’re the Case 3.1 higher-priority unit, wait (slow down or stop) until the lower-priority unit has gotten out of the way, then continue.
- If we’re the Case 3.3 higher-priority unit and the lower-priority unit can now get out of the way, go to Case 3.1.
- If we’re the Case 4.3 lower-priority unit and the higher-priority unit has passed its get-to point, resume normal speed and resolve the collision.

  • 如果我们是案例1的尚在移动个体,当我们到达预想中的点,解决这个碰撞。
  • 如果我们是案例3.1中的低优先级个体,并且高优先的个体已经通过他的“目的”点,那么我们开始返回到自己的初始点,并且解决这个碰撞。
  • 如果我们是案例3.1中的高优先级个体,等待(自己减速或者停止移动)低优先级的个体移动到自己的路径之外为止,继续刚才的运动。
  • 如果我们是案例3.3中的高优先级个体,并且低优先级的单位现在可以移动到自己的路径之外,跳转到案例3.1解决方式
  • 如果我们是案例4.3中的低优先级个体,并且高优先的个体已经通过他的“目的”点,唤醒自己的正常速度,解决这个碰撞。

Paragraph 4

One of the key components of coordinated unit movement is to prioritize and resolve disputes. Without a solid, well-defined priority system, you’re likely to see units doing a merry-go-round dance as each demands that the other move out of its way; no one unit has the ability to say no to a demand. The priority system also has to take the collision severity into account. A simple heuristic is to take the highest-priority hard collision and resolve down through all of the other hard collisions before considering any soft collisions. If the hard collisions are far enough in the future, though, you might want to spend some time resolving more immediate soft collisions.

协调单位个体的运动中关键部分之一是优先级划分和争端解决。如果没有一个可靠的,明确的优先级系统,很容易就会看到两个单位正在旋转舞,因为他们互相要求对方离开自己的移动路径,没有一个单位有能力拒绝对方的要求。优先级系统也必须把碰撞的严重程度纳入考虑的范围。一个启发性的方法是把“硬质”碰撞作为优先级最高的碰撞,再考虑解决“软性”的碰撞之前,将会解决掉所有的“硬质”碰撞。但是,如果一个“硬直”碰撞的发生时间在足够远的将来,你可能希望花费时间来处理当下的“软性”碰撞。

Paragraph 5

Depending on the game, the resolution mechanism might also need to scale based on unit density. If a huge melee battle is creating several compound hard collisions between some swordsmen, you’re better served spending your CPU time resolving all of those combat collisions than resolving a soft collision between two of your resource gatherers on a distant area of the map. An added bonus to tracking these areas of high collision density is that you can influence the pathfinding of other units away from those areas.

根据游戏的不同,解决机制可能需要根绝运动单位的密度来进行调整。如果一个巨大的肉搏战之中,在剑斗士之间发生了数次复合的“硬质”碰撞,我们最好把我们的CPU消耗在解决这些战斗碰撞之上,而不是遥远的区域里面两个资源采集单位的“软性”碰撞。附加追踪区域中的高密度碰撞发生,可以影响寻路,在寻路时让其他的单位远离这些区域。


基本规划 Basic Planning

Paragraph 1

Planning is a key element of unit cooperation. All of these predictions and calculations should be as accurate as possible. Inevitably, though, things will go wrong. One of the biggest mistakes we made with the Age of Empires’ movement was to make every decision within a single frame of reference. Every decision was always made correctly, but we didn’t track that information into future updates. As a result, we ended up with units that would make a decision, encounter a problem during the execution of that decision, and then make a decision that sent them right back on their original path, only to start the whole cycle over again the next update.

计划是单位合作的一个关键元素。所有的预测和计算应该尽可能的准确,但是话虽如此,总是会出错的。我们在《帝国时代》的运动系统中最大的错误之一是根据一帧中的数据为参照做出决定。我们所做的决策通常都是正确的,但是我们没有在未来的Update之中追踪这个决策相关的讯息。结果是,我们对这个单位给出决策作为终结,在执行这个决策的过程中遇到问题,然后做出让他们回到初始的路径的决策,然后在下一个Update中再一次重复整个循环。

Paragraph 2

Planning fixes this tautology. We keep around the old, resolved collisions long enough (defined by some game-specific heuristic) so that we can reference them should we get into a predicament in the future. When we execute an avoidance, for example, we remember what object it is that we’re avoiding. Because we’ll have created a viable resolution plan, there’s no reason to do collision checking with the other unit in the collision unless one of the units gets a new order or some other drastic change takes place. Once we’re done with the avoidance maneuver, we can resume normal collision checking with the other unit. As you’ll see next month, we’ll reuse this planning concept over and over again to accomplish our goals.

计划可以修正这个无意义的重复。我们把旧的、已经解决的碰撞得足够长时间的保存(根据游戏的特性来定义)这样当我们在遇到困境的时候可以参考这些。例如,当我们执行一个回避动作,我们记录我们回避的对象个体。因为我们已经创建了一个可行的解决方案,所以不会与其他碰撞中的个体进行碰撞检测,除非其中的个体得到了新的命令或者发生了一些剧烈的变化。我们一旦完成了回避操作,我们恢复与其他个体的正常的碰撞检测。在下个月的文章中【额外说明】我将稍后进行翻译,我们将反复利用这个规划构想来完成我们的目标。

Paragraph 3

Simple games are a thing of the past; so is simple movement. We’ve covered the basic components necessary for creating a solid, extensible movement system: a state-based movement algorithm, a scalable collision determination system, and a fast position prediction system. All of these components work together to create a deterministic plan for collision resolution.

简单的游戏已经是过去的事情,简单的移动也是同样。我们已经介绍了创建一个可靠的、可扩展的运动系统的必需组件:基于状态的移动算法、可以扩展的碰撞检测系统以及一个快速的位置预测系统。所有这些组件共同工作为碰撞的解决创建一个确定的计划。

Paragraph 4

Next month, we’ll extend these concepts to cover higher-order movement topics, such as group movement, full-blown formation movement, and compound collision resolution. I’ll also go into more detail about some implementation specifics that help solve some of the classic movement problems.

下个月中,我们将会扩展这些概念到更高阶的运动问题,比如,团体运动、展开的队形运动以及复合碰撞的解决。我们还将详细的介绍一些经典运动问题的实现细节。


For Further Info

【额外说明】我这部分就和主体内容关系不大,就不做翻译了

After several close calls, Dave managed to avoid getting a “real job” and joined Ensemble Studios straight out of college a few years ago (just in time to the do the computer-player AI for a little game called AGE OF EMPIRES). These days, Dave spends his time either leading the development of Ensemble Studios’ engines or with his lovely wife Kristen. Dave can be reached at dpottinger@ensemblestudios.com.


写在最后
上半篇【喵喵丸的博客】【翻译搬运】协调运动单元的移动 Coordinated Unit Movement【一】
https://blog.csdn.net/u011643833/article/details/79680419

后面一篇即将翻译该作者在下一个月月刊中发布的《Implementing Coordinated Movement》
是对协调运动单位运动的更深入解读。敬请期待。

本篇已经根据原文在杂志中的刊登格式重新作出了排版。

最后,欢迎各位留言指正~

转载请注明,出自喵喵丸的博客https://blog.csdn.net/u011643833/article/details/79680425

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值