Unity 3D: как правильно определить, что столкновение уже обработано для другого участника столкновения? - PullRequest
3 голосов
/ 29 мая 2019

У меня есть класс CollisionHandler, у которого есть метод OnCollisionEnter.Каждая встречная сущность в игре имеет CollisionHandler в качестве компонента.Таким образом, когда сталкиваются 2 объекта, метод OnCollisionEnter вызывается дважды , и это нормально, потому что повреждение и другие вещи обрабатываются в результате прикосновения к объекту "B" объектом "A" и наоборот.

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

private void OnCollisionEnter(Collision collision)
{
    // Calculate the damage caused by `this.gameObject` to `collision.gameObject`.
    // ...

    // Play an impact sound and show a visual effect.
    if (thisObject.CollisionFrameId != Time.frameCount)
    {
        otherObject.CollisionFrameId = Time.frameCount;
        // play sound
        // show hit effect
    }
}

Хотя это работает, я не уверен (я новичок в Unity), что это лучшая практика, и если да, пожалуйста, предложите другие возможные решения.

Обратите внимание, что я не сделал «Почему OnCollisionEnter вызывается дважды?» .Я знаю, почему это происходит.Мой вопрос касается другого, хотя в нем упоминается имя той же функции, которое он не запрашивает.

Ответы [ 3 ]

0 голосов
/ 29 мая 2019

Вы можете использовать систему тегов Unity, помечая действие, которое происходит при столкновении с этим конкретным теговым объектом.

Как пример:

internal void OnTriggerEnter(Collider other)    {

        if (other.gameObject.tag == "Oject Tag") {
            this.GetComponent<AudioSource> ().PlayOneShot (objectTagSoundClip);
        }

Просто нужен звук для воспроизведения, помещенный в игровой объект.

0 голосов
/ 29 мая 2019

Может быть, у вас есть 2 коллайдера.Если это так, вы можете проверить, сталкивается ли, например, boxcollider.Вы также можете приехать в отпуск.Надеюсь, это поможет.

0 голосов
/ 29 мая 2019

Вы можете сделать GetComponent для другого объекта с помощью одного из ваших сценариев (или того же сценария) и установить для RecentCollisionObject текущий сценарий или gameObject (и, возможно, данный период времени только для дополнительной безопасности (если только один запускает его) но не другой почему то)).

При каждом столкновении вы проверяете, является ли RecentCollisionObject другим объектом (и если прошло не более ~ 0,01 секунды). Если это правда, вы знаете , что определенное столкновение уже должно быть уже обработано другим объектом, поэтому сбросьте все значения этого другого объекта и больше ничего не делайте. Таким образом, следующее столкновение, которое произойдет, независимо от того, как скоро, выполнит этот цикл заново и будет работать как положено.

Таким образом, вы позволяете только первому запускать код столкновения выполнять ваш код (как звук). Дело в том, что оба события столкновения выполняются в одном и том же кадре, поэтому независимо от того, какой из них срабатывает первым, вы можете предотвратить запуск второго.

...