Я делаю игру, в которой игрок должен вращать трубы, чтобы соединить их с источником воды, но в определенный момент я получаю переполнение стека , и я не знаю, где и почему,Есть ли подходящие алгоритмы поиска пути для этой ситуации?
Первый уровень пока выглядит следующим образом:

"Сетка" - 9x9.Синий крестик является источником воды, и другие трубы должны проверить, имеют ли они правильный путь к источнику.
Каждый объект трубы выглядит следующим образом:

Он состоит из родительского элемента game object
для хранения всего, обводненного объекта трубы, collider
для обнаружения щелчков мыши и 3 circle colliders
для обнаружения столкновения с другими каналами.Эта установка со всеми этими коллайдерами - это то, что мне удалось заставить работать.У пустой трубы и заполненной трубы есть polygon collider
, чтобы предотвратить столкновение с circe colliders
в странных углах.Объекты 3 circle collider
необходимы из-за разных входов канала.
Теперь о коде:
Я попытался создать алгоритм поиска пути самостоятельно, чтобы проверить, есть ли у каждого тайладействительный путь к источнику воды.Я понятия не имею, почему это вызывает переполнение стека.
Вот метод поиска пути:
public bool FindSourceOfWater() {
foreach (var item in collidedList) {
if (!checkedObjectsList.Contains(item)) {
Pipe targetObjectScript = item.GetComponent<Pipe>();
checkedObjectsList.Add(item);
if (item.CompareTag("Pipes_WaterSource")) {
checkedObjectsList.Clear();
return true;
} else {
targetObjectScript.checkedObjectsList.Add(gameObject);
if (targetObjectScript.FindSourceOfWater()) {
checkedObjectsList.Clear();
return true;
}
}
}
}
checkedObjectsList.Clear();
return false;
}
Что делает код:
- Каждый в настоящее время столкнулсяТовар добавлен в список.Foreach пробегает этот список.
- Если целевого объекта нет в списке уже проверенных объектов, продолжайте.
- Получите тот же сценарий в целевом объекте и добавьте этот объект в список уже проверенных объектов.
- Если тег из целевого объекта математический, очистите список проверенных объектов и верните true.Это означает, что объект, вызвавший метод, подключен к источнику воды.
- Если тег не совпадает, добавьте этот объект в список уже проверенных объектов цели (чтобы предотвратить бесконечный цикл).
- Теперь он вызывает целевой метод FindSourceOfWater.
- Если вызванный метод возвращает true, то этот экземпляр также возвращает true.
- Если нет, переходите к следующему объекту, с которым столкнулись.
Методы вызываютсяво время обновления:
private void Update() {
if (collidedList.Count != 0) {
isConnectedToWaterSource = FindSourceOfWater();
} else {
isConnectedToWaterSource = false;
}
if (isConnectedToWaterSource && !filledPipe.activeSelf) {
filledPipe.SetActive(true);
} else if (!isConnectedToWaterSource && filledPipe.activeSelf) {
filledPipe.SetActive(false);
}
}
Ошибка StackOverflow ссылается на эту строку:
if (item.CompareTag("Pipes_WaterSource")) {
Это s intended to return true if it has a valid connection to the water source tile. But i guess it
s, вызывающий метод слишком много раз.Может быть, потому что это было вызвано в обновлении?Так что все проверяют источник воды одновременно.