如何放置一个临时对象,并通过我的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;
}
回答:
yield return new WaitUntil(IsBlocked);
哦,上帝没有。协程是而不是这里适当的工具,特别是你如何实现它。这是会发生什么:
- 评估的
IsBlocked()
- 返回值假设路径被阻挡,
FindPath()
将返回false由于放置 IsBlocked()
将返回false(边注堵塞:这是倒退(),并设置一些变量yield
将产生,停止进一步处理GetIsBlocked()
(无论如何,这种方法没有额外的行,所以这是毫无意义的)。if (!isBlocked && check)
将评估为假TestLocation()
将返回false(和销毁对象)- 其他
Update()
代码将运行并最终(在下一帧)的产量指令将被重新评估。 IsBlocked()
将再次评估,这个时候IsBlocked()
将返回true(因为我们破坏了#6遮挡物)GetIsBlocked()
将完成(但这里没有代码来执行)。
我不能猜测由于没有包含更新代码会出现什么奇怪的副作用。
你应该做的,而不是:
- 卸下所有协同程序的使用。
- 更正
IsBlocked()
的回报,以便如果是块return true
(这将实质上变成可以内联的return !FindPath(a, b);
)。 - 变化
if (!isBlocked && check)
到if(IsBlocked())
- 你不需要变量
isBlocked
和check
除此之外,你的逻辑本质上是正确的:
- 如果路径创建堵塞
- 检查存在
- 如果不存在,请移除块/防止放置/丢弃版本号
回答:
通过更新我的网格,像往常一样简单修复。 :P
以上是 如何放置一个临时对象,并通过我的A *寻路算法检测到它 的全部内容, 来源链接: utcz.com/qa/257334.html