Unity обрабатывает несколько коллайдеров с разным назначением

#unity3d

#c# #unity3d #обнаружение столкновений

Вопрос:

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

Второй — это сферический коллайдер, который я хочу использовать для обнаружения игрока и его союзников. У этого коллайдера для свойства isTrigger установлено значение true (у BoxCollider этого нет).

Моя проблема в том, что, когда мой игрок запускает снаряд, он сначала попадает в сферический коллайдер. Сферический коллайдер рассматривается как хитбокс, и мой враг получает урон. Вот сценарий снаряда:

 void OnTriggerEnter (Collider col)
{
    if (col.gameObject.tag == "Player")
    {
        AUnit a = col.gameObject.GetComponent<AUnit>();
        if (a != null)
        {
            a.takeDamage(damage);
            if (goThrough == false)
                Destroy(gameObject);
        }
    }
}
 

Мой вопрос довольно прост: как я могу сделать, чтобы обнаружить только обнаружение BoxCollider и игнорировать SphereCollider?

Ответ №1:

Этого можно достичь с помощью обнаружения столкновений на основе уровней.

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

Комментарии:

1. Я согласен с коллизией на основе слоев, но обратите внимание, что вы не хотите, чтобы сам игрок находился на другом уровне, а просто это SphereCollider, или ваш снаряд никогда не обнаружит BoxCollider, чтобы вызвать повреждение. Добавьте пустой дочерний элемент для хранения вашего SpereCollider и его логики на другом уровне, отличном от уровня player и ballistic logic 😉

2. @Frohlich точно. Кроме того, добавление пустого дочернего элемента и отсутствие пометки его как родительского также работает.

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

Ответ №2:

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

 public class "ClassNameHere": MonoBehaviour
{
    public BoxCollider2D Collider1;
    public CircleCollider2D Collider2;
    public CircleCollider2D Collider3;

    private void OnCollisionEnter2D(Collision2D other)
    {
        if(other.collider==Collider1)
        {
          Debug.Log("1");
        }
        if(other.collider==Collider2)
        {
           Debug.Log("2");
        }
        if(other.collider==Collider3)
        {
           Debug.Log("3")
        }
    }
}
 

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

Однако обратите внимание, что у Collider нет переменной id или чего-то подобного, что позволяет Unity обнаруживать разницу между коллайдерами одного и того же типа в одном и том же игровом объекте. Но пока коллайдеры другого типа, это будет работать.

Если вы хотите использовать 2 коллайдера одного типа для одного объекта, но все же хотите заметить разницу, вам, скорее всего, придется перейти к определению класса unity для этого типа collider и добавить общедоступный идентификатор int, float, long или string, который вы можете получить в коде, чтобы узнать, какой коллайдеропределенного типа, с которым вы взаимодействуете.