Dimusikus
@Dimusikus
Любитель

Как корректно обрабатывать столкновения пуль с объектами?

Здравствуйте уважаемые специалисты.
Меня замучил один вопрос, он касается обработки результатов столкновения объектов.
Перечитав много исходников в интернете я всегда видел примерно одину и туже концепцию к подходу обработки коллизий пуль
например:

//часть кода висит на пуле врага BulletEnemy:
void OnCollisionEnter2D(Collision2D collision)
{
    if (collision.gameObject.tag == "Player") 
    {
       //получаем компонент отвечающий за жизни Player
       HealthScript playerHealth = collision.GetComponent<HealthScript> ();
       //наносим урон
       playerHealth.Damage (1);
       //уничтожаем пулю
       Destroy(gameobject);
    }     
}

//часть кода висит на пуле Игрока PlayerBullet:
void OnCollisionEnter2D(Collision2D collision)
{
    if (collision.gameObject.tag == "Enemy") 
    {
       //получаем компонент отвечающий за жизни PlayerBullet
       HealthScript enemyHealth = collision.GetComponent<HealthScript> ();
       //убиваем врага
       enemyHealth.Die();
       //уничтожаем пулю
       Destroy(gameobject);
    }     
}


при этом на игроке и враге никакие коллизи с пулями не обрабатываются, код в самих пулях всё делает сам.

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

//часть кода пули врага BulletEnemy
void OnTriggerEnter2D(Collider2D coll)
{
	//при столкновении с Player
	if (coll.transform.CompareTag("Player") )
	{
		//просто уничтожаем пулю, и больше ничего не делаем
		Destroy(gameobject);
	}
}

//часть кода игрока Player
void OnTriggerEnter2D(Collider2D coll)
{
	//если в нас попала пуля врага
	if (coll.transform.CompareTag("BulletEnemy") )
	{
		//уменьшаем себе жизни
		health--;		
		.......
	}
}

//часть кода пули игрока PlayerBullet
void OnTriggerEnter2D(Collider2D coll)
{
	//если пуля игрока попала во врага
	if (coll.transform.CompareTag("Enemy") )
	{
		//просто уничтожаем пулю, и больше ничего не делаем
		Destroy(gameobject);
	}
}

//часть кода врага Enemy
void OnTriggerEnter2D(Collider2D coll)
{
	//если в нас попала пуля игрока
	if (coll.transform.CompareTag("PlayerBullet") )
	{
		//убиваемся
		Die();		
		.......
	}
}


Ответьте пожалуйста правилен ли мой подход? А то у меня есть ощущения что в моём случае могут быть глюки в логическом смысле обработки столкновений. Т.е. я изредка(не часто но было) замечал что пули(выпущенные от Player) пролетали сквозь Enemy(эти Enemy уничтожальсь) а пуля летела дальше как ни в чём не бывало, может быть это случайность , но всё же.
  • Вопрос задан
  • 3051 просмотр
Решения вопроса 1
BasmanovDaniil
@BasmanovDaniil
Геймдизайнер-телепат
Если жертва будет отслеживать попадания, то ей нужно будет знать про все возможные способы нанесения урона и запрашивать у пуль их урон, что довольно странно. Логичнее всего, когда свойства пули хранятся в ней, а не где-либо ещё, и пуля сама наносит урон. Так вам будет проще в случае чего добавить новые свойства оружию, например зажигательные патроны. И лучше будет, если вы в пуле будете через GetComponent доставать не конкретный класс, а интерфейс, например IDamageable, и дёргать метод Damage. Проверять теги тоже не советую, лучше свои и вражеские пули разнести по разным слоям, а возможность столкновения указать в матрице в настройках проекта.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы