В этой статье мы рассмотрим, что такое Ragdoll, научимся создавать его и применять.
Итак, для начала рассмотрим, что такое Ragdoll.
Википедия говорит, что это процедурная анимация, пришедшая на смену статичной пререндерной анимации. То есть эта анимация рассчитывается в реальном времени на основе соединения костей скелета персонажа и свойств твердого тела rigitbody. Название же и означает «Тряпичная кукла». При правильной настройке Ragdoll, персонаж будет падать в соответствии с законами физики и механики.
Выглядеть это будет примерно так:
Для начала подготовим сцену
Нам потребуется плоскость, куда будет падать персонаж и сам персонаж. Как плоскость я использовал Terrain с первой попавшейся текстурой на нем. А персонаж взят стандартный, бесплатный из Asset Store. Найти его можно по ссылке
После скачивания ассета, разместим его на сцене, так, чтобы он попадал в поле зрения камеры. И, наконец, приступим к созданию Ragdoll.
Для этого в Unity есть простой интуитивно понятный мастер. Для того, чтобы создать Ragdoll нам достаточно перетащить части тела нашего персонажа в соответствующие поля свойств в мастере, верно выставить массу (мы должны помнить, что для правильной работы физики в Unity требуется работать с реальными весами объектов):
Жмем кнопку Create. Мастер сам создаст коллайдеры , Character Joint и Rigitbody, распределив массы по ним в соответствии с частью тела, где расположен Rigitbody.
Проверяем. Жмем кнопку Play и смотрим, как падает персонаж:
Теперь поговорим о применении Ragdoll
Первое, что нам надо – это включать и выключать элементы Ragdoll по команде. Когда персонаж жив, Ragdoll выключен, а когда его уровень жизни падает до нуля, то Ragdoll включается и персонаж красиво падает на землю.
Создадим скрипт и назначим его персонажу. Назовем его RagdollController. Первое, что мы сделаем в скрипте – это объявим переменную – список всех компонентов Rigitbody нашего Ragdoll:
public List<Rigidbody> GetRigidbodies = new List<Rigidbody>();
В нем мы будем хранить ссылки на элементы Ragdoll, чтобы можно было по команде включать и выключать их.
Далее в методе Start мы найдем все элементы и добавим их в список:
GetRigidbodies.AddRange(GetComponentsInChildren<Rigidbody>());
Теперь создадим еще два метода.
Первый метод будет включать состояние rigitbody в isKinematic =true. То есть силы столкновения и соединения не будут влиять на rigitbody, а значит – не будет работать и Ragdoll.
В методе мы создаем цикл, который последовательно перебирает все элементы нашего списка и переключает их в состояние isKinematic=true:
void RigidbodyIsKinematicOn()
{
for(int i = 0; i < GetRigidbodies.Count; i++)
{
GetRigidbodies[i].isKinematic = true;
}
}
Чтобы сразу выключить Ragdoll вызовем RigidbodyIsKinematicOn из метода Start сразу после того, как список будет заполнен:
void Start()
{ GetRigidbodies.AddRange(GetComponentsInChildren<Rigidbody>());
RigidbodyIsKinematicOn();
}
И еще один метод будет переключать rigitbody в isKinematic = true, а значит и включит Ragdoll.
В нем мы расположим такой же цикл, как и в предыдущем методе, за исключением строки GetRigidbodies[i].isKinematic = true; в ней мы заменим true на false и получится у нас:
public void RigidbodyIsKinematicOff()
{
for (int i = 0; i < GetRigidbodies.Count; i++)
{
GetRigidbodies[i].isKinematic = false;
}}
В целом скрипт выглядит так:
Сохраняем и проверяем. Жмем Play и видим, что наш персонаж просто стоит:
Далее создадим пулю, которая красиво убьет нашего персонажа
Вначале добавим на сцену GameObject. Например, сферу и направим её ось z на персонажа, так, чтобы при движении вперед она гарантированно попала в персонажа.
Добавим объекту компонент rigitbody для того, чтобы он мог взаимодействовать с другими физическими объектами и отслеживать столкновения.
Осталось написать небольшой скрипт для пули и назначить его нашему GameObject. Заглянем в скрипт.
Для начала объявим две переменные, отвечающие за скорость пули и силу, которую она передает цели:
public float speed;
public float trust;
Затем в методе Update мы двинем пулю вперед с заданной скоростью и по заданному вектору. У нас это Vector3.forward – направление оси z, которая как раз направлена на персонажа:
void Update()
{
transform.Translate(Vector3.forward * speed * Time.deltaTime);
}
И в конце добавим метод, определяющий столкновение, в котором мы пропишем, что должна делать пуля в момент столкновения.
А должна она включить Ragdoll, вызвав метод RigidbodyIsKinematicOff() у цели, куда она попала. А также передать импульс силы и вектор компоненту rigidbody с которым она столкнулась:
private void OnCollisionEnter(Collision collision)
{
collision.collider.GetComponentInParent<RagdollController>().RigidbodyIsKinematicOff();
collision.collider.attachedRigidbody.AddForce(transform.forward*trust,ForceMode.Impulse);
}
Полный скрипт:
Сохраняем скрипт, назначаем в инспекторе значения speed и trust и жмем Play:
Для лучшего эффекта можно поиграть с настройками персонажа CharacterJoint, изменив степень свободы суставов и параметр trust у пули.
А что, прям точно Rigitbody???
Проконсультируйтесь пожалуйста через my.first.unity.help@gmail.com
у вас на этой странице 10 раз написано неправильно слово Rigitbody