Grip System Key Detection Problem

Hey everyone, i’m currently working on a grip and carry system and it is designed to allow players to interact with other players who are in a “knocked” state.

The knocked state is triggered when a player’s health drops to zero, at which point they are prevented from dying by setting their health to a minimum of 1. In this state, knocked players are immobilized and are eligible to be carried (“C”) or gripped (“B”) by other nearby players. This system involves two scripts: a ServerScript and a LocalScript.

The ServerScript handles setting a player’s knocked state, handling health restrictions, and listening for the B and C key presses to perform grip or carry actions. The LocalScript complements this by playing animations and sounds on the client side.

The issue here is that the B and C keys, which trigger the grip and carry actions, aren’t working as expected. Despite proximity checks and event setups. I dont know if this is an event handling problem or what exactly.

I’ll post both scripts down below for further clarity… Thanks everyone…

Server script

local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local FX = ReplicatedStorage:WaitForChild("FX")
local Sounds = ReplicatedStorage:WaitForChild("Sounds")
local Animations = ReplicatedStorage:WaitForChild("Animations")
local UserInputService = game:GetService("UserInputService")

local MIN_HEALTH_THRESHOLD = 1
local KNOCKED_DURATION = 50 
local GRIP_KEY = Enum.KeyCode.B
local CARRY_KEY = Enum.KeyCode.C
local PROXIMITY_RADIUS = 10

local GripEvent = ReplicatedStorage.Events:WaitForChild("GripEvent")
local CarryEvent = ReplicatedStorage.Events:WaitForChild("CarryEvent")
local DropEvent = ReplicatedStorage.Events:WaitForChild("DropEvent")

local function stopAllActions(character)
	local humanoid = character:FindFirstChild("Humanoid")
	if humanoid then
		humanoid.PlatformStand = true
		humanoid.WalkSpeed = 0
		humanoid.JumpPower = 0
		print("Stopping all actions for", character.Name)
	end
end

local function restoreNormalState(character)
	local humanoid = character:FindFirstChild("Humanoid")
	if humanoid then
		humanoid.PlatformStand = false
		humanoid.WalkSpeed = 16
		humanoid.JumpPower = 50
		print("Restoring normal state for", character.Name)
	end
end

local function applyKnockedState(character)
	if character:FindFirstChild("IsKnocked") and character.IsKnocked.Value == true then
		return
	end

	local humanoid = character:FindFirstChild("Humanoid")
	if not humanoid then return end

	humanoid.Health = MIN_HEALTH_THRESHOLD
	print(character.Name, "health set to", MIN_HEALTH_THRESHOLD)

	stopAllActions(character)
	character:SetPrimaryPartCFrame(character.HumanoidRootPart.CFrame * CFrame.new(0, -2, 0)) 
	character:FindFirstChild("IsKnocked").Value = true

	Sounds.Splurge:Play()

	print("Player is knocked:", character.Name)

	wait(KNOCKED_DURATION)

	restoreNormalState(character)
	character:FindFirstChild("IsKnocked").Value = false
	print("Knocked state ended for:", character.Name)
end
local function isPlayerCloseEnough(player, victim)
	local playerHRP = player.Character and player.Character:FindFirstChild("HumanoidRootPart")
	local victimHRP = victim:FindFirstChild("HumanoidRootPart")

	if playerHRP and victimHRP then
		local distance = (playerHRP.Position - victimHRP.Position).Magnitude
		print("Distance between player and victim:", distance)  
		return distance <= PROXIMITY_RADIUS
	end
	return false
end

local function preventDeath(humanoid)
	humanoid.HealthChanged:Connect(function()
		if humanoid.Health < MIN_HEALTH_THRESHOLD then
			humanoid.Health = MIN_HEALTH_THRESHOLD
		end
	end)
end

local function onKeyPress(player, key)
	print("Key pressed:", key) 

	local character = player.Character
	if not character then return end

	local humanoid = character:FindFirstChild("Humanoid")
	if not humanoid then return end

	local victim = nil
	local isKnocked = false

	for _, otherCharacter in pairs(workspace:GetChildren()) do
		if otherCharacter:FindFirstChild("Humanoid") then
			if otherCharacter:FindFirstChild("IsKnocked") and otherCharacter.IsKnocked.Value then
				victim = otherCharacter
				isKnocked = true
				break
			end
		end
	end

	if victim and isKnocked and isPlayerCloseEnough(player, victim) then
		if key == CARRY_KEY then
			local carryAnimation = Animations.Carry:Clone()
			local victimAnimation = Animations.BeingCarried:Clone()

			humanoid:LoadAnimation(carryAnimation):Play()
			victim:FindFirstChild("Humanoid"):LoadAnimation(victimAnimation):Play()

			Sounds.Splurge2:Play()

			local carryWeld = Instance.new("WeldConstraint")
			carryWeld.Parent = victim.HumanoidRootPart
			carryWeld.Part0 = character.HumanoidRootPart
			carryWeld.Part1 = victim.HumanoidRootPart

			victim:FindFirstChild("IsCarrying").Value = true
			character:FindFirstChild("IsCarrying").Value = true

			CarryEvent:FireClient(player, victim)

		elseif key == GRIP_KEY then
			local gripAnimation = Animations.Grip:Clone()
			local victimAnimation = Animations.BeingGripped:Clone()

			humanoid:LoadAnimation(gripAnimation):Play()
			victim:FindFirstChild("Humanoid"):LoadAnimation(victimAnimation):Play()

			Sounds.Hit:Play()

			local gripWeld = Instance.new("WeldConstraint")
			gripWeld.Parent = victim.HumanoidRootPart
			gripWeld.Part0 = character.HumanoidRootPart
			gripWeld.Part1 = victim.HumanoidRootPart

			victim:FindFirstChild("IsGripped").Value = true
			character:FindFirstChild("IsGripping").Value = true

			GripEvent:FireClient(player, victim)

			victim.Humanoid.Health = 0
		end
	else
		print("Player is not close enough to interact with victim.")
	end
end

Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(character)
		local isKnockedValue = Instance.new("BoolValue")
		isKnockedValue.Name = "IsKnocked"
		isKnockedValue.Value = false
		isKnockedValue.Parent = character

		local isCarryingValue = Instance.new("BoolValue")
		isCarryingValue.Name = "IsCarrying"
		isCarryingValue.Value = false
		isCarryingValue.Parent = character

		local isGrippedValue = Instance.new("BoolValue")
		isGrippedValue.Name = "IsGripped"
		isGrippedValue.Value = false
		isGrippedValue.Parent = character

		local humanoid = character:WaitForChild("Humanoid")
		preventDeath(humanoid)

		humanoid.HealthChanged:Connect(function()
			if humanoid.Health <= 0 then
				print(character.Name, "health reached 0, applying knocked state.")
				applyKnockedState(character)
			end
		end)
		UserInputService.InputBegan:Connect(function(input, isProcessed)
			if isProcessed then return end 
			if input.UserInputType == Enum.UserInputType.Keyboard then
				onKeyPress(player, input.KeyCode)
			end
		end)
	end)
end)

Local Script

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Animations = ReplicatedStorage:WaitForChild("Animations")
local Sounds = ReplicatedStorage:WaitForChild("Sounds")
local GripEvent = ReplicatedStorage.Events:WaitForChild("GripEvent")
local CarryEvent = ReplicatedStorage.Events:WaitForChild("CarryEvent")
local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Humanoid = Character:WaitForChild("Humanoid")
local UserInputService = game:GetService("UserInputService")


local function playGripAnimation(victim)
	local gripAnimation = Animations.Grip:Clone()
	local victimAnimation = Animations.BeingGripped:Clone()

	Humanoid:LoadAnimation(gripAnimation):Play()
	victim:FindFirstChild("Humanoid"):LoadAnimation(victimAnimation):Play()

	Sounds.Hit:Play()  -- Grip sound effect
end

local function playCarryAnimation(victim)
	local carryAnimation = Animations.Carry:Clone()
	local victimAnimation = Animations.BeingCarried:Clone()

	Humanoid:LoadAnimation(carryAnimation):Play()
	victim:FindFirstChild("Humanoid"):LoadAnimation(victimAnimation):Play()

	Sounds.Splurge2:Play()  -- Carry sound effect
end

GripEvent.OnClientEvent:Connect(function(player, victim)
	if player == Player then
		playGripAnimation(victim)  
	end
end)

CarryEvent.OnClientEvent:Connect(function(player, victim)
	if player == Player then
		playCarryAnimation(victim) 
	end
end)

UserInputService.InputBegan:Connect(function(input, isProcessed)
	if isProcessed then return end

	if input.UserInputType == Enum.UserInputType.Keyboard then
		if input.KeyCode == Enum.KeyCode.B then
			local victim = nil
			for _, otherCharacter in pairs(workspace:GetChildren()) do
				if otherCharacter:FindFirstChild("Humanoid") and otherCharacter:FindFirstChild("IsKnocked") and otherCharacter.IsKnocked.Value then
					victim = otherCharacter
					break
				end
			end

			if victim then
				GripEvent:FireServer(victim) 
			end
		end

		if input.KeyCode == Enum.KeyCode.C then
			local victim = nil
			for _, otherCharacter in pairs(workspace:GetChildren()) do
				if otherCharacter:FindFirstChild("Humanoid") and otherCharacter:FindFirstChild("IsKnocked") and otherCharacter.IsKnocked.Value then
					victim = otherCharacter
					break
				end
			end

			if victim then
				CarryEvent:FireServer(victim)
			end
		end
	end
end)

For one, you cannot use UserInputService or any client-based service on the server. The server doesn’t have any user input, it’s the server! Only clients can listen to user input directly. You have the right idea in mind, but your execution is slightly off.

Another thing is that you’re firing to the person doing the gripping or the carrying to play the animation on the victim on the client which won’t really work as well as you think it might because that animation might not replicate, the behavior will be pretty weird since you’re welding two network owners to each other, so they’ll be fighting over that network ownership and causing other unusual behavior.

I suggest finding a different solution that doesn’t use welds, maybe use RigidityEnabled with AlignPosition to mimic the behavior of a weld without the network ownership features.

1 Like

Thank you so much, that worked exactly as i wanted it to, had to move all input detection (UserInputService) to the client script as you stated, and i’m still working through welding issues trying to get it right.

On a side note, i dont know if you accept friend requests on discord, i’d love to occasionally learn from someone as knowledgeable as you, this has helped me a lot! :+1:

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.