Войти
UnityФорумОбщее

Нанесение урона с помощью collision в FixedUpdate

#0
14:25, 7 июня 2022

Добрый день, появилась потребность засунуть проверку Collision в FixedUpdate, как ни пытался делать, выдавало ошибку или не работало. Имею базовый метод проверки Colission но в нем есть проблема. Персонажу нанесется урон если он подбежит к врагу, но если он будет стоять у врага то урона не будет, хотелось бы реализовать нанесение урона главному герою каждые n секунд как он стоит рядом с врагом, например. Буду очень благодарен
Код | Нанесение урона с помощью collision  в FixedUpdate

#1
(Правка: 15:02) 15:01, 7 июня 2022

Есть OnCollisionStay2D. Туда и пихай таймер проверки нужно ли бить игрока.
Если же у тебя логика типа "получил урон, есть 2 секунды бессмертия" как в старых играх, то делаешь bool поле в классе плеер которое говорит могут ли ударить игрока и там же таймер отката заводишь и тогда в OnCollisionStay2D проdеряешь этот bool

#2
15:11, 7 июня 2022

>Ddd93
Предположу, что так происходит, из-за того, что у вас процедура вызывается только 1 раз, когда вы заходите в зону коллизии.
Персонаж попал в заданную зону - процедура выполнилась
Пока персонаж в зоне - ничего не происходит
Персонаж вышел зашел - опять сработала процедура.

Так же предположу (я не работаю с OnCollision), что в FixedUpdate или тем более в Update это выполнять не нужно.

- При входе в зону коллизии, можно запускать корутину, или использовать await/async где выполнять необходимые действия, в частности отнимание жизни через указанные промежутки времени.
- Так же необходимо кнтролировать выход персонаж из зоны, и останавливать запущенную ранее корутину или await/async

1) Зашли в зону, запустили корутину выполнения неких действий
2) Выполняем в корутине некие действий с персонажем или чем-то еще
3) Если вышли из зоны, останавливаем корутину неких действий

#3
19:02, 7 июня 2022

AlexStraga
Через какой метод в таких случаях реализуют таймер, не подскажете?

#4
0:08, 8 июня 2022

>Ddd93
Можно использовать, например
IEnumerator Test()...  и StartCoroutine(Test);
Тут есть команды, что бы подождать некоторое количество времени например WaitForSeconds
(при лагах не является точным и иные типа yield return new WaitForFixedUpdate(); значительно точнее, но так же при очень сильных лагах время поплывет, так же оно поплывет, если много корутин запущено)

или более навернутую штуку await/async тут ожидание +- похоже, но плавает +- несколько % и со временем может накопиться ошибка приличная, если используется не разово.

#5
(Правка: 2:00) 1:58, 9 июня 2022

Это можно делать проще, без всяких корутин и уж тем более async/await

OnCollisionEnter2D()
{
  InvokeRepeating("TakeDotDamage", 0, 1);
}

OnCollisionExit2D()
{
CancelInvoke("TakeDotDamage");
}

OnDisable()
{
CancelInvoke("TakeDotDamage");
}

void TakeDotDamage()
{
  //код который вызывается каждую секунду пока объект внутри коллизии, начиная с 0 секунды
}
UnityФорумОбщее