Рекомендуемый подход к нескольким коллайдерам

У меня есть некоторые трудности с тем, что, вероятно, очень глупо. У меня есть вражеский игровой объект, который в зависимости от того, где он попал (столкновение) - либо он, либо игра умирает. Я думаю, что самый простой способ описать это, используя классическую игру Super Mario Bros. в качестве примера.

Как вы все знаете, если игрок столкнется с врагом - игрок проиграет - ЕСЛИ он не прыгнет на голову врага, в этом случае враг должен умереть.

враг с коллайдерами

Моя первоначальная идея заключалась в создании двух коллайдеров на игровом объекте:

  1. Синяя рамка представляет BoxCollider2D - который при столкновении с ним приведет к проигрышу игрока (обратите внимание, что он немного ниже сверху)
  2. Зеленая граница представляет BoxCollider2D на дочернем игровом объекте - который при столкновении с ним приведет к смерти игрового объекта.

Ниже приведена упрощенная версия кода, который я использовал:

    // Collider #1
    public void OnCollisionEnter2D(Collision2D collision)
    {
        // Trigger 'Game-Over' logic
    }

    // Collider #2
    public void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.gameObject.tag == "Player")
        {
            Destroy(this.gameObject);
        }
    }

Этот вид работ, однако на мгновение после столкновения с Коллайдером № 1, Коллайдер № 2 также срабатывает - и пока враг уничтожен, игрок также проигрывает.

Я играл со значениями RigidBody2D, чтобы не дать игроку войти во 2-й коллайдер при ударе врага сверху - но, очевидно, с такой силой / скоростью, коллайдеры могут быть немного неточными (или, может быть, я просто делаю это неправильно?).

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

На данный момент я прибег к "единому коллайдеру с простым фрагментом кода, который мне не нравится, и не всегда работает:

    public void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.gameObject.tag == "Player")
        {
            float yVelocity = collision.gameObject.transform.rigidbody2D.velocity.y;

            if (yVelocity < 0)
            {
                Debug.Log("Enemy will lose..." + yVelocity);

                Destroy(this.gameObject);
            }
            else
            {
                // Trigger 'Game-Over' logic
            }
        }
    }

В настоящее время я работаю в режиме 2D, но решения для режима 3D (хотя, возможно, и более сложные, чем необходимо для моего вопроса) также будут рассмотрены.

Спасибо, парни.

3 ответа

Решение

Как разработчик игры, у вас всегда есть много способов решить проблему или создать игровой процесс. Прежде всего, я должен сказать, что вы должны сделать полигональный коллайдер 2d для ваших объектов и персонажей. просто столкновение картинок не очень хорошо, так как я вижу, что вы использовали коробчатые цилиндры в своей игре.

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

другой выбор может быть, когда o объекты сталкиваются, проверяют положение 2 объектов. игрока выше, он убивает, иначе враг убивает игрока.

если вы думаете больше, вы найдете больше ответов. Вы должны исследовать различные пути и найти наиболее эффективные.

Я думаю, что будет легко отключить другой коллайдер, когда он сработает. Вы можете легко включить / отключить коллайдеры с collider.enabled = true; или же collider.enabled = false;

// Collider #1
public void OnCollisionEnter2D(Collision2D collision)
{
    // Trigger 'Game-Over' logic
    // collider2.enabled = false;
}

// Collider #2
public void OnCollisionEnter2D(Collision2D collision)
{
    // collider1.enabled = false;
    if (collision.gameObject.tag == "Player")
    {
        Destroy(this.gameObject);
    }
}

Таким образом, он будет довольно легким и простым в реализации.

Один из способов реализовать то, что вы хотите, - поместить каждый коллайдер в свой дочерний игровой объект и использовать метод IsTouching().

void OnTriggerEnter2D(Collider2D other){
    if(GameObject.Find("Top Trigger").GetComponent<BoxCollider2D>().IsTouching(other)){
        Destroy(transform.gameObject)
    }
    if(GameObject.Find("Bottom Trigger").GetComponent<BoxCollider2D>().IsTouching(other)){
        Destroy(other.gameObject)
    }
}
Другие вопросы по тегам