官术网_书友最值得收藏!

  • 騰訊游戲開發精粹
  • 騰訊游戲編著
  • 553字
  • 2019-08-30 16:20:42

1.7 其他需求

1.7.1 如何將角色從障礙區域中移出

在MOBA游戲中有大量的擊飛、擊退等技能,角色被擊中難免會“卡”在障礙區域中,對于這種情況,需要能夠快速地將角色移動到最近的合適位置。因為梯度表示最大的變化方向,所以可以用梯度快速查找合適位置:

如圖1.11所示,n為梯度方向,r=0.5為角色半徑,實線圈位于障礙物內,圓心φ=-0.1;虛線圈位于合適位置,圓心φ=0.6,0.6= r ? (?0.1)。

圖1.11 查找合適位置示意圖

當障礙是凸區域時一次迭代就能找到合適位置,是非凸區域時一次迭代可能無法找到合適位置,而MOBA游戲地圖大多是非凸區域,因此需要多次迭代,直到φ(x′)≥r時停止。以下為迭代計算合適位置的代碼。

    Vector2 newPos = pos;
    for (int i = 0; i < 3; i++) {
        float SD = Sample(newPos);
        if (SD >= playerRadius)
          break;
        newPos += Gradient(newPos) * (playerRadius - SD);
    }

1.7.2 角色不能越過障礙物的遠距離移動

當角色進行瞬時遠距離移動,比如閃現,但又要求不能越過障礙物(能越過障礙物的情況則使用上面的方法)時,就需要進行連續碰撞檢測來規避穿越障礙物的情況。建設使用圓盤投射(Disk Casting)進行規避,基于SDF的圓盤投射的優勢在于迭代步進可以使用當前位置的φ值,如圖1.12所示,這大大減少了迭代次數。

以下為圓盤投射計算位置的代碼。

    // oriPos:原始位置,dir:沖刺方向,radius:角色半徑,maxDist:最大沖刺距離
    public Vector2 DiskCast(Vector2 origin, Vector2 dir, float radius, float maxDist)
    {
        float t = 0f;
        while (true) {
          Vector2 p = origin + dir * t;
          float sd = Sample(p);
          if (sd <= radius) return p;
          t += sd - radius;
            if (t >= maxDist) return origin + dir * maxDist;
        }
      }
主站蜘蛛池模板: 青海省| 昌乐县| 汉中市| 西乌珠穆沁旗| 磐安县| 台北市| 武义县| 瑞安市| 那坡县| 伊宁市| 陵川县| 敦化市| 长垣县| 商城县| 仁化县| 益阳市| 唐河县| 化隆| 科技| 黄平县| 贡觉县| 吉木萨尔县| 大厂| 焦作市| 阳高县| 甘孜| 木里| 灵宝市| 志丹县| 雷山县| 静宁县| 余姚市| 潮州市| 抚顺市| 桂阳县| 福海县| 海安县| 墨脱县| 崇礼县| 大丰市| 襄樊市|