2016-11-26 82 views
1

好日子大家,我在寫我自己的尋路的腳本,首先必須在紙上,然後開始編碼,讓我告訴你,這是在實踐中更難比理論。所以,我遇到了一個問題,我當然無法解決。尋路 - 索引越界

的問題提出了自己在下面的圖片:Works perfectly 1)在這幅圖中,航點設置爲(6,6),並返回沒有錯誤。 Error 2)請注意,在右上角的2點,一個沒有顯示出方向上的另一顯示出來。錯誤是指向上的節點。在這個鏡頭中,航點被移到(7,5),此時它開始從最後一個索引開始拋出錯誤。我越動航點接近右下角,在X = 13倒Y軸的多點拋出異常。

相關代碼:

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錯誤是,只有當我添加了檢查,看是否再度朝方向點還說得過去或不拋出。另外要注意的是,我用direction.y在方向實際上是存儲在x和z。出於某種原因,如果我使用z而不是y,它會完全停止工作。

回答

3

有疑問時,嘗試穿行測試案例,看看有什麼不順心。

比方說,我們在第二圖像,x = 13, y = 12

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

(13,12)是不是我們的目標點,並且還過得去,所以我們通過這個測試,並繼續到下一行.. 。

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

heading最終被類似(0.659, 0, 0.753)這裏,但如果你有一些y偏移,因爲你歸零y之前正常化它,它可能會更短。

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,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,所以我們離開了董事會的邊緣!


所以,這個錯誤很容易僅僅通過問題的情況下行走探測。

可能修復(從多到少哈克):

  • 難道每當您嘗試訪問的相鄰小區邊界檢查,並跳過它,如果它會導致從地圖上。

  • 在地圖周圍添加未使用的網格單元的邊框,因此從邊緣檢查一個單元格從不會造成問題。如果你想用路徑信息填充整個網格,考慮切換到一個更傳統的,研究得很好的尋路算法,如廣度優先搜索(所有運算花費相同)或Djikstra算法(不同的移動成本)或A *如果你想要最短的點對點路徑。

1

做一個簡單的函數來檢查,如果你是map.grid二維數組的做if (map.grid[x + (int)direction.x, y + (int)direction.y].passable)之前的範圍內。

檢查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; 
         } 
        } 
       } 
      } 
     } 
    } 
}