Хочешь, чтобы персонаж при смерти или ударе обмякал и падал тряпичной куклой, а не оставался деревянным? Это и есть рэгдолл, и для R6-моделей он делается своими руками на Lua. Разберём по-справочному: чем R6 отличается от R15, из каких суставов он собран, как превратить жёсткие соединения в шарниры и переключить персонажа в физику. В конце — цельный разбор рабочего скрипта и как применить его к NPC, а не только к игроку.
Ремарка не по коду: если для проекта нужны робуксы на плагины, анимации или ассеты, а карта РФ не проходит, пополнить их можно через SUB.SUP (Telegram, ВКонтакте). Теперь к рэгдоллу.
Рэгдолл и чем R6 отличается от R15
Рэгдолл — это когда персонаж перестаёт держать позу и подчиняется физике: конечности болтаются на шарнирах, тело оседает под гравитацией. По умолчанию Roblox держит части персонажа жёстко скреплёнными моторами, и чтобы получить тряпичность, эти жёсткие связи надо на время заменить свободными.
Разница между R6 и R15 тут принципиальна, и её надо понимать. R6 — старая простая схема из шести частей тела с небольшим набором суставов: шея, два плеча, два бедра и корневой сустав. R15 — новая, из пятнадцати частей с куда большим числом соединений. Код рэгдолла в обоих случаях идейно один, но конкретные суставы разные, поэтому скрипт для R15 на R6 не заведётся как есть. Мы говорим именно про R6 — его меньше, и разбираться в нём проще. Ещё пара слов о самой идее, чтобы код дальше не казался магией. Всё, что делает рэгдолл, — это подмена типа соединения: жёсткий мотор фиксирует части в одной позе, а шарнир позволяет им свободно вращаться. Мы не ломаем персонажа и не создаём его заново — мы лишь на время меняем правила, по которым его части держатся друг за друга. Захотел вернуть — поменял правила обратно. Понимание этого сразу снимает страх перед физикой: ты просто переключаешь тело между двумя режимами, жёстким и тряпичным.
Из чего состоит скелет R6
Чтобы менять суставы, надо знать, где они лежат. В R6 части соединены через Motor6D — это и есть жёсткие «моторы», держащие позу. Шея (Neck) соединяет голову с торсом, два плечевых сустава — руки с торсом, два бедренных — ноги с торсом, а корневой сустав (RootJoint) держит торс на HumanoidRootPart.
Почти все эти моторы живут внутри Torso, а корневой — в HumanoidRootPart. Наша задача — пройтись по всем Motor6D персонажа и каждый заменить на шарнир, который позволит частям свободно болтаться. Зная этот небольшой список суставов, ты уже понимаешь весь объём работы: их немного, и обработать их можно одним циклом. Полезно и знать, зачем вообще искать моторы циклом, а не перечислять их вручную. Да, в R6 суставов ровно шесть, и их можно было бы перебрать по именам. Но цикл по всем Motor6D надёжнее: он поймает любой сустав независимо от имени и сработает, даже если модель чуть отличается от стандартной. Поэтому в коде мы и пробегаем по всем потомкам персонажа, отбирая те, что являются Motor6D, — так скрипт универсальнее и не сломается на нестандартном рике.
Меняем каждый Motor6D на BallSocketConstraint в суставах R6
Ядро рэгдолла — замена жёстких Motor6D на шарнирные BallSocketConstraint. Идея такая: для каждого мотора создаём две точки крепления (Attachment) там, где мотор соединял части, вешаем между ними BallSocketConstraint, а сам мотор отключаем. Части остаются связанными, но теперь свободно вращаются в шарнире — вот и тряпичность.
Вот функция, которая делает это для всего персонажа:
```lua
local function ragdoll(character)
for _, motor in ipairs(character:GetDescendants()) do
if motor:IsA("Motor6D") then
local a0 = Instance.new("Attachment")
local a1 = Instance.new("Attachment")
a0.CFrame = motor.C0
a1.CFrame = motor.C1
a0.Parent = motor.Part0
a1.Parent = motor.Part1
local socket = Instance.new("BallSocketConstraint")
socket.Attachment0 = a0
socket.Attachment1 = a1
socket.Parent = motor.Part0
motor.Enabled = false
end
end
end
```
Мы берём все Motor6D в персонаже, для каждого создаём Attachment на тех же смещениях C0 и C1, соединяем их BallSocketConstraint и гасим сам мотор. После этого тело держится на шарнирах и обмякает под гравитацией. Разберём код по строчкам, чтобы он был прозрачным. Для каждого мотора мы создаём две точки крепления — Attachment. Первую ставим на Part0 (обычно это торс) со смещением C0, вторую — на Part1 (конечность) со смещением C1. Именно эти смещения и хранят информацию о том, где сустав соединял части, поэтому копировать их важно точь-в-точь: ошибёшься здесь — и конечности встанут криво или вывернутся. Затем между точками вешаем BallSocketConstraint — это и есть шарнир, разрешающий свободное вращение. И в самом конце гасим мотор через Enabled = false, а не удаляем его: так его легко включить обратно при возврате из рэгдолла. Вот и весь фокус — шесть моторов превращаются в шесть шарниров.
Переключаем Humanoid в состояние Physics
Одних шарниров мало — Humanoid по-прежнему пытается управлять персонажем и ставить его на ноги. Ему надо сказать, что теперь командует физика. Для этого выключаем автоподъём и переводим гуманоида в физическое состояние или ставим PlatformStand.
Без этого шага персонаж будет упрямо вставать обратно, и рэгдолл выйдет наполовину: шарниры есть, а тело всё равно норовит подняться. Отключив автоподъём и включив PlatformStand, ты отдаёшь тело на волю физики полностью. Почему нужны оба действия, а не одно. Отключение GettingUp запрещает гуманоиду запускать анимацию вставания, а PlatformStand отключает его собственное управление движением, отдавая тело физике. Уберёшь только одно — и получишь полурэгдолл: либо тело дёргается, пытаясь встать, либо стоит столбом, несмотря на шарниры. Вместе же эти две строки и создают полноценную тряпичность.
Отключаем лишние столкновения
Мелкая, но важная деталь: если части персонажа сталкиваются друг с другом, рэгдолл дёргается и распирает изнутри. Отключи столкновения между частями тела, чтобы конечности не толкали сами себя, и падение станет естественным. Но не переусердствуй: столкновения с миром оставь, иначе тело провалится сквозь пол.
Быстрые вопросы по рэгдоллу
### Почему персонаж проваливается сквозь пол?
Чаще всего потому, что у частей тела отключены столкновения не только между собой, но и с миром, либо HumanoidRootPart остался с включённой физикой и тянет тело вниз. Убедись, что части сталкиваются с полом, и проверь состояние корневой части. Практически это значит: отключай столкновения только между частями самого персонажа, а не с окружением. HumanoidRootPart при этом часто делают некалибрящимся или прячут, чтобы он не мешал телу лежать. Если проваливание осталось, поиграй именно с этими двумя настройками.
### Как вернуть персонажа из рэгдолла обратно?
Обратной операцией: включаешь Motor6D снова, удаляешь созданные шарниры и Attachment, выключаешь PlatformStand и возвращаешь гуманоида в обычное состояние. Удобно заранее хранить ссылки на созданные объекты, чтобы было что удалять.
### Работает ли это на мобильных?
Да, рэгдолл — серверная и физическая механика, она не зависит от устройства игрока. Главное — не переусердствовать с числом одновременно активных рэгдоллов, чтобы не грузить слабые телефоны физикой.
Плавность и типичные баги рэгдолла
Пару слов о том, что обычно ломается. Если рэгдолл дёргается и трясётся — почти всегда виноваты столкновения частей между собой; отключи их. Если тело растягивается или выворачивается — проверь, что Attachment созданы на правильных смещениях C0 и C1, иначе шарниры встанут не туда. А если персонаж наполовину встаёт — значит, не до конца отдал управление физике: вернись к шагу с PlatformStand и автоподъёмом. Разбор по симптомам экономит кучу времени, поэтому держи эту связку в голове: трясётся — столкновения, растягивается — смещения C0 и C1, встаёт — управление физикой. Почти любой баг рэгдолла ложится в одну из этих трёх категорий, и зная их, ты чинишь его за минуту, а не гадаешь наугад.
Ещё частый баг — рэгдолл срабатывает, но при возврате персонаж остаётся кривым. Причина — не все временные объекты удалены при подъёме. Держи чёткий список того, что создал, и при возврате удаляй всё до последнего Attachment. Удобный приём — складывать все созданные шарниры и Attachment в отдельную папку внутри персонажа: тогда при возврате достаточно очистить эту папку одним махом, и ничего не забудется.
Полный разбор рабочего скрипта рэгдолла
Соберём всё вместе в понятную последовательность. Рабочий рэгдолл для R6 — это три действия по кнопке или по событию смерти: заменить моторы на шарниры, отдать тело физике, отключить лишние столкновения. Вот как это выглядит целиком:
```lua
local function enableRagdoll(character)
local humanoid = character:FindFirstChildOfClass("Humanoid")
for _, motor in ipairs(character:GetDescendants()) do
if motor:IsA("Motor6D") then
local a0 = Instance.new("Attachment")
local a1 = Instance.new("Attachment")
a0.CFrame, a1.CFrame = motor.C0, motor.C1
a0.Parent, a1.Parent = motor.Part0, motor.Part1
local socket = Instance.new("BallSocketConstraint")
socket.Attachment0, socket.Attachment1 = a0, a1
socket.Parent = motor.Part0
motor.Enabled = false
end
end
end
```
Скрипт лучше выполнять на сервере, чтобы рэгдолл видели все игроки одинаково. Повесь вызов enableRagdoll на событие смерти гуманоида (Humanoid.Died) — и персонаж будет красиво обмякать при гибели. Обязательно протестируй его в игре с несколькими игроками, а не только в одиночном превью: физика в мультиплеере ведёт себя чуть иначе, и лучше поймать это заранее. Разберу этот финальный скрипт ещё раз по шагам, потому что он собирает всё воедино. Сначала берём Humanoid и отключаем ему автоподъём с включением PlatformStand — тело перестаёт сопротивляться физике. Затем в цикле проходим по всем Motor6D персонажа и каждый превращаем в шарнир BallSocketConstraint на тех же смещениях, гася сам мотор. После этого персонаж полностью во власти гравитации и обмякает. Повесив всё это на Humanoid.Died, ты получаешь красивую смерть в одну строку вызова; повесив на попадание — реакцию на удар. Вся прелесть в том, что один и тот же enableRagdoll работает в обоих сценариях, и тебе не нужно писать два разных куска кода. Ещё раз про то, где выполнять: рэгдолл делают на сервере, потому что физика тела должна одинаково выглядеть у всех игроков. Если сделать это только на клиенте, один игрок увидит красивое падение, а остальные — стоящий столб. Сервер решает эту рассинхронизацию, а клиенту можно оставить лишь косметику вроде эффектов удара.
Рэгдолл для NPC, а не только для игрока
Приятная новость: тот же скрипт работает и на NPC, ведь у ботов на R6 такой же скелет из Motor6D, как у игроков. Разница только в том, что ты вызываешь функцию для модели NPC, а не для персонажа игрока. Так делают падающих врагов, трупы и физические реакции мобов на удары. Кстати, если для проекта нужны готовые анимации падения или ассеты, а робуксы приходится пополнять из России, это оформляют через SUB.SUP (Telegram, ВКонтакте). По сути любой R6-персонаж на сцене — потенциальный кандидат на рэгдолл, будь то игрок, союзный NPC или враг, и один и тот же скрипт покрывает их всех.
Единственная тонкость — производительность: если ты роняешь в рэгдолл десятки NPC разом, следи за нагрузкой и убирай тела через время, чтобы они не копились на сцене и не топили физику. В остальном рэгдолл универсален: один аккуратный скрипт оживляет падение и игрока, и любого R6-бота.
### Нужно ли делать рэгдолл на сервере или на клиенте?
На сервере, если рэгдолл должны видеть все игроки одинаково — клиенту оставляют только косметику. Серверный рэгдолл синхронизируется у всех, клиентский увидит лишь один игрок.
### Как сделать рэгдолл от удара, а не только от смерти?
Вызывай ту же функцию рэгдолла по событию попадания и через пару секунд возвращай персонажа обратно. Получается физическая реакция на удар: персонажа сбивает с ног, и он встаёт.
Комментарии
Войдите, чтобы написать комментарий