Doesn't detect if tool is touching player consistently

The sticks in my game are supposed to push back players, but on the client the touching of players isn’t detected consistently. In addition to that, when I attack a player with the stick over 100 times on only either arm, it is completely ignored. At least when I hit the Torso/HumanoidRootPart a couple of times it will eventually push the player back. And yes I checked, the client which is shown here is the issue.

local Players = game:GetService("Players")
local Teams = game:GetService("Teams")
local RunService = game:GetService("RunService")
local Workspace = game:GetService("Workspace")

local lobbyTeam = Teams.Lobby

local player = Players.LocalPlayer

local StickClient = {} :: StickClient

StickClient.CAN_DAMAGE_DURATION = 0.5
StickClient.SWING_DURATION = 0.25

function StickClient.init(self: StickClient, Modules)
	local previousTime = 0
	local animation = Instance.new("Animation")
	local childAdded: RBXScriptConnection? = nil
	local activated: RBXScriptConnection? = nil
	local touched: RBXScriptConnection? = nil
	local renderStepped: RBXScriptConnection? = nil

	local function characterAdded(character: Model)
		local active = false

		local humanoid = character:WaitForChild("Humanoid")
		if not humanoid then
			return
		end
		if humanoid.RigType == Enum.HumanoidRigType.R15 then
			animation.AnimationId = "rbxassetid://117635790220071"
		else
			animation.AnimationId = "rbxassetid://122585922776616"
		end

		local animator = character:WaitForChild("Humanoid"):WaitForChild("Animator")
		if not animator then
			return
		end

		childAdded = character.ChildAdded:Connect(function(tool: Instance)
			if not tool:IsA("Tool") then
				return
			end
			
			if renderStepped then
				renderStepped:Disconnect()
			end

			if activated then
				activated:Disconnect()
			end

			activated = tool.Activated:Connect(function()
				if player.Team == lobbyTeam then
					return
				end
				local now = time()
				local level = Modules.Communicator:sendSyncToServer("GetStickLevel", Modules.StickNamePurify(tool.Name))
				if level < 1 then
					return
				end
				local cooldown = Modules.StickStats[Modules.StickNamePurify(tool.Name)].Level[level].cooldown
				if now - previousTime >= cooldown then
					previousTime = now
					active = true
					local track = animator:LoadAnimation(animation)
					track:Play()
					task.wait(self.CAN_DAMAGE_DURATION)
					active = false
				end
			end)
			
			--local handle = tool:FindFirstChild("Handle")
			--if not handle then
			--	return
			--end

			--touched = handle.Touched:Connect(function(touchedPart)
			--	if not active then
			--		return
			--	end
			--	active = false
			--	if touchedPart.Parent:FindFirstChildWhichIsA("Humanoid", true) then
			--		Modules.Communicator:sendAsyncToServer("Knockback", touchedPart.Parent, tool.Name)
			--	end
			--end)
			
			renderStepped = RunService.PreSimulation:Connect(function(_deltaTime: number)
				local handle = tool:FindFirstChild("Handle")
				if not handle then
						renderStepped:Disconnect()
						return
				end
				--local EnemyCharacters = {}
				--for _, player in Players:GetPlayers() do
				--	if player == Players.LocalPlayer then
				--		continue
				--	end
					
				--	if player.Character then
				--		EnemyCharacters[#EnemyCharacters + 1] = player.Character
				--	end
				--end
				local overlapParams = OverlapParams.new()
				overlapParams.FilterType = Enum.RaycastFilterType.Exclude
				overlapParams:AddToFilter(character)
				for _, touchedPart in Workspace:GetPartsInPart(handle, overlapParams) do
					if not active then
						return
					end
					active = false
					if touchedPart.Parent:FindFirstChildWhichIsA("Humanoid", true) then
						print("yes")
						Modules.Communicator:sendAsyncToServer("Knockback", touchedPart.Parent, tool.Name)
					end
				end
			end)
		end)
	end

	if player.Character then
		characterAdded(player.Character)
	end

	player.CharacterAdded:Connect(characterAdded)

	player.CharacterRemoving:Connect(function(character: Model)
		if childAdded then
			childAdded:Disconnect()
		end

		if activated then
			activated:Disconnect()
		end
		
		if renderStepped then
			renderStepped:Disconnect()
		end
	end)
end

type StickClient = typeof(StickClient)

return StickClient
1 Like

Are the BaseParts for the stick, and character parts have “CanTouch” and/or “CanQuery” set to true?

Are the CollisionGroups the same? CollisionGroups, if not “grouped” properly wont trigger events.

I didn’t mess with the CollisionGroups in any way, thus they are at their default state. The Handles of all Sticks have CanTouch and CanQuery set to true. Furthermore the character of the player too, but the arms have CanCollide set to false.