Howdy Roblox devs! For a couple of days I’ve been trying to get a good, realistic ragdoll in my game and it works great for my standards when I am in “Run” mode, but when I do “Play” mode it looks like crap and it’s all laggy and stuff. Does anyone have any solutions? (If anyone would like to see the script that I’m using I can comment it) Thanks for reading!
Could I see both the script and a video showcasing it?
yeah of course!
Run Mode (awesome lookin ragdoll imo) ↓
Play Mode (doo doo ragdoll imo) ↓
and here’s the main ragdoll script:
wait(2)
for i, v in pairs(game:GetDescendants()) do
if v:IsA("Model") and v:FindFirstChildOfClass("Humanoid") then
--> Make sure this script is located under the Character Model
local Character: Model = v
local Torso: BasePart = Character:WaitForChild("Torso")
local Humanoid: Humanoid = Character:FindFirstChildOfClass("Humanoid")
--> Necessary for Ragdolling to function properly
Character.Humanoid.BreakJointsOnDeath = false
Character.Humanoid.RequiresNeck = false
--> Specific CFrame's made for the best looking Ragdoll
local attachmentCFrames = {
["Neck"] = {CFrame.new(0, 1, 0, 0, -1, 0, 1, 0, -0, 0, 0, 1), CFrame.new(0, -0.5, 0, 0, -1, 0, 1, 0, -0, 0, 0, 1)},
["Left Shoulder"] = {CFrame.new(-1.3, 0.75, 0, -1, 0, 0, 0, -1, 0, 0, 0, 1), CFrame.new(0.2, 0.75, 0, -1, 0, 0, 0, -1, 0, 0, 0, 1)},
["Right Shoulder"] = {CFrame.new(1.3, 0.75, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1), CFrame.new(-0.2, 0.75, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1)},
["Left Hip"] = {CFrame.new(-0.5, -1, 0, 0, 1, -0, -1, 0, 0, 0, 0, 1), CFrame.new(0, 1, 0, 0, 1, -0, -1, 0, 0, 0, 0, 1)},
["Right Hip"] = {CFrame.new(0.5, -1, 0, 0, 1, -0, -1, 0, 0, 0, 0, 1), CFrame.new(0, 1, 0, 0, 1, -0, -1, 0, 0, 0, 0, 1)},
}
local ragdollInstanceNames = {
["RagdollAttachment"] = true,
["RagdollConstraint"] = true,
["ColliderPart"] = true,
}
--> Used to trigger Ragdoll
local RagdollValue = Instance.new("BoolValue")
RagdollValue.Name = "IsRagdoll"
RagdollValue.Parent = Character
-------------------------------------------------------------------------------------------------
--> push :)
local function push()
local velRange = math.random() < 0.5 and {-35, -25} or {25, 35}
local angularVelRange = math.random() < 0.5 and {-85, -30} or {30, 85}
-- Torso:ApplyImpulse(Vector3.new(math.random(velRange[1], velRange[2]), 0, math.random(velRange[1], velRange[2])))
Torso:ApplyAngularImpulse(Vector3.new(math.random(angularVelRange[1], angularVelRange[2]),math.random(angularVelRange[1], angularVelRange[2]),0)) --(Vector3.new(math.random(angularVelRange[1], angularVelRange[2]), math.random(angularVelRange[1], angularVelRange[2]), math.random(angularVelRange[1], angularVelRange[2])))
end
--> Allows for proper limb collisions
local function createColliderPart(part: BasePart)
if not part then return end
local rp = Instance.new("Part")
rp.Name = "ColliderPart"
rp.Size = part.Size/1.7
rp.Massless = true
rp.CFrame = part.CFrame
rp.Transparency = 1
local wc = Instance.new("WeldConstraint")
wc.Part0 = rp
wc.Part1 = part
wc.Parent = rp
rp.Parent = part
end
--converts motor 6d's with ballsocketconstraints
local function replaceJoints()
for _, motor: Motor6D in pairs(Character:GetDescendants()) do
if motor:IsA("Motor6D") then
if not attachmentCFrames[motor.Name] then return end
motor.Enabled = false;
local a0, a1 = Instance.new("Attachment"), Instance.new("Attachment")
a0.CFrame = attachmentCFrames[motor.Name][1]
a1.CFrame = attachmentCFrames[motor.Name][2]
a0.Name = "RagdollAttachment"
a1.Name = "RagdollAttachment"
createColliderPart(motor.Part1)
local b = Instance.new("BallSocketConstraint")
b.Attachment0 = a0
b.Attachment1 = a1
b.Name = "RagdollConstraint"
-- Set different constraint properties based on the joint
if motor.Name == "Neck" then
b.Radius = 0.1
b.LimitsEnabled = true
b.TwistLimitsEnabled = true
b.UpperAngle = 45
b.TwistLowerAngle = -70
b.TwistUpperAngle = 70
elseif motor.Name == "Left Shoulder" or motor.Name == "Right Shoulder" then
b.Radius = 0.2
b.LimitsEnabled = true
b.TwistLimitsEnabled = true
b.UpperAngle = 50
b.TwistLowerAngle = -30
b.TwistUpperAngle = 30
elseif motor.Name == "Left Hip" or motor.Name == "Right Hip" then
b.Radius = 0.3
b.LimitsEnabled = true
b.TwistLimitsEnabled = true
b.UpperAngle = 25
b.TwistLowerAngle = -30
b.TwistUpperAngle = 30
end
b.MaxFrictionTorque = 0
b.Restitution = 0
a0.Parent = motor.Part0
a1.Parent = motor.Part1
b.Parent = motor.Parent
end
end
end
--> Destroys all Ragdoll made instances and re-enables the Motor6D's
local function resetJoints()
if Humanoid.Health < 1 then return end
for _, instance in pairs(Character:GetDescendants()) do
if ragdollInstanceNames[instance.Name] then
instance:Destroy()
end
if instance:IsA("Motor6D") then
instance.Enabled = true;
end
end
end
local function Ragdoll(value: boolean)
if value then
Humanoid:ChangeState(Enum.HumanoidStateType.Ragdoll)
Humanoid:SetStateEnabled(Enum.HumanoidStateType.GettingUp, false)
replaceJoints()
push()
else
resetJoints()
Humanoid:ChangeState(Enum.HumanoidStateType.GettingUp)
end
end
-------------------------------------------------------------------------------------------------
--> Connect the Events
RagdollValue.Changed:Connect(Ragdoll)
Humanoid.Died:Once(function()
RagdollValue.Value = true
push()
end)
end
end
--[[
for i, v in pairs(workspace:GetChildren()) do
if v:IsA("Model") and v:FindFirstChildOfClass("Humanoid") then
wait(.25)
v:FindFirstChild("IsRagdoll").Value = true
end
end]]
In the videos you’re showing, you’re using the R6 avatar… which is known to have a very bland response with any ragdoll system. I’d recommend swapping to R15 for a cooler Ragdoll effect.
Is the ragdoll script a LocalScript or a script? From what I can see from the video, the ragdoll doesn’t replicate to the client, whereas you can see the ragdoll clearly from the server’s view (Run Mode)
no. that’s not how it works.
the posters problem is most likely because physics replication.
yeah its a server script I tried to change it from server to client replication but it just leaves the limbs behind and works even worse.
i’m just trying to use R6 cause i was gonna make a stealth game cause i’m more comfortable with R6 regarding things like sizes and i thought it would be unique and simpler…
how could i effectively replicate it to the client (sorry that your miserable)
If it’s a server script it should be able to replicate it to every client. Could you try to compare the RagdollValue.Value
in both the client and the server? And ensure that the constraints and attachments are properly created too.
I usually set the players state on the client, and server. Try setting the Humanoids State on the Client, alongside the server.
you can try to set the NPC networkownership to a player client.
It turns out I forgot that I use the exact if not the same ragdoll script, try mine and lmk if it works. I only added client NetworkOwnership for smoothier ragdoll
--> Make sure this script is located in StarterPlayer.StarterCharacterScripts
local Character: Model = script.Parent
local Torso: BasePart = Character:WaitForChild("Torso")
local Humanoid: Humanoid = Character:FindFirstChildOfClass("Humanoid")
--> Necessary for Ragdolling to function properly
Character.Humanoid.BreakJointsOnDeath = false
Character.Humanoid.RequiresNeck = false
--> Specific CFrame's I made for the best looking Ragdoll
local attachmentCFrames = {
["Neck"] = {CFrame.new(0, 1, 0, 0, -1, 0, 1, 0, -0, 0, 0, 1), CFrame.new(0, -0.5, 0, 0, -1, 0, 1, 0, -0, 0, 0, 1)},
["Left Shoulder"] = {CFrame.new(-1.3, 0.75, 0, -1, 0, 0, 0, -1, 0, 0, 0, 1), CFrame.new(0.2, 0.75, 0, -1, 0, 0, 0, -1, 0, 0, 0, 1)},
["Right Shoulder"] = {CFrame.new(1.3, 0.75, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1), CFrame.new(-0.2, 0.75, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1)},
["Left Hip"] = {CFrame.new(-0.5, -1, 0, 0, 1, -0, -1, 0, 0, 0, 0, 1), CFrame.new(0, 1, 0, 0, 1, -0, -1, 0, 0, 0, 0, 1)},
["Right Hip"] = {CFrame.new(0.5, -1, 0, 0, 1, -0, -1, 0, 0, 0, 0, 1), CFrame.new(0, 1, 0, 0, 1, -0, -1, 0, 0, 0, 0, 1)},
}
local ragdollInstanceNames = {
["RagdollAttachment"] = true,
["RagdollConstraint"] = true,
["ColliderPart"] = true,
}
-------------------------------------------------------------------------------------------------
--> Allows for proper limb collisions
local function createColliderPart(part: BasePart)
if not part then return end
local rp = Instance.new("Part")
rp.Name = "ColliderPart"
rp.Size = part.Size/1.7
rp.Massless = true
rp.CFrame = part.CFrame
rp.Transparency = 1
local wc = Instance.new("WeldConstraint")
wc.Part0 = rp
wc.Part1 = part
wc.Parent = rp
rp.Parent = part
end
--> Converts Motor6D's into BallSocketConstraints
local function replaceJoints()
Humanoid.AutoRotate = false --> Disabling AutoRotate prevents the Character rotating in first person or Shift-Lock
for _, motor: Motor6D in pairs(Character:GetDescendants()) do
if motor:IsA("Motor6D") then
if not attachmentCFrames[motor.Name] then return end
motor.Enabled = false;
local a0, a1 = Instance.new("Attachment"), Instance.new("Attachment")
a0.CFrame = attachmentCFrames[motor.Name][1]
a1.CFrame = attachmentCFrames[motor.Name][2]
a0.Name = "RagdollAttachment"
a1.Name = "RagdollAttachment"
createColliderPart(motor.Part1)
local b = Instance.new("BallSocketConstraint")
b.Attachment0 = a0
b.Attachment1 = a1
b.Name = "RagdollConstraint"
b.Radius = 0.15
b.LimitsEnabled = true
b.TwistLimitsEnabled = false
b.MaxFrictionTorque = 0
b.Restitution = 0
b.UpperAngle = 90
b.TwistLowerAngle = -45
b.TwistUpperAngle = 45
if motor.Name == "Neck" then
b.TwistLimitsEnabled = true
b.UpperAngle = 45
b.TwistLowerAngle = -70
b.TwistUpperAngle = 70
end
a0.Parent = motor.Part0
a1.Parent = motor.Part1
b.Parent = motor.Parent
end
end
end
--> Destroys all Ragdoll made instances and re-enables the Motor6D's
local function resetJoints()
if Humanoid.Health < 1 then return end
for _, instance in pairs(Character:GetDescendants()) do
if ragdollInstanceNames[instance.Name] then
instance:Destroy()
end
if instance:IsA("Motor6D") then
instance.Enabled = true;
end
end
Humanoid.AutoRotate = true
end
local function Ragdoll(value: boolean)
if value then
replaceJoints()
local Player = game:GetService("Players"):GetPlayerFromCharacter(Character)
if Player then
for _, part in pairs(Character:GetDescendants()) do
if part:IsA("BasePart") then
part:SetNetworkOwner(Player)
end
end
end
else
resetJoints()
end
end
local Connection
Connection = Humanoid.Changed:connect(function()
if Humanoid then
if Humanoid.Health <= 0 then
Connection:Disconnect()
Humanoid:ChangeState(Enum.HumanoidStateType.Dead)
Ragdoll(true)
end
end
end)
ill try to try all of that stiff but i probably should mention that the ragdoll is and npc and the thing that i dont like about the play mode ragdoll is that like the limbs kinda freeze middair and stuff but yeah ill try those as soon as i can thanks guys
Yeah this looks like its a network issue. If the animation is run on the server then call the function :SetNetworkOwner(nil)
on the HumanoidRootPart
If the animation is run locally then do :SetNetworkOwner(Player)
sorry i think there might be a little bita confusion theres no animations is just like the ballsocketconstraits on the ragdoll but yeah ill try setting the network ownership later today prob if i can
ok i just tried doing that, it doesn’t work though because the check for the change of value is in a server script.
i tried your script and unfortunatly it looks the same as the second clip that I sent. what i’m really trying to do it just make the ragdoll look smooth, idk if any of you have played entry point but you might’ve noticed that the ragdolls in that look smooth and i can’t find out how to do it.
Do you have any other external scripts interfering with the ragdoll script?
dude im such a fetching idiot sorry i forgot to say in the title that its nps that look crappy specifically