Как сделать спрайтовую анимацию в unity

Как сделать спрайтовую анимацию в unity

Как сделать спрайтовую анимацию в unity

Как сделать спрайтовую анимацию в unity

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

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

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

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

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

Ближний / контактный бой персонажа [2D]
Или Ближний / контактный бой персонажа [2D]
После того, как радиус атаки будет определен, необходимо удалить коллайдер!

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

public Transform punch1; public float punch1Radius;
То бишь, тут и точка и радиус ее атаки.

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

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

using UnityEngine; using System.Collections; public class EnemyHP : MonoBehaviour { public float HP = 100; }
Одноклеточный скрипт, тем не менее, очень важный.

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

using UnityEngine; using System.Collections; public class Fight2D : MonoBehaviour { // функция возвращает ближайший объект из массива, относительно указанной позиции static GameObject NearTarget(Vector3 position, Collider2D[] array) { Collider2D current = null; float dist = Mathf.Infinity; foreach(Collider2D coll in array) { float curDist = Vector3.Distance(position, coll.transform.position); if(curDist < dist) { current = coll; dist = curDist; } } return current.gameObject; } // point - точка контакта // radius - радиус поражения // layerMask - номер слоя, с которым будет взаимодействие // damage - наносимый урон // allTargets - должны-ли получить урон все цели, попавшие в зону поражения public static void Action(Vector2 point, float radius, int layerMask, float damage, bool allTargets) { Collider2D[] colliders = Physics2D.OverlapCircleAll(point, radius, 1 << layerMask); if(!allTargets) { GameObject obj = NearTarget(point, colliders); if(obj.GetComponent<EnemyHP>()) { obj.GetComponent<EnemyHP>().HP -= damage; } return; } foreach(Collider2D hit in colliders) { if(hit.GetComponent<EnemyHP>()) { hit.GetComponent<EnemyHP>().HP -= damage; } } } }
Добавлять на сцену его не нужно. Данный скрипт, производит поиск целей в указанной точке и взаимодействует с EnemyHP.

Пример использования:

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

if(Input.GetKeyDown(KeyCode.Space)) { Fight2D.Action(punch1.position, punch1Radius, 8, 12, false); }
Здесь мы сообщаем функции, -точку контакта, -радиус, -номер слоя юнита, -урон по цели, и в конце обозначаем что урон получит только одна цель (ближайшая от точки). Соответственно, если поставить true, урон получат все юниты попавшие в радиус атаки, это удобно для супер приема например.

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

Ближний / контактный бой персонажа [2D]
Отсюда же и берем номер слоя.

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


Источник: https://null-code.ru/solution/100-blizhniy-kontaktnyy-boy-personazha-2d.html


Как сделать спрайтовую анимацию в unity

Как сделать спрайтовую анимацию в unity

Как сделать спрайтовую анимацию в unity

Как сделать спрайтовую анимацию в unity

Как сделать спрайтовую анимацию в unity