Hey! I recently got a ragdoll script for a game I’m working on but I used to have an issue. Basically, the ragdolling would be smooth on the client side but would be very stiff and laggy on the server side. And I recently discovered a fix for this, the fix was that I had to set the HumanoidRootPart of the player to massless in order to be smooth on the server side. Now while this did make it smoother it caused other issues. As you can see in the video below, the camera and movement is very glitchy. In conclusion, I wanted to find a way to have ragdolling be smooth on the server side with the HumanoidRootPart being massless while also getting rid of these glitches.
I’m trying to make it so that the humanoidrootpart has mass until the R button is clicked then it’s massless and then when it’s clicked again it gains back its mass. But I don’t know where to include it in the scripts.
This is the client script that fires the event:
local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:wait()
local Humanoid = Character:WaitForChild("Humanoid")
local Modules = script.Parent:WaitForChild("Modules")
--local Rig = require(Modules:WaitForChild("Rig"))
local Addons = require(Modules:WaitForChild("Addons"))
local Settings = require(Modules:WaitForChild("Settings"))
local Events = script.Parent:WaitForChild("Events")
local Events_Toggle = Events:WaitForChild("Toggle")
local Events_GuiToClient = Events:WaitForChild("GuiToClient")
local Events_ResetClient = Events:WaitForChild("ResetClient")
local Functions = script.Parent:WaitForChild("Functions")
--local Functions_Ragdoll = Functions:WaitForChild("Ragdoll")
local Functions_RemoteRagdoll = Functions:WaitForChild("RemoteRagdoll")
local Functions_RemoteVelocity = Functions:WaitForChild("RemoteVelocity")
local Variables = script.Parent:WaitForChild("Variables")
local Variables_Ragdoll = Variables:WaitForChild("Ragdoll")
local Variables_RagdollClient = Variables:WaitForChild("RagdollClient")
Addons.KillRagdolls()
function Functions_RemoteRagdoll.OnClientInvoke(Mode,Velocity)
if Mode == true then
Humanoid:ChangeState(Enum.HumanoidStateType.Physics)
Variables_RagdollClient.Value = true
Humanoid.AutoRotate = false
pcall(function() Character.Animate.Disabled = true end)
for _,v in pairs(Humanoid:GetPlayingAnimationTracks()) do
if v.Name ~= "ExampleAnim" then --animation you don't want ragdoll script to stop
v:Stop(0)
end
end
if Velocity then
Character.HumanoidRootPart.Velocity = Velocity
end
else
Humanoid:ChangeState(Enum.HumanoidStateType.GettingUp)
Variables_RagdollClient.Value = false
Humanoid.AutoRotate = true
pcall(function() Character.Animate.Disabled = false end)
Addons.KillVelocity(Character)
end
end
function Functions_RemoteVelocity.OnClientInvoke(Velocity)
if Velocity then
Character.HumanoidRootPart.Velocity = Velocity
end
end
function ToggleVariables(mode)
if mode == "R" then
Events_Toggle:FireServer("R", not Variables_RagdollClient.Value)
elseif mode == "L" then
Events_Toggle:FireServer("L")
end
end
Events_GuiToClient.Event:Connect(ToggleVariables)
--[[
Events_ResetClient.Event:Connect(function()
ToggleVariables("L")
end)
spawn(function()
local resetsuccess = false
repeat wait() resetsuccess = pcall(function() game:GetService("StarterGui"):SetCore("ResetButtonCallback",Events_ResetClient) end) until resetsuccess == true
end)]]
local cas = game:GetService("ContextActionService")
cas:BindAction("RagdollToggle", function(_,input)
if input == Enum.UserInputState.Begin then
ToggleVariables("R")
end
end, Settings.MobileSupport, Enum.KeyCode.R)
cas:BindAction("ResetHotkey", function(_,input)
if input == Enum.UserInputState.Begin then
ToggleVariables("L")
end
end, Settings.MobileSupport, Enum.KeyCode.L)
if Settings.MobileSupport then
cas:SetPosition("RagdollToggle",UDim2.new(0.6,0,0.2,0))
cas:SetTitle("RagdollToggle","Ragdoll")
cas:SetPosition("ResetHotkey",UDim2.new(0.3,0,0.7,0))
cas:SetTitle("ResetHotkey","Reset")
end
And this is the server script that does the ragdolling:
local Player = script.Parent.Parent.Parent
local Character = Player.Character or Player.CharacterAdded:wait()
local Humanoid = Character.Humanoid
local Modules = script.Parent.Modules
local Rig = require(Modules.Rig)
local Addons = require(Modules.Addons)
local Settings = require(Modules.Settings)
local Events = script.Parent.Events
local Events_Toggle = Events.Toggle
local Events_GuiToClient = Events.GuiToClient
local Functions = script.Parent.Functions
local Functions_Ragdoll = Functions.Ragdoll
local Functions_RemoteRagdoll = Functions.RemoteRagdoll
local Functions_RemoteVelocity = Functions.RemoteVelocity
local Variables = script.Parent.Variables
local Variables_Ragdoll = Variables.Ragdoll
local Variables_RagdollClient = Variables.RagdollClient
Humanoid.BreakJointsOnDeath = false -- We're using a custom method for breaking joints.
--Humanoid:SetStateEnabled(Enum.HumanoidStateType.Dead, false)
Rig.Character = Character
Rig.CreateFolders()
Rig.FindParts()
Rig.CreateAltRootMotor()
Rig.ScaleAltRootMotorOffset()
Rig.CreateConstraints()
Rig.BuildConstraintRig()
if Settings.CreateAccessoryConstraints == true then Rig.CreateAccessoryConstraints() end
Rig.CreateNoClipCollisionGroup()
Rig.TakeCareOfRootPartAndHead()
Rig.CreateCustomHeadCollisionBox()
Rig.CreateNoCollisionConstraints()
local Debris = game:GetService("Debris")
local IsRagdollNow = false
local CurrentCooldown = 0
function ragdoll(Mode,Velocity)
if Mode == true then
if IsRagdollNow then spawn(function() if Velocity then Functions_RemoteVelocity:InvokeClient(Player,Velocity) end end) return end
IsRagdollNow = true
CurrentCooldown = time()+Settings.UnRagdollCooldown
Variables_Ragdoll.Value = true
Rig.ToggleRagdollRig(true)
Functions_RemoteRagdoll:InvokeClient(Player,true,Velocity)
elseif Mode == "dead" then
if Settings.CloneCharacterOnDeath then
Player.CharacterRemoving:Connect(function()
Character.Archivable = true
Humanoid.AutomaticScalingEnabled = false
local CharClone = Character:Clone()
CharClone.Name = Player.Name.."'s Ragdoll"
for _,v in pairs(CharClone:GetDescendants()) do
if v:IsA("BaseScript") or v:IsA("Sound") then
v:Destroy()
end
end
Character:Destroy()
CharClone.Parent = workspace
Addons.KillHumanoid(CharClone.Humanoid)
if Settings.AutoCleanup and Settings.AutoCleanupTime then
Debris:AddItem(CharClone, Settings.AutoCleanupTime)
end
pcall(function()
for _,v in pairs(CharClone:GetDescendants()) do
if v:IsA("BasePart") then
v:SetNetworkOwnershipAuto()
end
end
end)
end)
end
else
if not IsRagdollNow then return end
IsRagdollNow = false
Variables_Ragdoll.Value = false
Rig.ToggleRagdollRig(false)
Functions_RemoteRagdoll:InvokeClient(Player,false)
end
end
local HealthConnection
HealthConnection = Humanoid:GetPropertyChangedSignal("Health"):Connect(function()
if Humanoid.Health <= 0 then
HealthConnection:Disconnect() --Preparing for death sequence
pcall(function() Character.Health:Destroy() end)
-- PLACE FOR CODE MEANT TO HAPPEN BEFORE ACTUALLY KILLING --Executing code that needs to run before death to avoid bugs
--Humanoid:SetStateEnabled(Enum.HumanoidStateType.Dead, true) --Killing
Addons.KillHumanoid(Humanoid)
ragdoll(true) --Ragdolling
if Settings.BreakJointsOnDeath then Addons.DestroyMotors(Rig.Motors) end --Breaking joints after ragdolling to ensure consistency with ragdolling normally
ragdoll("dead") --Executing post-mortem events
end
end)
Variables_Ragdoll:GetPropertyChangedSignal("Value"):Connect(function()
if Humanoid.Health > 0 then
ragdoll(Variables_Ragdoll.Value)
end
end)
Events_Toggle.OnServerEvent:Connect(function(player,name,mode)
if name == "R" then
if mode then
ragdoll(true)
else
if IsRagdollNow and (time() > CurrentCooldown) and (Humanoid.Health > 0) then
ragdoll(false)
end
end
elseif name == "L" then
Humanoid.Health = -1
end
end)
function Functions_Ragdoll.OnInvoke(velocity)
ragdoll(true,velocity)
end
function Functions_RemoteRagdoll.OnServerInvoke(plr,velocity)
ragdoll(true,velocity)
end
(also ignore the music oops)