How Can I Make An Efficient Handcuff System?

Hello there. I’ll try to make this quick a simple. I already have a working handcuff system that I made which handcuffs a person, un-handcuffs them, grabs them, and releases them. Although it is working, there are a couple of flaws with it. These flaws come down to the grabbing system.

The first flaw is the lag produced when a player is grabbing another player and the cuffed player is moving. Although I do set the NetworkOwnership of all player’s body parts to the player grabbing them, the player is still applying their forces. Of course, when grabbed I do put the player in platform stand, but if they gain the ability of control, then it creates this “lagging” effect and it’s hard to control.

The second flaw is a death chain effect. Basically, when one of the players dies, the other one (either grabbing or being grabbed) dies as well. I am assuming that is caused because of the BreakJoints() function that runs whenever a player dies, but I am not very sure.

I know that there are similar posts, but they don’t really answer my main question which is, what is the most effective way to make a handcuff system? In my handcuff system, I use a weld which is placed inside the player being grabbed and is causing this issue. The weld is linked between the two players’ HumanoidRootPart. I am remaking a whole new system, and would like to know if there is a more efficient way of simulating the “grab” effect without having to disable their movement whatsoever. I know it is possible to do this some way, as I have seen it in other games like New Haven County, which uses something that has to do with NetworkOwnership. I also had the idea of using CFrame to move the player, but I don’t know how well that will work because it’s probably going to be using a lot of resources.

Here is the code so you can take a better look at it and understand it better:

Useful Variables:

local Character = Player.Character
local Humanoid = Character:WaitForChild("Humanoid")
local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")
local TargetCharacter = Target.Character
local TargetHumanoid = TargetCharacter:WaitForChild("Humanoid")
local TargetHumanoidRootPart = TargetCharacter:WaitForChild("HumanoidRootPart")
local PlayerArrestData = HumanoidRootPart:WaitForChild("ArrestData")
local TargetArrestData = TargetHumanoidRootPart:WaitForChild("ArrestData")

(Player is the player that is grabbing and Target is the player being grabbed)

Grab Part:

if TargetArrestData:WaitForChild("IsCuffed").Value == true then
	if TargetArrestData:WaitForChild("GrabbedBy").Value == nil then
		local Weld = Instance.new("Weld")
	    Weld.Part0 = HumanoidRootPart
	    Weld.Part1 = TargetHumanoidRootPart
	    Weld.C0 = CFrame.new(1.5, 0, -2.75)
		Weld.Name = "CuffWeld"
	    Weld.Parent = HumanoidRootPart
		TargetHumanoid.WalkSpeed = 0
		TargetHumanoid.JumpPower = 0
		if TargetHumanoid.Sit == true then
			TargetHumanoid.Sit = false
		end
		TargetHumanoid.PlatformStand = true
		TargetArrestData:WaitForChild("GrabbedBy").Value = Player
		PlayerArrestData:WaitForChild("Grabbing").Value = Target
		local function SetNetworkOwnership(Father)
			for i, v in pairs(Father:GetChildren()) do
				if v:IsA("BasePart") then
					v:SetNetworkOwner(Player)
					v.Massless = true
				end
				if #v:GetChildren() > 0 then
					SetNetworkOwnership(v)
				end
			end
		end
		SetNetworkOwnership(Target.Character)
	end
end

If you have any ideas, please let me know below. Thank you for your time and effort.

8 Likes

Are you creating a weld or cframing it on the renderstep? If your problem is with the :BreakJoints() try to not parent it to the other player and cframe it instead of using a weld if you where

2 Likes

Thank you for the reply. I am using a weld that is placed inside the HumanoidRootPart of the player that is being grabbed. The :BreakJoints() function is an assumption and not 100% verified. I guess that the function is the reason because of how the function works.
Quote from the function’s page:

Breaks connections between BaseParts , including surface connections with any adjacent parts, WeldConstraint s, and all Weld s and other JointInstance s.

When BreakJoints is used on a Player character Model , the character’s Humanoid will die as it relies on the Neck joint.

I will try to parent it into somewhere else. That should probably fix the death chain problem, but the first one remains. Thanks for the suggestion.

EDIT: Changing the parent of the weld does not change anything. It still kills the player grabbing if the player grabbed by dies.

As @Dev_HDWC mentioned, Set the cframe instead. Here is some rough example code. Not going to test it but it should lead you in the general direction.

local Target = game.Players.Player1 -- Person being held
local Attacker = game.Players.Player2 -- Person holding other person



while wait() do
    local TargetCharacter = Target.Character
    local AttackerCharacter = Attacker.Character
    if TargetCharacter and AttackerCharacter then
        local TargetHRP = TargetCharacter:FindFirstChild("HumanoidRootPart")
        local AttackerHRP = AttackerCharacter:FindFirstChild("HumanoidRootPart")
        if TargetHRP and AttackerHRP then
            TargetHRP.CFrame = AttackerHRP.Cframe * CFrame.new(1,0, -2)
        end
    end
end
2 Likes

Thank you for the reply. I thought of this too as well, I just don’t know if it’s worth the resources. I want to see if doing it with welds is possible. Clearly, CFrame would work great as it would solve all of the problems, but it would take up a lot of resources, especially if you have multiple players grabbing other players. I truly believe weld is possible, because as mentioned above, I believe a game called “New Haven County” as it shows signs of NetworkOwnership, which are not visible when using CFrame unless CFraming from the client (making assumptions here), which I don’t think is possible. If I’m wrong please correct me because that might be the way to do it. Again, thanks for the reply and the suggestion.

I’ll hop into studio and try and figure something out for you :slight_smile: Could you send me the code you currently use? So I can save a bit of time. – Ignore that I was being dumb dumb.

2 Likes

He dies, because you’re using Weld, you can just exchange of using weld, use a loop to position target

Thank you for the reply. I do know that and I even stated it.

I am planning on using a loop and CFrame’ing the character instead, I just wanted to figure out if there is a way to do it with welds, which at this point I am assuming not.

Thank you for the reply and suggestion though.

If you don’t want them to be able to move if they’re being handcuffed, you could set their walkspeed to 0 for the time that they’re cuffed.

He already does this. But that’s not what he is referring to.

1 Like

@Aiza_Teizuki is correct. I already replicated this in my system, but I am trying to find a way to make this so it works regardless of the person moving, dancing, e.t.c.

Thank you for the reply and the suggestion though.

1 Like

So I found a way around both players dying. It was quite simple. Instead of trying to explain I will just give you some code that I used. I ran a server of 2 “clients” in studio and ran this on the server. Pretty much I just make a temporary weld part. This should? solve the lag.

local Target = game.Players.Player1 -- Person being held
local Attacker = game.Players.Player2 -- Person holding other person


local TargetCharacter = Target.Character
local AttackerCharacter = Attacker.Character
local TargetHumanoid = TargetCharacter:FindFirstChild("Humanoid")
local AttackerHumanoid = AttackerCharacter:FindFirstChild("Humanoid")

local function NewWeld(Part1, Part2, Offset)
	Offset = Offset or CFrame.new(0,0,0)
	local Weld = Instance.new("Weld")
    Weld.Part0 = Part1
    Weld.Part1 = Part2
    Weld.C0 = Offset
	Weld.Name = "Weld"
    Weld.Parent = game.Workspace.Welds
	return(Weld)
end

if TargetCharacter and AttackerCharacter and TargetHumanoid and AttackerHumanoid then
    local TargetHRP = TargetCharacter:FindFirstChild("HumanoidRootPart")
    local AttackerHRP = AttackerCharacter:FindFirstChild("HumanoidRootPart")
    if TargetHRP and AttackerHRP then
		local part = Instance.new("Part")
		part.Size = Vector3.new(0.01, 0.01, 0.01)
		part.Parent = AttackerHRP
		local weld1 = NewWeld(TargetHRP, part)
		local weld2 = NewWeld(AttackerHRP, part, CFrame.new(1.5, 0, -2.75))

		TargetHumanoid.WalkSpeed = 0
		TargetHumanoid.JumpPower = 0
		if TargetHumanoid.Sit == true then
			TargetHumanoid.Sit = false
		end
		TargetHumanoid.PlatformStand = true
		
		DiedConn = AttackerHumanoid.Died:Connect(function()
			weld1:Destroy()
			weld2:Destroy()
			TargetHumanoid.WalkSpeed = 16
			TargetHumanoid.JumpPower = 50
			TargetHumanoid.PlatformStand = false
			DiedConn:Disconnect()
		end)
    end
end
6 Likes

Brilliant! That is an incredible idea. I thought of that as well, but not with that much detail into it. This could for sure work. I’ll give it a try once I come back. This should certainly fix the death chain problem. Thank you a lot.

CFraming from the client is very well possible. You would basically just set the network owner of the player to said other player and from there on out you can handle anything. Though instead I would recommend setting the network owner of a dummy humanoid root part, and then just moving the over from there to prevent exploiters of performing :Destroy() on the player they are now on.

1 Like

Sorry, I gotta ask, are you even able to set the networkownership of a players character? Would roblox not automatically set it back to their own client. Also if you were able to do this. Can’t a exploiter just parent your body to nil?

1 Like

This is why you would make a dummy part and cframe on the other client. You could set the network owner of the part to the player or you could just change the cframe on the server.

1 Like

I love the way you both think about it. I’ll probably use a dummy part as that will probably work best. I’ll test that soon and tell you the results. I thank both of you for the awesome replys and suggestions!

I ended up using the CFrame system. It works very well. I did end up changing the CFrame from the client. Other than some small changes, your code works as intended. Thank you!

You should probably set a maximal distance beetween the player humanoidRootPart and the one who’s detained since exploiter can teleport and break the weld.

Or all part of the character since they can move whatever part of their body they wants