Единство - игра по соединению водопроводных труб.Проблема с проверкой подключения объектов труб к центральному источнику - PullRequest
3 голосов
/ 18 марта 2019

Я пытаюсь сделать игру-головоломку, в которой игроку предоставляется сетка труб с одним источником воды. Игрок должен повернуть трубы, чтобы соединить их друг с другом и, конечно, с источником воды.

Проблема, с которой я застрял, заключается в следующем:

Шаг 1:

enter image description here

Шаг 2:

enter image description here

Шаг 3:

enter image description here

Как показано на рисунках, когда я вращаю трубу, которая подключена к группе других труб, соединение с водой не разрывается в оставшейся группе, оно работает только в одной соседней трубе.

Это происходит из-за способа, которым я выполняю соединения, используя группу коллайдеров на каждом выходе труб, как показано на рисунках ниже.

Коллайдеры - Сцена:

enter image description here

Коллайдеры - Иерархия:

enter image description here

Если столкнувшийся объект подключен к воде (посредством bool), он добавляет столкнувшийся объект в список. Если список больше 0, активируется синий спрайт. Если список пуст, деактивирует синий спрайт. Как показано в примере кода ниже.

Триггеры, которые проверяют, связан ли объект с водой:

private void OnTriggerEnter2D(Collider2D other) {
    if (other.GetComponent<FlipPipes2>() != null) {
        isFlowingWater = other.GetComponent<FlipPipes2>().flowingWater;
    }
    if (other.CompareTag("WaterPipe")) {
        if (other.name == "Filled_Cross" || isFlowingWater) {
            myFlipPipes.flowingWater = true;
        }
        TestingScoreStatic.connectedPipes++;
    }
}

private void OnTriggerStay2D(Collider2D other) {
    if (!inList) {
        myFlipPipes.collidedObjectsList.Add(other.gameObject);
        inList = true;
    }
    if (other.name == "Filled_Cross" || isFlowingWater) {
        myFlipPipes.flowingWater = true;
    }
}

private void OnTriggerExit2D(Collider2D other) {
    if (other.CompareTag("WaterPipe")) {
        myFlipPipes.collidedObjectsList.Remove(other.gameObject);
        myFlipPipes.flowingWater = false;
        isConnectedToWater = false;
        TestingScoreStatic.connectedPipes--;
        inList = false;
    }
}

Пример кода фактического изменения спрайта:

private void Update() {
    if (collidedObjectsList.Count > 0) {
        filledPipe.SetActive(true);
    } else {
        filledPipe.SetActive(false);
    }
}

Даже если плитка, подключенная к источнику воды, теряет связь, остальные нет, потому что они все еще связаны с плитками воды.

Как я могу проверить, существует ли правильный путь к источнику воды? Или любой другой способ сделать то, что мне нужно?

Вот некоторые другие примеры кода, которые могут помочь:

Метод создания доски:

private void SetUp() {
    for (int i = 0; i < width; i++) {
        for (int j = 0; j < height; j++) {
            Vector2 tempPosition = new Vector2(i, j);
            int tempIndex = levelManager.levelOne[pipeIndex];
            GameObject pipe = Instantiate(pipes[tempIndex], tempPosition, Quaternion.identity);
            pipe.transform.parent = transform;
            allPipes[i, j] = pipe;
            if (!pipe.CompareTag("WaterPipe")) {
                shuffleSpawnedPipes.pipes.Add(pipe);
            }
            pipeIndex++;
        }
    }
    shuffleSpawnedPipes.ShufflePipes();
}

(Ужасно) Попытка проверить каждую трубу с двойной петлей for:

void IsConnectedToWater() {
    if (column > 0 && column < board.width - 1) {
        GameObject leftPipe1 = board.allPipes[column - 1, row];
        GameObject rightPipe1 = board.allPipes[column + 1, row];
        if (leftPipe1.tag == this.gameObject.tag && rightPipe1.tag == this.gameObject.tag) {
            leftPipe1.GetComponent<Pipe>().connectedToWater = true;
            rightPipe1.GetComponent<Pipe>().connectedToWater = true;
            connectedToWater = true;
        }
    }
}

Конечно, это не работает, потому что он не проверяет, сталкивается ли текущий объект. Даже с проверкой столкновения результат одинаков. Я нахожусь в цикле выполнения множества разных попыток, приводящих к одной и той же вещи.

1 Ответ

1 голос
/ 18 марта 2019

Вам нужен алгоритм поиска пути.

Создайте рекурсивную функцию, которая будет проверять пути к вашему водному источнику. Вместо проверки каждого элемента, подключен ли он к воде, проверьте, находится ли ваш объект водного источника в списке подключенных объектов этой проверенной трубы. Если это не сохранить этот объект трубы в список checkedObjects и перейти к следующему подключенному объекту, повторяйте, пока вы не проверили все объекты трубы, связанные друг с другом. Если ни один из объектов не имел вашего водного источника в списке подключенных объектов, это означает, что все объекты на пути checkedObjects не связаны с водой, и вы можете отключить водный спрайт на всех из них.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...