Help with handcuff system

I am trying to make a hand cuff system like liberty county, and so that the cop holds the player in front of them,

This is what I have:

As you can see, it all bugs out. The cop isn’t holding the player in the right way, and the player is affecting how the cop moves.

This is how I want it to look like:

image

Local Script (In handcuffs tool):

-- // Services
local PlayerService = game:GetService('Players')
local ReplicatedStorage = game:GetService('ReplicatedStorage')
local TeamService = game:GetService('Teams')
local RunService = game:GetService('RunService')

-- // refrences 
local Player = PlayerService.LocalPlayer
local Assets = ReplicatedStorage:WaitForChild('Assets')
local ArrestPrompt = Assets:WaitForChild('ArrestPrompt')
local CuffEvent = ReplicatedStorage:WaitForChild('Remotes'):WaitForChild('CuffEvent')

local Tool = script.Parent

local Prompts = {}

local function OnEquip()

	if Player.TeamColor ~= TeamService["Metropolitan Police"].TeamColor then
		return warn('Player is not on the police team!')
	end
	
	for _, GamePlayer in ipairs(PlayerService:GetPlayers()) do
		if GamePlayer.TeamColor == TeamService.Criminal.TeamColor then
			if GamePlayer.Character and GamePlayer.Character.Humanoid.Health > 0 then
				if not GamePlayer:FindFirstChild('Cuffed') then
					print('Cloning prompt')
					local ClonedPrompt = ArrestPrompt:Clone()
					ClonedPrompt.Parent = GamePlayer.Character.HumanoidRootPart

					table.insert(Prompts, ClonedPrompt)
				end
			
			end
		end
	end

	print('Tool Equipped')
	
	for Each, Prompt in ipairs(Prompts) do
		Prompt.Triggered:Connect(function()
			print('Triggered')
			local Victim = PlayerService:GetPlayerFromCharacter(Prompt.Parent.Parent)
			if Victim then
				CuffEvent:FireServer(Victim)
				Prompt.Enabled = false
				table.remove(Prompts, Each)
				Prompt:Destroy()
			end
		end)
	end
end

local function OnUnEquip()
	for _, Prompt in ipairs(Prompts) do
		Prompt:Destroy()
	end
	
	table.clear(Prompts)
end


Tool.Unequipped:Connect(OnUnEquip)
Tool.Equipped:Connect(OnEquip)

Server script:

-- // ARREST SYSTEM
-- // Created by: Suncurve 
-- // Date: 31/12/21
-- // Description: Handles arresting and cuffing.

-- // Services
local PlayerService = game:GetService('Players')
local ReplicatedStorage = game:GetService('ReplicatedStorage')
local TeamService = game:GetService('Teams')
local PhysicService = game:GetService('PhysicsService')

-- // Refrences
local Remotes = ReplicatedStorage.Remotes
local CuffRemote = Remotes.CuffEvent
local PlayerGroup = PhysicService:CreateCollisionGroup('PlayerGroup')
local PartGroup = PhysicService:CreateCollisionGroup('PartGroup')

PhysicService:CollisionGroupSetCollidable('PartGroup', 'PlayerGroup', false)

-- // Variables
local WantedRequired = false

-- // functions

local function OnCuff(Officer, Victim)
	-- make sure they 'exist' and haven't left the game
	if Officer and Victim then
		-- make sure neither of them are dead
		if Officer.Character.Humanoid.Health > 0 and Victim.Character.Humanoid.Health > 0 then
			-- Make sure that the player hasn't been cuffed by another officer
			if Victim:FindFirstChild('Cuffed') then
				return warn('Cuffed by another officer')
			end
			
			if (Victim.Character.Head.Position - Officer.Character.Head.Position).Magnitude > 15 then
				return warn('Too far away!')
			end
			
			
			-- Prevent any other officers cuffing the victim
			local CuffedValue = Instance.new('IntValue')
			CuffedValue.Name = 'Cuffed'
			CuffedValue.Value = 1
			CuffedValue.Parent = Victim
			
			-- Play cuffed animation
			local CurrentAnimations = Victim.Character.Humanoid:GetPlayingAnimationTracks()
			-- stop any current animations (such as walking)
			for i, track in pairs (CurrentAnimations) do
				track:Stop()
			end
			
			Victim.Character.Humanoid.WalkSpeed = 0
			Victim.Character.Humanoid.JumpPower = 0
			
			local CuffAnimation = Instance.new('Animation')
			CuffAnimation.AnimationId = 'rbxassetid://8413363246'
			CuffAnimation.Parent = Victim.Character
			
			local LoadedCuff = Victim.Character.Humanoid:LoadAnimation(CuffAnimation)
			LoadedCuff:Play()
			
			local OfficerAnimation = Instance.new('Animation')
			OfficerAnimation.AnimationId = 'rbxassetid://8413419782'
			OfficerAnimation.Parent = Officer.Character
			
			local LoadedOfficer = Officer.Character.Humanoid:LoadAnimation(OfficerAnimation)
			LoadedOfficer:Play()
			
			-- Weld the criminal to the Officer's hand so they can't move
			
			for _, Part in ipairs(workspace:GetDescendants()) do
				if Part:IsA('BasePart') then
					PhysicService:SetPartCollisionGroup(Part, 'PartGroup')
				end
			end
			
			for _, Part in ipairs(Victim.Character:GetDescendants()) do
				if Part:IsA('BasePart') then
					PhysicService:SetPartCollisionGroup(Part, 'PlayerGroup')
				end
			end
			
			Victim.Character.HumanoidRootPart.CFrame = Officer.Character.RightHand.CFrame * CFrame.new(0,0,0)
			
			local Weld = Instance.new('WeldConstraint')
			Weld.Name = 'CriminalWeld'
			Weld.Part0 = Officer.Character.RightHand
			Weld.Part1 = Victim.Character.HumanoidRootPart
			Weld.Parent = Officer.Character.RightHand
			
			
		end
	end
end

CuffRemote.OnServerEvent:Connect(OnCuff)

Would appreciate help, thank you!

3 Likes

Instead of using the Officer’s RightHand as where the CFrame would go, you could use the Officer’s HumanoidRootPart and tweak it a bit so it goes on the right hand of the Officer.

Victim.Character.HumanoidRootPart.CFrame = Officer.Character:WaitForChild("HumanoidRootPart").CFrame * CFrame.new(0,0,-2)

Something else you could try is set the whole Victim’s body to be Massless, so it does not affect the Officer’s movements.

Thank you, but now with the new code, the victim is in the falling animation:

If I don’t make the victim uncolliable with everything, then I get pushed into the ground. (video below)

How can I fix this? Thanks!

Code:

-- // ARREST SYSTEM
-- // Created by: Suncurve 
-- // Date: 31/12/21
-- // Description: Handles arresting and cuffing.

-- // Services
local PlayerService = game:GetService('Players')
local ReplicatedStorage = game:GetService('ReplicatedStorage')
local TeamService = game:GetService('Teams')
local PhysicService = game:GetService('PhysicsService')

-- // Refrences
local Remotes = ReplicatedStorage.Remotes
local CuffRemote = Remotes.CuffEvent
local PlayerGroup = PhysicService:CreateCollisionGroup('PlayerGroup')
local PartGroup = PhysicService:CreateCollisionGroup('PartGroup')

PhysicService:CollisionGroupSetCollidable('PartGroup', 'PlayerGroup', false)

-- // Variables
local WantedRequired = false

-- // functions

local function OnCuff(Officer, Victim)
	-- make sure they 'exist' and haven't left the game
	if Officer and Victim then
		-- make sure neither of them are dead
		if Officer.Character.Humanoid.Health > 0 and Victim.Character.Humanoid.Health > 0 then
			-- Make sure that the player hasn't been cuffed by another officer
			if Victim:FindFirstChild('Cuffed') then
				return warn('Cuffed by another officer')
			end
			
			if (Victim.Character.Head.Position - Officer.Character.Head.Position).Magnitude > 15 then
				return warn('Too far away!')
			end
			
			
			-- Prevent any other officers cuffing the victim
			local CuffedValue = Instance.new('IntValue')
			CuffedValue.Name = 'Cuffed'
			CuffedValue.Value = 1
			CuffedValue.Parent = Victim
			
			-- Play cuffed animation
			local CurrentAnimations = Victim.Character.Humanoid:GetPlayingAnimationTracks()
			-- stop any current animations (such as walking)
			for i, track in pairs (CurrentAnimations) do
				track:Stop()
			end
			
			Victim.Character.Humanoid.WalkSpeed = 0
			Victim.Character.Humanoid.JumpPower = 0
			
			local CuffAnimation = Instance.new('Animation')
			CuffAnimation.AnimationId = 'rbxassetid://8413363246'
			CuffAnimation.Parent = Victim.Character
			
			local LoadedCuff = Victim.Character.Humanoid:LoadAnimation(CuffAnimation)
			LoadedCuff:Play()
			
			local OfficerAnimation = Instance.new('Animation')
			OfficerAnimation.AnimationId = 'rbxassetid://8413419782'
			OfficerAnimation.Parent = Officer.Character
			
			local LoadedOfficer = Officer.Character.Humanoid:LoadAnimation(OfficerAnimation)
			LoadedOfficer:Play()
			
			-- Weld the criminal to the Officer's hand so they can't move
	
			
			for _, Part in ipairs(Victim.Character:GetDescendants()) do
				if Part:IsA('BasePart') then
					Part.Massless = true
				end
			end
			
			Victim.Character.HumanoidRootPart.CFrame = Officer.Character:WaitForChild("HumanoidRootPart").CFrame * CFrame.new(0,.6,-2.5)
			
			local Weld = Instance.new('WeldConstraint')
			Weld.Name = 'CriminalWeld'
			Weld.Part0 = Officer.Character.RightHand
			Weld.Part1 = Victim.Character.HumanoidRootPart
			Weld.Parent = Officer.Character.RightHand
			
			
		end
	end
end

CuffRemote.OnServerEvent:Connect(OnCuff)

You could try changing the victim’s HumanoidStateType. Since it’s currently on the “Falling” state, try switching it over to “None”, it’s up to you to try the state that works best.

Since I’m not really good with that topic, here’s a link to the official API Reference.
https://cdn.discordapp.com/attachments/746690621414047794/926351702586699786/funky_fumo_friday.mp4

1 Like

In the end, I solved it by using massless, and setting the PlatformStand to true on the Victim’s humanoid.

2 Likes