Обработка коллизий игровых объектов: запуск выполнения кода только один раз

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

Метод 1: использование логического флага
Один простой подход — использовать логический флаг, чтобы отслеживать, был ли уже выполнен код. Вот фрагмент кода, иллюстрирующий этот метод:

bool hasCollided = false;
void OnCollisionEnter(Collision collision)
{
    if (!hasCollided)
    {
        // Your code to be executed once goes here
        hasCollided = true;
    }
}

Метод 2: использование тегов
Unity предоставляет возможность назначать теги игровым объектам. Вы можете использовать теги для идентификации конкретных объектов, участвующих в столкновении, и соответственно выполнять код. Вот пример:

void OnCollisionEnter(Collision collision)
{
    if (collision.gameObject.CompareTag("Tag1") && collision.gameObject.CompareTag("Tag2"))
    {
        // Your code to be executed once goes here
    }
}

Метод 3: использование OnTrigger
Если вы используете триггерные коллайдеры вместо обычных коллайдеров, вы можете использовать функцию OnTriggerEnterвместо OnCollisionEnter. Вот пример:

void OnTriggerEnter(Collider other)
{
    if (other.gameObject.CompareTag("Tag1") && other.gameObject.CompareTag("Tag2"))
    {
        // Your code to be executed once goes here
    }
}

Метод 4. Использование систем событий
Система событий Unity позволяет создавать и обрабатывать собственные события в вашей игре. Вы можете определить событие для столкновения и подписаться на него для выполнения кода. Вот упрощенный пример:

public delegate void CollisionEventHandler();
public static event CollisionEventHandler OnCollision;
void OnCollisionEnter(Collision collision)
{
    if (OnCollision != null)
    {
        OnCollision.Invoke();
        OnCollision = null; // Remove the event subscription to ensure code runs only once
    }
}