【翻譯搬運】協調多個運動單元的移動 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 [email protected].


寫在最後
上半篇【喵喵丸的博客】【翻譯搬運】協調運動單元的移動 Coordinated Unit Movement【一】
https://blog.csdn.net/u011643833/article/details/79680419

後面一篇即將翻譯該作者在下一個月月刊中發佈的《Implementing Coordinated Movement》
是對協調運動單位運動的更深入解讀。敬請期待。

本篇已經根據原文在雜誌中的刊登格式重新作出了排版。

最後,歡迎各位留言指正~

轉載請註明,出自喵喵丸的博客https://blog.csdn.net/u011643833/article/details/79680425

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章