2016-11-26 8 views
1

良い一日の皆さん、私は自分のパスファインディングスクリプトを書いています。最初にそれを紙に書いてコーディングを始めました。私に教えてください。実際には理論よりもはるかに難しいです。だから私は問題に遭遇しましたが、私はもちろん解決できません。パスファインディング - 境界外のインデックス

この問題は、次の画像に現れます。Works perfectly 1)このショットでは、ウェイポイントは(6,6)に設定され、エラーは返されません。 Error 2)右上の2つの点に注意してください。一方はもう一方の方向を示していません。エラーは、上を指すノードです。このショットでは、ウェイポイントは(7,5)に移動し、最後のインデックスから開始してエラーをスローします。ウェイポイントを右下隅に近づけば増えるほど、X軸の下のX = 13の点が例外をスローします。

関連するコード:私は方向に向けたポイントが通行可能かそうでないかどうかを確認するためのチェックを追加するとき

for (int x = 0; x < map.sizeX; x++) 
    { 
     for (int y = 0; y < map.sizeY; y++) 
     { 
      if (!(x == pVal.x && y == pVal.y) && map.grid[x, y].passable) 
      { 
       float dot = 1; 
       var heading = (grid[x, y].position - t.position).normalized; 
       heading.y = 0; 
       foreach (Vector3 direction in map.GetDirections()) 
       { 
        var dot2 = Vector3.Dot(heading, direction.normalized); 
        if (dot > dot2) 
        { 
         if (map.grid[x + (int)direction.x, y + (int)direction.y].passable) 
         { // Error thrown when it reaches this if-statement \\ 
          grid[x, y].direction = direction; 
          dot = dot2; 
         } 
        } 
       } 

      } 
     } 
    } 

このIndex out of Boundsエラーのみがスローされます。注意すべきもう一つは、方向が実際にxとzに格納されているdirection.yを使用することです。 yの代わりにzを使用すると何らかの理由で完全に動作しなくなります。

答えて

3

不明な点がある場合は、テストケースを見て、何がうまくいかないかを確認してください。我々は第二の画像にしているとしましょう

x = 13, y = 12

if (!(x == pVal.x && y == pVal.y) && map.grid[x, y].passable) 

(13、12)が、当社の目標点ではなく、まずまずであるので、我々はこのテストに合格し、次の行に進みます。..あなたには、いくつかのyオフセットを持っている場合は、Yをゼロにする前に、それを正規化するので、それは短いかもしれませんが。

float dot = 1; 
var heading = (grid[x, y].position - t.position).normalized; 
heading.y = 0; 

headingは、ここに(0.659, 0, 0.753)のようなものされて終わります。

foreach (Vector3 direction in map.GetDirections()) 

私はあなたの方向がで保存されている順序かわからないので、私はちょうどここに推測します:を皮切り

{(0, 0, 1), (1, 0, 1), (1, 0, 0), (1, 0, -1)...} 

(0、0、1)、その後...

var dot2 = Vector3.Dot(heading, direction.normalized); 
if (dot > dot2) 

dot依然として1であり、そしてdot2は0.753であるので、我々は、このテストに合格し、それが乱暴に離れる点にもかかわらず、上記細胞は、(通過可能であることを確認我々が行きたい方向から! )すぐにその上より、dot = dot2を設定し、次の方向試してみてください。

(1、0、1)(0.707, 0, 0.707)に正規化を。 dotは0.753であり、dot2は0.466 + 0.532 = 0.998なので、dot > dot2テストに失敗し、この1つをスキップします。 (1、0、0)

dotはまだ0.753であるとdot2が0である:

ここキラーです。659は、私たちはdot > dot2テストに合格し、その方向にセルをチェックするために進ん:

if (map.grid[x + (int)direction.x, y + (int)direction.y].passable) 
{ // Error thrown when it reaches this if-statement \\ 

エラーがスローされません冗談を!我々はすでにat x = 13(すなわちmap.sizeX - 1)だったので、私たちは1を追加したので、ボードの端から離れています!


このエラーは、問題のケースを辿るだけで簡単に検出できます。

可能な修正(ほとんどから最低までハック):あなたはそれがマップをオフにつながる場合は、隣接するセルにアクセスし、それをスキップしようとするたび

  • 境界チェックください。

  • マップの周囲に未使用のグリッドセルの境界を追加すると、エッジから1つのセルをチェックすることで問題が発生することはありません。

  • パス情報をグリッド全体に入力する場合は、幅優先探索(すべての移動が同じコスト)またはDjikstraのアルゴリズム(別々の移動コスト)のような、最短のポイントツーポイントパスが必要な場合はA *を入力します。

1

あなたがif (map.grid[x + (int)direction.x, y + (int)direction.y].passable)を行う前にmap.grid 2D配列の範囲内にあるかどうかを確認する簡単な関数を作成します。

チェックmap.grid[x + (int)direction.x未満map.sizeX-1

ある場合map.grid[ y + (int)direction.y]未満map.sizeY-1であるならば、確認してください。

両方の条件が満たされている場合は、if (map.grid[x + (int)direction.x, y + (int)direction.y].passable)に進みます。ここで

はそれを簡素化するための簡単な関数である。

bool isWithinBound(Vector3 direction, int sizeX, int sizeY, int x, int y) 
{ 
    return ((x + (int)direction.x < sizeX - 1) && (y + (int)direction.y < sizeY - 1)); 
} 

は今、あなただけ行うことができます。

for (int x = 0; x < map.sizeX; x++) 
{ 
    for (int y = 0; y < map.sizeY; y++) 
    { 
     if (!(x == pVal.x && y == pVal.y) && map.grid[x, y].passable) 
     { 
      float dot = 1; 
      var heading = (grid[x, y].position - t.position).normalized; 
      heading.y = 0; 
      foreach (Vector3 direction in map.GetDirections()) 
      { 
       var dot2 = Vector3.Dot(heading, direction.normalized); 
       if (dot > dot2) 
       { 
        //Check if we are within bounds 
        if (isWithinBound(direction, map.sizeX, map.sizeY, x, y)) 
        { 
         if (map.grid[x + (int)direction.x, y + (int)direction.y].passable) 
         { // Error thrown when it reaches this if-statement \\ 
          grid[x, y].direction = direction; 
          dot = dot2; 
         } 
        } 
       } 
      } 
     } 
    } 
} 
関連する問題