Ragdoll not working

Im trying to make it so when the tree his the player it ragdolls them but it only really stiffens them up, Does anyone know how to make it a real ragdoll and make them flop?
55 and below btw

local pushTree = script.Parent
local aoe = pushTree:FindFirstChild("AOE")
local tree = pushTree:FindFirstChild("Tree")

if not aoe or not tree then return end

local Players = game:GetService("Players")

local TARGET_POSITION = Vector3.new(-25.733, 4.052, -35.079)
local FORWARD_TIME = 0.5
local BACK_TIME = 1.5
local RAGDOLL_DURATION = 2
local PUSH_RADIUS = 12

local isTriggered = false

local function easeOutQuad(t)
	return 1 - (1 - t) * (1 - t)
end

local function easeInOutQuad(t)
	if t < 0.5 then
		return 2 * t * t
	else
		return 1 - (-2 * t + 2) ^ 2 / 2
	end
end

local function pushPlayer(character)
	local humanoid = character:FindFirstChildOfClass("Humanoid")
	if not humanoid or humanoid.Health <= 0 then return end

	local hrp = character:FindFirstChild("HumanoidRootPart")
	if not hrp then return end

	local startCFrame = hrp.CFrame
	local endPosition = Vector3.new(TARGET_POSITION.X, hrp.Position.Y, TARGET_POSITION.Z)

	local pushDir = (endPosition - startCFrame.Position)
	pushDir = Vector3.new(pushDir.X, 0, pushDir.Z)
	if pushDir.Magnitude > 0 then
		pushDir = pushDir.Unit
	end

	
	humanoid.PlatformStand = true
	humanoid:SetStateEnabled(Enum.HumanoidStateType.GettingUp, false)
	humanoid:SetStateEnabled(Enum.HumanoidStateType.Running, false)
	humanoid:SetStateEnabled(Enum.HumanoidStateType.Landed, false)


	local savedJoints = {}
	local createdConstraints = {}

	for _, joint in character:GetDescendants() do
		if joint:IsA("Motor6D") then
		
			table.insert(savedJoints, {
				name = joint.Name,
				part0 = joint.Part0,
				part1 = joint.Part1,
				c0 = joint.C0,
				c1 = joint.C1,
				parent = joint.Parent,
			})

		
			local socket = Instance.new("BallSocketConstraint")
			local a1 = Instance.new("Attachment")
			local a2 = Instance.new("Attachment")
			a1.Parent = joint.Part0
			a2.Parent = joint.Part1
			socket.Parent = joint.Parent
			socket.Attachment0 = a1
			socket.Attachment1 = a2
			a1.CFrame = joint.C0
			a2.CFrame = joint.C1
			socket.LimitsEnabled = true
			socket.TwistLimitsEnabled = true

			table.insert(createdConstraints, {socket = socket, a1 = a1, a2 = a2})

			joint:Destroy()
		end
	end


	hrp.AssemblyLinearVelocity = pushDir * 80 + Vector3.new(0, 30, 0)
	hrp.AssemblyAngularVelocity = pushDir:Cross(Vector3.new(0, 1, 0)) * 10

	task.delay(RAGDOLL_DURATION, function()
		if not humanoid or not humanoid.Parent then return end

	
		for _, data in createdConstraints do
			if data.socket and data.socket.Parent then data.socket:Destroy() end
			if data.a1 and data.a1.Parent then data.a1:Destroy() end
			if data.a2 and data.a2.Parent then data.a2:Destroy() end
		end

		-- Recreate Motor6D joints
		for _, data in savedJoints do
			local joint = Instance.new("Motor6D")
			joint.Name = data.name
			joint.Part0 = data.part0
			joint.Part1 = data.part1
			joint.C0 = data.c0
			joint.C1 = data.c1
			joint.Parent = data.parent
		end

		-- Allow recovery
		humanoid.PlatformStand = false
		humanoid:SetStateEnabled(Enum.HumanoidStateType.GettingUp, true)
		humanoid:SetStateEnabled(Enum.HumanoidStateType.Running, true)
		humanoid:SetStateEnabled(Enum.HumanoidStateType.Landed, true)
		humanoid:ChangeState(Enum.HumanoidStateType.GettingUp)
	end)
end

local function checkPlayersInPath(pushedPlayers)
	local treePos = tree:GetPivot().Position

	for _, player in Players:GetPlayers() do
		if pushedPlayers[player] then continue end

		local character = player.Character
		if not character then continue end

		local hrp = character:FindFirstChild("HumanoidRootPart")
		if not hrp then continue end

		local distance = (hrp.Position - treePos).Magnitude
		if distance <= PUSH_RADIUS then
			pushedPlayers[player] = true
			pushPlayer(character)
		end
	end
end

local function onAOETouch(otherPart)
	local character = otherPart.Parent
	local humanoid = character and character:FindFirstChildOfClass("Humanoid")
	if not humanoid or humanoid.Health <= 0 then return end

	if isTriggered then return end
	isTriggered = true

	local pushedPlayers = {}
	local startCFrame = tree:GetPivot()
	local targetCFrame = CFrame.new(TARGET_POSITION) * (startCFrame - startCFrame.Position)


	local startTime = os.clock()
	while os.clock() - startTime < FORWARD_TIME do
		local alpha = easeOutQuad((os.clock() - startTime) / FORWARD_TIME)
		tree:PivotTo(startCFrame:Lerp(targetCFrame, alpha))
		checkPlayersInPath(pushedPlayers)
		task.wait()
	end
	tree:PivotTo(targetCFrame)

	task.wait(0.3)


	startTime = os.clock()
	while os.clock() - startTime < BACK_TIME do
		local alpha = easeInOutQuad((os.clock() - startTime) / BACK_TIME)
		tree:PivotTo(targetCFrame:Lerp(startCFrame, alpha))
		task.wait()
	end
	tree:PivotTo(startCFrame)

	task.wait(1)
	isTriggered = false
end

aoe.Touched:Connect(onAOETouch)

1 Like

cant really read all the script but if you ragdoll your character on the client it probably cause that issue

1 Like

If that script is running in a LocalScript, the physics changes won’t replicate to the server. The server will still see the character as standing normally, which is why it looks stiff to everyone else.

this is mainly the ballsocketconstraint giving into the “stiff” effect, also i would disable motors and enable rather than destroying and re-adding them.

the maxtorque applied to it, the higher - the more stiff, imagine the ballsocketconstraint like this

bolt = constraint
torque = force applied