для некоторого контекста я создаю простую игру для университетского проекта, где есть несколько отдельных "островков", по которым игрок может пройти.
У игрока также есть собака-компаньон, которая использует алгоритм поиска путей A *, который случайным образом выбирает область в пределах определенного диапазона игрока, проверяет, могут ли они там ходить, и не слишком ли близко к месту, где собака уже есть и возвращает истину или нет.
Проблема, с которой я сталкиваюсь, заключается в том, что пока код работает в некоторой степени идеально на первом острове, при переходе на второй остров кажется, что каждый путь, по которому собака пытается пройти, отклонено и вызывает ошибку переполнения стека.
Я посмотрел на инспектор отладки в пределах единства, чтобы убедиться, что сценарии ссылаются на сценарии, от которых они зависят, а не от сценариев первых островов, но все это кажется будь прав.
Надеюсь, мне удастся взглянуть на это как можно скорее, поскольку я работаю над этим всего несколько дней.
Код, над которым создается ошибка:
public Node NodeFromWorldPoint(Vector3 worldPosition)
{
float percentX = (worldPosition.x - transform.position.x) / gridWorldSize.x + 0.5f - (nodeRadius / gridWorldSize.x);
float percentY = (worldPosition.z - transform.position.z) / gridWorldSize.y + 0.5f - (nodeRadius / gridWorldSize.y);
percentX = Mathf.Clamp01(percentX);
percentY = Mathf.Clamp01(percentY);
int x = Mathf.FloorToInt(Mathf.Min(gridSizeX * percentX, gridSizeX-1));
int y = Mathf.FloorToInt(Mathf.Min(gridSizeY * percentY, gridSizeY - 1));
return grid[x, y];
}
Это код, который генерирует случайное местоположение в пределах диапазона и возвращает, если он действителен или нет:
public Vector3 GetRandomPointInBounds(Bounds bounds)
{
desintationReached = false;
Vector2 location;
location = new Vector2(
Random.Range(bounds.min.x, bounds.max.x),
Random.Range(bounds.min.y, bounds.max.y)
);
if (CheckIfPointInCollider(location))
{
//Debug.DrawLine(transform.position, location,Color.green,20f);
return new Vector3(location.x, location.y, 0);
}
else
{
Debug.DrawLine(transform.position, location, Color.red, 0.1f);
//Debug.Log("Invalid Location:" + location);
return GetRandomPointInBounds(bounds);
}
}
public bool CheckIfPointInCollider(Vector2 location)
{
Node targetNode = grid.NodeFromWorldPoint(new Vector3(location.x, location.y, 0));
if (targetNode.walkable && !rangeToIgnore.OverlapPoint(location))
{
return true;
}
else
{
return false;
}
}
Вот код, который перемещается между первым объектом сетки и вторым :
public void Launch()
{
// Increasing Current Island Count
gm.IncreaseIsland();
Debug.Log("Transitioning to island: " + gm.GetCurrentIsland());
// Enabling & Disabling Monty, Player, Canoe Single and their depencies
canoeAIO.transform.position = canoeSpawnPoints[0].transform.GetChild(currentIsland).transform.position;
canoeAIO.SetActive(true);
canoeAIO.GetComponent<CanoePaddle>().beached = false;
canoeAIO.GetComponent<CanoePaddle>().canPaddle = true;
canoe.SetActive(false);
player.SetActive(false);
monty.SetActive(false);
layerManager.SetActive(false);
interactionsManager.SetActive(false);
pathwayCollider.SetActive(false);
spritesManager.SetActive(true);
//Setting all other pathfinding managers to inactive
for (int i = 0; i < pathfindingManagers.Length; i++)
{
pathfindingManagers[i].SetActive(false);
}
// Activating the next islands pathfinding and clearing any existing path requests
pathfindingManagers[gm.GetCurrentIsland()].SetActive(true);
PathRequestManager.ClearRequests();
monty.GetComponent<MontyStateActions>().StopAllCoroutines();
montyStateVariables.grid = pathfindingManagers[gm.GetCurrentIsland()].GetComponent<MyGrid>();
montyStateVariables.currentlyOnPath = false;
//hide monty
//hide canoe object
//show canoe all in one at the new location
cameraHandler.SwitchToCanoe();
}
(кстати, Монти - это имя собаки :))
Надеюсь, это будет полезно, и если вам понадобится еще какой-нибудь код / изображения, я попробую и загрузите их