如何放置一个临时对象,并通过我的A *寻路算法检测到它

问题描述:

我有一个功能正常的A *路径查找算法,并且我不试图放置一个对象,让它由路径查找算法拾取,然后如果它阻止路径,则将其删除。我到目前为止的代码如下:如何放置一个临时对象,并通过我的A *寻路算法检测到它

if (Physics.Raycast(ray, out hit)) 
{ 
    Vector3 testPos = new Vector3(hit.transform.position.x, hit.transform.position.y, hit.transform.position.z - 0.633f); 
    if (pathFinding.TestLocation(startPos, endPos, wall, testPos)) 
    { 
     Instantiate(wall, testPos, wall.transform.rotation); 
    } 

    //In the path finding algorithm class 
    public bool TestLocation(Vector3 startPos, Vector3 endPos, GameObject wall, Vector3 position) 
    { 
    GameObject clone = Instantiate(wall, position, wall.transform.rotation); 

    if (FindPath(startPos, endPos)) 
    { 
     Debug.Log(FindPath(startPos, endPos)); 
     Destroy(clone); 
     return true; 
    } else 
    { 
     Destroy(clone); 
     return false; 
    } 
} 

一旦路径被阻断正在建造其绑定到阻止的路径,但不会遮挡物体时,我的代码不会阻止正在生成的目标这ISN”我想要的东西。我很难过,因为这是什么原因造成的,任何帮助将不胜感激。谢谢。

public bool FindPath (Vector3 startPointValue, Vector3 endPointValue) { 
    Vector3 startPosition = new Vector3(startPointValue.x+2.5f, startPointValue.y+0.5f, 0); 
    Vector3 endPosition = new Vector3(endPointValue.x+4, endPointValue.y+1, 0); 

    Node startNode = grid.NodePosition(startPosition); 
    Node endNode = grid.NodePosition(endPosition); 

    List<Node> possiblePaths = new List<Node>(); 
    HashSet<Node> triedPaths = new HashSet<Node>(); 
    possiblePaths.Add(startNode); 

    while(possiblePaths.Count > 0) 
    { 
     Node currentNode = possiblePaths[0]; 
     for (int i = 1; i < possiblePaths.Count; i++) 
     { 
      if (possiblePaths[i].FCost < currentNode.FCost || possiblePaths[i].FCost == currentNode.FCost && possiblePaths[i].hCost < currentNode.hCost) 
      { 
       currentNode = possiblePaths[i]; 
      } 
     } 

     possiblePaths.Remove(currentNode); 
     triedPaths.Add(currentNode); 


     if (currentNode == endNode) 
     { 
      RetracePath(startNode, endNode); 
      //return true; 
     } /*else if (possiblePaths.Count == 0 && !triedPaths.Contains(endNode)) 
     { 
      Debug.Log("Impossible"); 
      RetracePath(startNode, currentNode); 
     }*/ 

     foreach (Node neighbour in grid.GetNeighbours(currentNode)) 
     { 
      if (!neighbour.blocked || triedPaths.Contains(neighbour)) 
      { 
       continue; 
      } 

      int newMovementCostToNeighbour = currentNode.gCost + GetDistance(currentNode, neighbour); 
      if (newMovementCostToNeighbour<neighbour.gCost || !possiblePaths.Contains(neighbour)) 
      { 
       //Debug.Log(newMovementCostToNeighbour); 
       neighbour.gCost = newMovementCostToNeighbour; 
       neighbour.hCost = GetDistance(neighbour, endNode); 

       neighbour.parent = currentNode; 

       if (!possiblePaths.Contains(neighbour)) 
       { 
        possiblePaths.Add(neighbour); 
       } 
      } 
     } 
     if (possiblePaths.Count == 0 && !triedPaths.Contains(endNode)) 
     { 
      //RetracePath(startNode, possiblePaths); 
      Debug.Log("is false"); 
      return false; 
     } 
    } 
    return true; 
} 
+0

删除问题并再次调整相同的事情通常不是一个好主意。 – InBetween

+0

我之前的问题被关闭了,因为它与https://*.com/questions/47372172/detect-if-there-is-any-object-between-two-objects-with-boxcastall重复,而我不完全肯定它是如何在同一个问题 – Bradeurs

+0

@InBetween我可以有一些洞察我应该如何提出这个问题? – Bradeurs

yield return new WaitUntil(IsBlocked);

哦,上帝没有。协程是而不是这里适当的工具,特别是你如何实现它。这是会发生什么:

  1. 评估的IsBlocked()
  2. 返回值假设路径被阻挡,FindPath()将返回false由于放置
  3. IsBlocked()将返回false(边注堵塞:这是倒退(),并设置一些变量
  4. yield将产生,停止进一步处理GetIsBlocked()(无论如何,这种方法没有额外的行,所以这是毫无意义的)。
  5. if (!isBlocked && check)将评估为假
  6. TestLocation()将返回false(和销毁对象)
  7. 其他Update()代码将运行并最终(在下一帧)的产量指令将被重新评估。
  8. IsBlocked()将再次评估,这个时候IsBlocked()将返回true(因为我们破坏了#6遮挡物)
  9. GetIsBlocked()将完成(但这里没有代码来执行)。

我不能猜测由于没有包含更新代码会出现什么奇怪的副作用。

你应该做的,而不是:

  1. 卸下所有协同程序的使用。
  2. 更正IsBlocked()的回报,以便如果是块return true(这将实质上变成可以内联的return !FindPath(a, b);)。
  3. 变化if (!isBlocked && check)if(IsBlocked())
  4. 你不需要变量isBlockedcheck

除此之外,你的逻辑本质上是正确的:

  • 如果路径创建堵塞
  • 检查存在
  • 如果不存在,请移除块/防止放置/丢弃版本号
+0

感谢您的回复。我做了这些改变,但问题仍然存在,我认为问题是我的FindPath方法,我会添加到我的问题。我也将我的问题中的代码更改为您的建议。 – Bradeurs

通过更新我的网格,像往常一样简单修复。 :P

+0

请分享你如何解决你的问题,以便其他具有相同问题的人也可以有解决方案。 – Sefe