Setting ‘HumanoidRootPart’ to massless for smoother server side ragdoll causes glitches

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)

I saw your last topic. You can edit your posts, you don’t need to delete it.
Dont have any thing to say for your glitch, sorry.

Oh sorry I didn’t see the edit button so I deleted it

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.

Ok I managed to fix it myself so I’m just gonna leave it here in case someone is facing the same problem. (This is the server sided script btw):

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)
		local rootPart = Character:FindFirstChild("HumanoidRootPart")
		if rootPart then
			rootPart.Massless = true
		end
		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"
				local rootPart = Character:FindFirstChild("HumanoidRootPart")
				if rootPart then
					rootPart.Massless = true
				end
				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)
		local rootPart = Character:FindFirstChild("HumanoidRootPart")
		if rootPart then
			rootPart.Massless = false
		end
		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

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.