JIT
Enhance Roblox Ragdoll Standing Realism
local humanoid = script.Parent:WaitForChild("Humanoid") local character = script.Parent local userInputService = game:GetService("UserInputService") local runService = game:GetService("RunService") humanoid.BreakJointsOnDeath = false -- Variables to track state local isRagdolled = false local attachmentPairs = {} local forces = {} -- Create a function to handle ragdolling local function makeRagdoll() if isRagdolled then return end isRagdolled = true for index, joint in pairs(character:GetDescendants()) do if joint:IsA("Motor6D") then 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 -- Store attachment pairs for later use table.insert(attachmentPairs, {a1 = a1, a2 = a2, part0 = joint.Part0, part1 = joint.Part1, originalC0 = joint.C0, originalC1 = joint.C1, jointName = joint.Name}) -- Set collision properties character.Head.CanCollide = true character.LeftHand.CanCollide = true character.RightHand.CanCollide = true character.RightFoot.CanCollide = true character.LeftFoot.CanCollide = true character.UpperTorso.CanCollide = true character.LowerTorso.CanCollide = true character.LeftUpperLeg.CanCollide = true character.RightUpperLeg.CanCollide = true character.LeftUpperArm.CanCollide = true character.RightUpperArm.CanCollide = true character.LeftLowerLeg.CanCollide = true character.RightLowerLeg.CanCollide = true character.LeftLowerArm.CanCollide = true character.HumanoidRootPart.CanCollide = false character.HumanoidRootPart.Velocity = character.LowerTorso.CFrame.lookVector * 1 socket.Attachment0 = a1 socket.Attachment1 = a2 a1.CFrame = joint.C0 a2.CFrame = joint.C1 socket.LimitsEnabled = true socket.TwistLimitsEnabled = true joint:Destroy() elseif joint:IsA("Attachment") and not joint:FindFirstAncestor("Accessory") then -- Don't remove accessories' attachments joint:Destroy() end end -- Optional: Change humanoid state to make it look ragdolled humanoid:ChangeState(Enum.HumanoidStateType.Physics) -- Automatically apply standing forces immediately after ragdolling -- Clear any existing forces first for _, force in pairs(forces) do force:Destroy() end forces = {} -- Create forces to simulate muscle tension for standing -- Upright torso local torsoForce = Instance.new("BodyGyro") torsoForce.Parent = character.UpperTorso torsoForce.MaxTorque = Vector3.new(10000, 10000, 10000) torsoForce.D = 100 torsoForce.P = 3000 torsoForce.CFrame = CFrame.new(character.UpperTorso.Position) * CFrame.Angles(0, character.HumanoidRootPart.Orientation.Y * math.pi/180, 0) table.insert(forces, torsoForce) -- Push lower torso up local lowerTorsoForce = Instance.new("BodyForce") lowerTorsoForce.Parent = character.LowerTorso lowerTorsoForce.Force = Vector3.new(0, character.LowerTorso:GetMass() * workspace.Gravity * 1.1, 0) table.insert(forces, lowerTorsoForce) -- Force for legs for _, legPart in pairs({"LeftUpperLeg", "RightUpperLeg", "LeftLowerLeg", "RightLowerLeg"}) do local legGyro = Instance.new("BodyGyro") legGyro.Parent = character[legPart] legGyro.MaxTorque = Vector3.new(5000, 5000, 5000) legGyro.D = 100 legGyro.P = 1000 -- Set orientation to make legs straight if legPart:find("Upper") then legGyro.CFrame = CFrame.new(character[legPart].Position) * CFrame.Angles(0, character.HumanoidRootPart.Orientation.Y * math.pi/180, 0) else legGyro.CFrame = CFrame.new(character[legPart].Position) * CFrame.Angles(0, character.HumanoidRootPart.Orientation.Y * math.pi/180, 0) end table.insert(forces, legGyro) end -- Arms slightly out (natural T-pose) for _, armPart in pairs({"LeftUpperArm", "RightUpperArm", "LeftLowerArm", "RightLowerArm"}) do local armGyro = Instance.new("BodyGyro") armGyro.Parent = character[armPart] armGyro.MaxTorque = Vector3.new(2000, 2000, 2000) armGyro.D = 50 armGyro.P = 800 -- Determine arm orientation local armAngle = 0 if armPart:find("Upper") then if armPart:find("Left") then armAngle = math.pi/2 + math.pi/8 -- slightly forward else armAngle = -math.pi/2 - math.pi/8 -- slightly forward end armGyro.CFrame = CFrame.new(character[armPart].Position) * CFrame.Angles(armAngle, character.HumanoidRootPart.Orientation.Y * math.pi/180, 0) else armGyro.CFrame = CFrame.new(character[armPart].Position) * CFrame.Angles(0, character.HumanoidRootPart.Orientation.Y * math.pi/180, 0) end table.insert(forces, armGyro) end -- Head upright local headGyro = Instance.new("BodyGyro") headGyro.Parent = character.Head headGyro.MaxTorque = Vector3.new(2000, 2000, 2000) headGyro.D = 100 headGyro.P = 1000 headGyro.CFrame = CFrame.new(character.Head.Position) * CFrame.Angles(0, character.HumanoidRootPart.Orientation.Y * math.pi/180, 0) table.insert(forces, headGyro) -- Balance force on the HumanoidRootPart local balanceForce = Instance.new("BodyGyro") balanceForce.Parent = character.HumanoidRootPart balanceForce.MaxTorque = Vector3.new(10000, 10000, 10000) balanceForce.D = 200 balanceForce.P = 5000 balanceForce.CFrame = CFrame.new(character.HumanoidRootPart.Position) * CFrame.Angles(0, character.HumanoidRootPart.Orientation.Y * math.pi/180, 0) table.insert(forces, balanceForce) -- Upward force to help standing local standForce = Instance.new("BodyForce") standForce.Parent = character.HumanoidRootPart standForce.Force = Vector3.new(0, character.HumanoidRootPart:GetMass() * workspace.Gravity * 1.2, 0) table.insert(forces, standForce) end -- Function to reset the character local function resetCharacter() if isRagdolled then isRagdolled = false -- Clear forces for _, force in pairs(forces) do force:Destroy() end forces = {} -- Destroy constraints and reset for _, joint in pairs(character:GetDescendants()) do if joint:IsA("BallSocketConstraint") then joint:Destroy() end end -- Reset the character humanoid:ChangeState(Enum.HumanoidStateType.GettingUp) -- Wait for the character to reset wait(0.5) humanoid:ChangeState(Enum.HumanoidStateType.Running) end end -- Connect the death event humanoid.Died:Connect(function() makeRagdoll() end) -- Add key press detection for 'R' userInputService.InputBegan:Connect(function(input, gameProcessed) if not gameProcessed then if input.KeyCode == Enum.KeyCode.R then makeRagdoll() -- This now automatically includes standing elseif input.KeyCode == Enum.KeyCode.Y then resetCharacter() end end end) -- Optional: Add a helper message local message = Instance.new("Message") message.Parent = workspace message.Text = "Press R to ragdoll (auto-standing), Y to reset" wait(5) message:Destroy()enhance this ragdoll, make it stand more realistically, this is what i want you to do, make the ragdoll stand with its legs seperated, i want the knees to bend on the weight, i want footplaninting, like one foot higher than another

Okay, I can help enhance the ragdoll script to achieve a more realistic standing pose with separated legs and bent knees. Implementing true dynamic foot planting based on terrain height is significantly more complex and often requires techniques like Inverse Kinematics (IK) or complex physics constraint manipulation (like AlignPosition/AlignOrientation driven by raycasts), which goes beyond simple BodyGyro adjustments.

However, we can simulate the appearance of bent knees and a wider stance using the existing BodyGyro approach by adjusting the target angles.

Here's the updated script incorporating these changes:

Key Changes:

  1. Collision Groups: Implemented basic collision groups (Ragdoll) to prevent the character's own limbs from colliding with each other during ragdoll, which often improves stability.
  2. Collision Management: Added functions storeOriginalCollisions and restoreOriginalCollisions to properly save and restore CanCollide and CollisionGroupId settings when toggling ragdoll.
  3. Torso Stability: Used separate BodyGyro instances for the UpperTorso and LowerTorso, focusing their torque on pitch/roll (X and Z axes) relative to the character's forward direction. Added a BodyForce specifically to the UpperTorso to help keep the upper body upright.
  4. Leg Separation (legSpreadAngle): Added a Y-axis rotation to the BodyGyro CFrame for the upper and lower legs to make them spread outwards.
  5. Knee Bend (kneeBendAngle): Added an X-axis rotation to the BodyGyro CFrame for the lower legs to simulate a bend at the knee.
  6. Relative Angles: Leg and arm angles are now applied relative to the HumanoidRootPart's orientation (currentOrientation) when the standing forces are applied. This makes the standing pose align with the direction the character was facing.
  7. Force/Torque Tuning: Adjusted MaxTorque, P, and D values. These often require significant experimentation to get right for your specific character model and desired stability. Added small upward BodyForce to legs.
  8. Arm Pose: Adjusted arm BodyGyro targets for a slightly more relaxed pose instead of a strict T-pose.
  9. HRP Balance: Removed the BodyGyro on the HumanoidRootPart as the torso gyros should now handle orientation. Kept the main upward BodyForce on the HRP, calculating it based on an approximation of the character's total mass.
  10. Reset: Improved the reset function to recreate the Motor6D joints correctly and slightly teleport the character upwards to avoid getting stuck.
  11. Cleanup: Added character.Destroying connection to clean up forces.

Remember that achieving perfect, dynamically stable standing on any surface with just BodyMovers is very challenging. This script provides a good visual approximation of the desired pose. You'll likely need to fine-tune the P, D, MaxTorque, angle values, and BodyForce magnitudes further to get the exact behavior you want.

Updated files
v1
19:23:38.269 Collision group not found. - Client - LocalScript:57

Okay, that error "Collision group not found" usually means the script tried to use PhysicsService:GetCollisionGroupId("Ragdoll") before the "Ragdoll" group was successfully created or registered by the service.

We can fix this by making the collision group creation more robust, ensuring it exists before we try to get its ID.

Here's the updated script with the fix:

Changes Made:

  1. setupCollisionGroup() Function: Created a dedicated function to handle the creation and retrieval of the collision group ID (ragdollGroupId).
  2. Robust Check: This function now uses pcall to safely check if the group exists. If not, it tries to create it (also within a pcall to catch errors). If creation fails, it warns the user and uses the default group ID (0) as a fallback.
  3. Called on Start: setupCollisionGroup() is called once when the script first runs to ensure the group is ready.
  4. Called Before Ragdoll: It's also called at the beginning of makeRagdoll() just to be absolutely sure the ragdollGroupId variable is correctly set before being used in the loop.
  5. Conditional Assignment: Inside the loop, part.CollisionGroupId = ragdollGroupId is only assigned if ragdollGroupId is not 0 (meaning the group was successfully found or created).

This should prevent the "Collision group not found" error by ensuring the script correctly handles the existence and creation of the collision group.

Updated files
v2