Как сделать урон от падения в unity

Добавил пользователь Алексей Ф.
Обновлено: 04.10.2024

Я пытаюсь сделать игру сверху вниз, похожую на игры SNES Zelda, в Unity 4.3, в 2D. Когда мой персонаж качает меч, каждый враг в радиусе получает урон. Я хочу убедиться, что атаки в ближнем бою наносят урон врагам, с которыми сталкивается игрок.

Как я могу это сделать?

Соответствующий код в PlayerAttack.cs выглядит следующим образом:

Сравните направление, в котором ваш персонаж сталкивается с направлением противнику. точечный продукт вектора A и вектора B, деленный на величину вектора B, скажет вам проецирование от A до B. Если вы используете нормализованные векторы, вы можете пропустить разделение. Результаты можно интерпретировать следующим образом:

  • Результат = 1: Векторы полностью перекрываются.
  • Результат = 0: Векторы перпендикулярны
  • Результат = -1: векторы точно противоположны

Играйте с результатами, посмотрите, какие диапазоны вы хотите разрешить. Я бы предложил результат> .85f.

Описание алгоритма: вам нужно следующее:

  1. Позиция (x1, y1) вашего персонажа.
  2. Угол альфа, в котором он обращен.
  3. Позиции (и, возможно, размеры) всех вражеских существ.

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

  1. Создайте список всех врагов поблизости.
  2. Вычислить расстояние от каждого врага. Если не в пределах диапазона ближнего боя, удалите его.
  3. Итерация над всеми оставшимися врагами (в пределах диапазона ближнего боя) и вычисление угла вектора их положения за вычетом вашей позиции.
  4. Вычитайте этот угол из угла, с которым сталкивается символ (получите абсолютное значение). Если значение ближе к 2 * Pie (или 360 градусов), чем к нулю, вычесть из него 2 * Pie и снова получить абсолютное значение.
  5. Сравните результат с тем, что вы считаете приемлемым срезом конуса (например, Pie /5).
  6. Если враг находится в пределах диапазона, вычитайте здоровье.
  7. Если вы только хотели поразить одну цель, возьмите ближайшую к персонажу и внутри конуса и вычтите ее здоровье.

Обычно вы вычисляете угол между позициями двух символов следующим образом:

Эта функция или совместимая, вероятно, существует на языке ваших предпочтений.

Укажите, какая часть этого алгоритма неясна, если вы хотите получить дополнительную помощь.

Подробнее: Атака в ближнем бою - это просто (в игровой механике) атака дальнего боя с небольшим радиусом действия. Обычно существует два вида атак, одна целевая атака, в которой вы наносите только один враг максимум и AoE, где вы наносите урон нескольким противникам (каждый символ в пределах диапазона эффекта).

В вашем случае, я думаю, вы направились в правильном направлении. Проверка расстояния. Теперь вам нужно проверить угол между вашим персонажем и этим противником и сравнить его с углом, с которым вы сталкиваетесь. Если разница слишком велика (PI / 4) , то она не попадает.

Итак, получите абсолютное значение разницы между углами и сравните его с некоторой константой.

Одно из решений более четкое:

Текущая ситуация оставлена, правая идеальная ситуация

Слева - это то, что происходит; право - это то, что вы хотите.

Ясно, что расстояние от игрока не является единственным важным фактором. Существует также направление врагов .

Направление относительно лицевой стороны игрока :

Направления врагов относительно направления движения игрока

Если вам известен вектор положения проигрывателя p и код противника e , вы можете наблюдать базовый тригонометрический идентификатор что

tan(angle) = opp / adj , где opp = | p.y - e.y | и adj = | p.x - e.x |

Следовательно, angle = atan(abs(p.y - e.y)/abs(p.x - e.x)) .

Затем вы отфильтровываете список врагов, в первую очередь, находятся ли они в радиусе, а затем от того, находится ли угол к ним под углом атаки. Все оставленное попадает.

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

Создайте Transform и сделайте его дочерним элементом вашего персонажа. Расположите его там, где атака приземляется, а затем добавьте его в качестве публичного трансформирования скрипта PlayerAttack. Назовем это attackPositionTransform. Теперь в вашей функции MeleeAttack вы можете сравнить позицию attackPositionTransform с целью.

Просто сделайте коллайдер круга, чтобы проверить, когда объект входит в ваш радиус атаки, а затем используйте foreach для доступа ко всем объектам рядом с вами:

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

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

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

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

Популярные теги

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

Сразу отметим, что анимацию мы рассматривать тут не будем, так как проще либо посмотреть официальные обучающие видео материалы по этой теме, либо изучить стандартный 2D ассет, который поставляется в комплекте движка. В общем, если у вас уже готова анимация персонажа, продолжим.

Подготовка. Делаем подготовленный спрайт с анимацией, дочерним к пустому объекту, назовем его Player. Затем уже на этот пустой объект вешаем коллайдер и Rigidbody2D. То есть анимируем мы только дочерний объект, а управляем родительским. Суть в том, что каждый удар рукой, ногой, мечом и т.п. это определенное положение спрайта / модели. Переключаться в режим удара, например:

Ближний / контактный бой персонажа [2D]

И ставим в точку удара пустышку, делаем ее дочерней к Player, не к спрайту! Эта точка должна сохранять свое положение, вне зависимости от анимации. Называем точку, допустим, punch-1.

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



После того, как радиус атаки будет определен, необходимо удалить коллайдер!

А в основном скрипте, где мы управляем движением и анимацией, добавляем необходимые переменные:

То бишь, тут и точка и радиус ее атаки.

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

Следующий шаг, на все вражеские юниты повесить скрипт EnemyHP:

Одноклеточный скрипт, тем не менее, очень важный.

Далее, в папку вашего проекта, где находятся все скрипт, добавляем еще Fight2D:

Добавлять на сцену его не нужно. Данный скрипт, производит поиск целей в указанной точке и взаимодействует с EnemyHP.

На клавише "пробел" у нас удар мечом, делаем следующее:

Здесь мы сообщаем функции, -точку контакта, -радиус, -номер слоя юнита, -урон по цели, и в конце обозначаем что урон получит только одна цель (ближайшая от точки). Соответственно, если поставить true, урон получат все юниты попавшие в радиус атаки, это удобно для супер приема например.

Все вражеские юниты должны иметь свой отдельный слой, например, под именем Enemy:


Отсюда же и берем номер слоя.

Вот, как-то так. Достаточно просто, единственна заморочка, это расстановка точек, но опять же всё зависит от количества возможных ударов, к тому же радиус некоторых однотипных ударов можно стандартизировать.

Читайте также: