#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, который вы можете получить в коде, чтобы узнать, какой коллайдеропределенного типа, с которым вы взаимодействуете.