RTS本地回避如何完成?


15

当前,我正在模拟物理冲击力以局部避开单位,但是这种方法有时会将单位推离地层,并且当单位结块时会产生非常不利的影响。

对于像《星际争霸2》这样的RTS游戏,如何进行局部回避?是物理模拟还是全能控制器决定一切应该在哪里?我知道这个问题可能有点笼统,所以我专门问如何实现《星际争霸2》的局部回避行为。尽管任何有效的方法都将不胜感激。

我不是在寻找任何代码-只是有用的资源或有关Starcraft 2(或类似游戏)如何处理本地回避的解释。

目前,我已经实现了碰撞检测(带有穿透向量),碰撞力和速度移动。检查每个单元是否相互碰撞-如果它们发生碰撞,则物体会立即被渗透矢量偏移,然后施加碰撞力。然后,另一个循环按其速度移动对象,并将阻力施加到该速度。偏移减轻了施加在结块单元上的过大碰撞力的问题,但是单元有时仍会射出。

我正在寻找的解决方案需要满足以下要求(例如在Starcraft 2中):

  • 对象不会重叠;至少必须解决重叠问题。
  • 物体不会将彼此推开超过必要的距离,因此2个单位可以在一个编队中直立并相互靠近。
  • 当对象聚集到同一目的地时,不应有任何奇怪的行为。
  • 可以支撑不同尺寸甚至不同凸面形状的单元。

到目前为止,我一直在思考的不是检测冲突,而是检测将来的冲突,这样就不会发生重叠。然后应用约束,确保2个单位的速度不会导致它们重叠。我仍然在修改限制重叠之外的移动的算法。


“植绒行为”(谷歌术语)是一个非常广泛的问题,
棘轮怪胎2015年

由于“过于广泛”,这已经在接近的投票队列中了-我倾向于同意。尝试缩小:您尝试了什么?您要避免什么“不良影响”?我是说您想让部队保持编队吗?
Anko 2015年

RTS游戏通常由每个客户端在每台计算机上运行相同的确定性仿真来工作。因此,基本上,如果您可以在一台机器上解决该问题,则可以将相同的解决方案应用于多人游戏情况,无论最终使用哪种本地回避技术。
艾伦·沃尔夫

感谢您对问题的反馈。我将问题缩小了一点,并具体说明了我要完成的工作。
JPtheK9 2015年

这是一个很好的资源:red3d.com/cwr/steer
tbkn23

Answers:


11

似乎您正在寻找的是“ 最佳往复碰撞避免”算法。该先行的纸张也值得一读。尽管可能涉及到一些论文,但该算法背后的理论非常简单:

假设您已经有一个带有代理(单位)的模拟(游戏),这些代理(单位)周围有某种包围盒。此边界体积可能是您已经用于执行碰撞检测和响应的体积。对于每个代理,定义v_p可能基于或不基于代理目标的首选速度。

现在,执行模拟:

  1. 对于每个特工,假设它是固定的,请计算将导致它在将来与任何其他移动特工发生碰撞的所有速度。这可以在“速度空间”中表示为一组相交的半平面(也称为速度障碍物)。
  2. 确定该空间中最接近的点v_p,这是单位的新速度。

如果所有代理都运行相同的算法,则它们将选择相互补充的速度,并避免使用其他代理。在某些情况下,当您直接走进大厅中的某个人并且都试图朝同一方向移开时,可能会引起类似尴尬的事情,但是这些论文涵盖了如何避免这种情况的发生。

为了计算上述算法的两个阶段,您可以使用Minkowski Sums来确定什么是速度障碍,然后使用线性编程模型(例如Simplex算法)来确定v_p避免速度障碍的最接近点。此外,这样做防撞代码为您审阅,并已被移植到C#的游戏引擎,如统一使用。至少已在《战锤40,000:太空海军》以及其他游戏中使用了此技术。


那是一篇了不起的文章,我觉得我从您的解释中读了一半。感谢您提供此信息。
JPtheK9 2015年

0

我不知道您的单元如何工作,但我认为它们就像一个状态机:

可能的状态

  • 跑到(x,y,z)
  • 参加(enemy_id)
  • 收集资源(ressource_id)

如果您关注星际争霸如何解决此问题,您会发现:

  1. 如果有空间可沿某个方向移动,则字符会沿该方向移动。
  2. 如果没有空间,则该单元将移动以腾出空间
  3. 如果需要移动以腾出空间的单元已经有了命令,它将保留该命令,但对其进行稍加修改以最终放置。

这是场景1:

在此处输入图片说明

我有空间去那里吗?是啊 那你去

方案2:

在此处输入图片说明

我有空间去那里吗?不是吗 嘿,你能为我留一些空间吗,你在阻止我。我已经下令前进,但是我会适应你的。

因此,您将需要实现:

  • 单位必须了解周围环境
  • 单元必须具有相互通信的方式
  • 您必须实现一种方法,在使另一个单元不舒适的同时继续执行命令

感谢您提供信息和可视化。现在,我正在使用碰撞检测来发现一个单元是否可以移动到另一个地方或另一个单元是否正在占领它。我要弄清楚的主要事情是某种算法,可以告诉另一台设备移动多少距离或调整多少速度。换句话说,阻塞单元将如何容纳试图通过的单元。
JPtheK9 2015年

由于此行为是在每次物理更新时都会计算出来的,因此您实际上不必告诉距离,它会一直移动直到不妨碍您。对于方向,您只需将两个单位的速度相乘即可扫描,这将使您获得一半的点,以便它在容纳的同时保持运动。之后,您可以尝试使用它以使其更加符合订单或更快地移开。
Antoine

“移动直到不碍事”是什么意思?单元如何首先移动?
JPtheK9 2015年

抱歉,我忘记提及:单位不是状态机。它们在储物柜中具有很多功能,每帧都会进行模拟-除非这些功能仅在激活时才起作用,无论目的地是X距离还是存在目标。单元的运动是其速度的结果,可以通过能力改变它。
JPtheK9 2015年

0

一种方法是让单元自动形成地层,并让它们尝试相对于地层中心保持位置。然后,而不是单独移动每个单元,而是移动地层的中心。

这是使用箱形结构和简单弹簧将单元保持在适当位置的基本方法:

// Defines a phalanx (box) formation
class Formation
    // Center of the box in the world
    Position center;
    // Width in # of units
    int width;
    // Height in # of units
    int height;
    // Space between units
    float scale;
    // How much force units will apply to stay near
    // their assigned spot.
    float springforce;

    // Return a position of a unit at the given row and column
    // Todo: add a rotation to this formation so it can rotate when moving.
    Position GetUnitPhalanxPosition(int row, int column)
        return new Position(center.X + column * scale - width * scale /2, 
                            center.Y + row * scale    - height* scale / 2);

// Represents a simple point object with a velocity and position;
// it belongs to a formation.
class Unit
    Position pos;
    Velocity vel;
    Formation formation;
    // What's our assigned spot in the formation?
    int row;
    int column;

    void Update(float dt)
        // Get the desired target position in the formation
        Position target = formation.GetUnitPhalanxPosition(row, column);
        // Apply a spring force toward the position (todo: you might want to damp this)
        vel += (target - position) * dt * formation.springforce;
        // Move along the velocity vector.
        pos += vel * dt;

谢谢!这是一个非常有趣和创新的解决方案。对于人群的行为/形式,我已经实现了与此类似的功能,但仍然存在单元重叠的问题。如果两个编队相遇会怎样?
JPtheK9 2015年

我认为这取决于设计。最简单的方法就是将另一个转向力施加到远离其他编队的附近单位,如该图所示。您可以做的另一件事是,将玩家选择的编队合并在一起,甚至形成“元编队”
mklingen 2015年

元格式听起来真的很复杂而且有错误:C。您链接的图像可能正是我所需要的。我将对转向力进行更多的研究。您是否有指向该图片文章的链接?
JPtheK9 2015年

我有一个与您类似的问题,很高兴知道您是如何解决的。发表本文后,我想到了一个主意:也许结合探路(A *)进行宏路径规划,同时使用排斥力来避免微碰撞:
ColdSteel

0

我知道有些人不赞成链接转储,但是我发现基于多代理电位域的实时策略游戏机器人方法(ISBN 978-91-7295-160-0)是非常有启发性的论文,它显然传达了远远超出我的阐述。本文探索了使用人工势场(一种源自机器人技术的概念)来促进游戏开发环境中的局部碰撞避免。


谢谢!研究和对我的解释一样有用。我将深入研究本文。
JPtheK9 2015年

我已经建立了一个影响力图,但这对我来说似乎太复杂了。最主要的是为不同单位生成势场以移动它们,并将势场中的数据转换为移动的速度。基本上,我认为这不适用于不同大小的单位。尽管有很多有趣的想法,但它是一本好书。
JPtheK9 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.