Flinging when changing states I think

Expected behavior

I expect the engine to not fling the character like this lol

Hi! Thanks for the report. Can you provide us with some more information, for example an rbxl reproducer, so we can more effectively debug this?

1 Like

I mean it just randomly happened in my game so Idk if I can provide you an rbxl of anything other then info of what I think happened, my ragdoll uses ball constraints is done on the server, a push effect is with body velocity it’s done on the client, both enable the same time, unragdolling happens while the body velocity is still in effect I’m guessing which is causing this weird behaviour?

Would giving the ragdoll script and snippets of how I do the push help?

Sure, those scripts would be very helpful!

RagdollCharacters = {}
@native function Module.Ragdoll(character, state)
	local player = G.Players:GetPlayerFromCharacter(character)

	if not G.CharacterLoaded(character) then
		return
	end

	local head = character.Head
	local torso = character.Torso
	local humanoidRootPart = character.HumanoidRootPart
	local rightArm = character["Right Arm"]
	local leftArm = character["Left Arm"]
	local rightLeg = character["Right Leg"]
	local leftLeg = character["Left Leg"]
	local humanoid = character.Humanoid

	local playerData = G.PlayerData(player, true)

	if not playerData then
		for _, v in G.ServerStorage.NPCs:GetChildren() do
			if v:IsA("ScreenGui") and v.Character.Value == character then
				playerData = v
				break
			end
		end

		if not playerData then
			return
		end
	end

	local function createAttachment(position, name, parent)
		local attachment = Instance.new("Attachment")
		attachment.Position = position
		attachment.Name = name
		attachment.Parent = parent
		return attachment
	end

	local function createBallSocket(parent, attachment0, attachment1, twistLowerAngle, twistUpperAngle)
		local ballSocket = Instance.new("BallSocketConstraint")
		ballSocket.Attachment0 = attachment0
		ballSocket.Attachment1 = attachment1
		ballSocket.LimitsEnabled = true
		ballSocket.TwistLimitsEnabled = true
		ballSocket.TwistLowerAngle = twistLowerAngle
		ballSocket.TwistUpperAngle = twistUpperAngle
		ballSocket.MaxFrictionTorque = 10
		ballSocket.Parent = parent
	end

	if state then
		if not playerData:GetAttribute("Ragdoll") then
			playerData:SetAttribute("Ragdoll", true)
			Module.Movement(player, humanoid, nil, true)

			local torsoToHead0 = createAttachment(Vector3.new(0, 1, 0), "TorsoToHead0", torso)
			local torsoToHRP0 = createAttachment(Vector3.new(0, 0, 0), "TorsoToHRP0", torso)
			local torsoToRightArm0 = createAttachment(Vector3.new(1, 0.5, 0), "TorsoToRightArm0", torso)
			local torsoToRightLeg0 = createAttachment(Vector3.new(0.5, -1, 0), "TorsoToRightLeg0", torso)
			local torsoToLeftArm0 = createAttachment(Vector3.new(-1, 0.5, 0), "TorsoToLeftArm0", torso)
			local torsoToLeftLeg0 = createAttachment(Vector3.new(-0.5, -1, 0), "TorsoToLeftLeg0", torso)

			local torsoToHead1 = createAttachment(Vector3.new(0, -0.6, 0), "TorsoToHead1", head)
			local torsoToHRP1 = createAttachment(Vector3.new(0, 0, 0), "TorsoToHRP1", humanoidRootPart)
			local torsoToRightArm1 = createAttachment(Vector3.new(-0.5, 0.5, 0), "TorsoToRightArm1", rightArm)
			local torsoToRightLeg1 = createAttachment(Vector3.new(0, 1, 0), "TorsoToRightLeg1", rightLeg)
			local torsoToLeftArm1 = createAttachment(Vector3.new(0.5, 0.5, 0), "TorsoToLeftArm1", leftArm)
			local torsoToLeftLeg1 = createAttachment(Vector3.new(0, 1, 0), "TorsoToLeftLeg1", leftLeg)

			createBallSocket(torso, torsoToHead0, torsoToHead1, -45, 45)
			createBallSocket(torso, torsoToHRP0, torsoToHRP1, 0, 0)
			createBallSocket(torso, torsoToRightArm0, torsoToRightArm1, 45, 0)
			createBallSocket(torso, torsoToLeftArm0, torsoToLeftArm1, 0, 45)
			createBallSocket(torso, torsoToRightLeg0, torsoToRightLeg1, -45, 45)
			createBallSocket(torso, torsoToLeftLeg0, torsoToLeftLeg1, -45, 45)

			humanoidRootPart:ApplyImpulse(humanoidRootPart.CFrame.LookVector * 100)

			RagdollCharacters[character.Name] = {}

			local connection = character.AncestryChanged:Once(function()
				RagdollCharacters[character.Name] = nil
			end)

			RagdollCharacters[character.Name].RagdollConnection = connection

			for _, v in character:GetDescendants() do
				pcall(function()
					if not v.Massless then
						v.Massless = true
						RagdollCharacters[character.Name][v] = true
					end
				end)

				if v.Name == "RagdollHitbox" then
					v.CollisionGroup = "Ragdolls"
					v.CanCollide = true
				elseif v:IsA("Motor6D") then
					v.Enabled = false
				end
			end
		end
	elseif
		humanoid.Health > 0
		and (not playerData:GetAttribute("Stun") or playerData:GetAttribute("AntiRagdoll"))
	then
		playerData:SetAttribute("Ragdoll", false)
		Module.Movement(player, humanoid, true)

		for _, v in torso:GetChildren() do
			if v:IsA("BallSocketConstraint") or v.Name:find("TorsoTo") then
				v:Destroy()
			end
		end

		if RagdollCharacters[character.Name] then
			RagdollCharacters[character.Name].RagdollConnection:Disconnect()
			RagdollCharacters[character.Name].RagdollConnection = nil

			for i in RagdollCharacters[character.Name] do
				i.Massless = false
			end

			RagdollCharacters[character.Name] = nil
		end

		for _, v in character:GetDescendants() do
			if v.Name == "RagdollHitbox" then
				v.CollisionGroup = "Players"
				v.CanCollide = false
			elseif v:IsA("Motor6D") then
				v.Enabled = true
			end
		end
	end
end

This for the Ragdoll script, it’s called on the server here

As for the Pushback script

Do notice, my personal belief is that it has nothing to do with the actual scripts because I remember similar behaviour happening when let’s say my character tripped for some reason, almost every time if I went to block which triggered a blocking animation I’d fling upwards to the sky like in the video