Hello! My game has NPCs (every limb’s NetworkOwner is set to nil) that you can run into to ragdoll.
However, the NPC ragdolls appear choppy, while the players’ appears fine. I tried removing the code where it sets the NetworkOwners to nil, but to no avail.
(In the video, you can see the NPCs ragdoll when they trip over me.)
Ragdoll module, if it helps
local module = {}
local Players = game:GetService("Players")
local Debris = game:GetService("Debris")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local PhysicsService = game:GetService("PhysicsService")
local Modules = ReplicatedStorage.Modules
local ImpactSoundModule = require(Modules.ImpactSoundModule)
local ragParts = script.RagdollParts:GetChildren()
local sounds = script.Sounds:GetChildren()
local slip = script.Slip
local defaultMinZoomDistance = game.StarterPlayer.CameraMinZoomDistance
local function playSound(part, s, vol)
local sound = s:Clone()
sound.Parent = part
sound.Volume = vol or 0.5
sound:Play()
task.wait(0.1)
Debris:AddItem(sound, sound.TimeLength + 0.1)
end
local function playRandomSound(char)
local sound = sounds[math.random(1, #sounds)]
local head = char and char:FindFirstChild("Head")
if not head or not sound then return end
playSound(head, slip)
playSound(head, sound, 0.2)
end
local function createCollider(limb : BasePart) -- Not used
if not limb then return end
if limb.Name == "HumanoidRootPart" then return end
local collider = Instance.new("Part")
collider.CFrame = limb.CFrame
collider.Massless = true
collider.Size = limb.Size * 0.5
collider.Transparency = 1
local weld = Instance.new("WeldConstraint")
weld.Part0 = collider
weld.Part1 = limb
weld.Parent = collider
collider:AddTag("Collider")
collider.Name = limb.Name .. " Collider"
collider.Parent = limb.Parent
return collider
end
function module:Setup(char : Model, isPlayer, canGrab)
if not char.Humanoid then return end
local humanoid = char:FindFirstChild("Humanoid")
assert(humanoid, "Can only set-up ragdoll on R6 humanoid rigs")
assert(humanoid.RigType == Enum.HumanoidRigType.R6, "Can only set-up ragdoll on R6 humanoid rigs")
assert(humanoid.RootPart ~= nil, "No RootPart was found in the provided rig")
assert(char:FindFirstChild("HumanoidRootPart"), "No HumanoidRootPart was found in the provided rig")
if not isPlayer then
for _, v: BasePart in ipairs(char:GetDescendants()) do
if v:IsA("BasePart") then
v:SetNetworkOwner(nil)
end
end
end
-- Setup ragdoll
char.Head.Size = Vector3.new(1, 1, 1)
humanoid.BreakJointsOnDeath = false
humanoid.RequiresNeck = true
char:SetAttribute("CanGrabWhenRagdolled", canGrab)
local clones = {}
for _, v in ipairs(ragParts) do
clones[v.Name] = v:Clone()
end
local folder1 = Instance.new("Folder")
folder1.Name = "RagdollConstraints"
for _, v in pairs(clones) do
if v:IsA("Attachment") then
v.Parent = char[v:GetAttribute("Parent")]
elseif v:IsA("BallSocketConstraint") then
v.Attachment0 = clones[v:GetAttribute("0")]
v.Attachment1 = clones[v:GetAttribute("1")]
v.Parent = folder1
end
end
folder1.Parent = char
local folder2 = Instance.new("Folder")
folder2.Name = "Motors"
local value
for _, v in ipairs(char.Torso:GetChildren()) do
if v:IsA("Motor6D") then
value = Instance.new("ObjectValue")
value.Value = v
value.Parent = folder2
end
end
folder2.Parent = folder1
-- Ragdoll trigger
local trigger = Instance.new("BoolValue")
trigger.Name = "RagdollTrigger"
trigger.Parent = char
trigger.Changed:Connect(function(bool)
if bool then
module:Ragdoll(char)
else
module:Unragdoll(char)
end
end)
humanoid.Died:Once(function()
trigger.Value = true
end)
end
function module:SetRagdollTrigger(char: Model, value)
local trigger = char:FindFirstChild("RagdollTrigger")
if trigger then
trigger.Value = value
end
return trigger
end
function module:Ragdoll(char: Model)
if not char.Humanoid then return end
char.Humanoid:ChangeState(Enum.HumanoidStateType.Physics)
char.Humanoid:SetStateEnabled(Enum.HumanoidStateType.Seated, false)
char.Humanoid.AutoRotate = false
local player = Players:GetPlayerFromCharacter(char)
if player then
player.CameraMinZoomDistance = player.CameraMaxZoomDistance
playRandomSound(char)
end
if char:GetAttribute("CanGrabWhenRagdolled") == true then
char:AddTag("CanGrab")
end
for _, v in ipairs(char.RagdollConstraints.Motors:GetChildren()) do
v.Value.Enabled = false
end
for _, v in ipairs(char:GetDescendants()) do
if v:IsA("BasePart") then
v.CollisionGroup = "Ragdoll"
end
end
local hrp = char:FindFirstChild("HumanoidRootPart")
if not hrp then return end
local rootJoint = hrp:FindFirstChildOfClass("Motor6D")
if rootJoint then
task.spawn(function()
rootJoint.Enabled = false
task.wait()
rootJoint.Enabled = true
end)
end
ImpactSoundModule.Enable(char)
end
function module:Unragdoll(char: Model)
if not char.Humanoid then return end
char.Humanoid:ChangeState(Enum.HumanoidStateType.GettingUp)
char.Humanoid:SetStateEnabled(Enum.HumanoidStateType.Seated, true)
local player = Players:GetPlayerFromCharacter(char)
if player then
player.CameraMinZoomDistance = defaultMinZoomDistance
end
char:RemoveTag("CanGrab")
for _, v in ipairs(char.RagdollConstraints.Motors:GetChildren()) do
v.Value.Enabled = true
end
for _, v in ipairs(char:GetChildren()) do
if v:IsA("BasePart") then
v.CollisionGroup = player and "Players" or "Default"
--[[if v:HasTag("Collider") then
v:Destroy()
end]]--
end
end
ImpactSoundModule.Disable(char)
char.Humanoid.AutoRotate = true
end
return module
How can I make the server and client ragdolls appear the same, nice and smooth?