Inconsistent Touched Event

I’ve scripted a gum gum pistol but the touched event is really inconsistent, i also have another bug where if i hit 1 npc then i hit another, the first one that i hit takes the damage instead of the 2nd one i hit

External Media
-- Local Script --
local CAS = game:GetService("ContextActionService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local Player = game.Players.LocalPlayer
local Mouse = Player:GetMouse()

local Char = Player.Character or Player.CharacterAdded:Wait()
local Humanoid = Char:WaitForChild("Humanoid")
local HRP = Char:WaitForChild("HumanoidRootPart")

local Animations = ReplicatedStorage:WaitForChild("Animations").GumGum
local Remote = ReplicatedStorage:WaitForChild("Remotes").GumGumRemote

local Charging = false
local SkillInUse = false

local Debounces = {
	Pistol = false
}

local Cooldowns = {
	Pistol = 0
}

local function ActionHandler(ActionName, InputState, InputObject)
	
	if ActionName == "Pistol"  and InputState == Enum.UserInputState.Begin then
		
		if not Debounces.Pistol and not SkillInUse then
			Debounces.Pistol = true
			SkillInUse = true
			Charging = true
			
			HRP.Anchored = true

			local AnimationTrack = Humanoid:FindFirstChild("Animator"):LoadAnimation(Animations.PistolStart)
			AnimationTrack:Play()
			
			repeat
				HRP.CFrame = CFrame.new(HRP.Position, Mouse.Hit.Position)
				wait()
			until Charging == false
			
			AnimationTrack:Stop()
			AnimationTrack = nil
			
			AnimationTrack = Humanoid:FindFirstChild("Animator"):LoadAnimation(Animations.PistolEnd)
			AnimationTrack:Play()
			
			local Data = {Action = "Pistol", Direction = Mouse.Hit}
			
			AnimationTrack:GetMarkerReachedSignal("PistolBegin"):Connect(function()
				Remote:FireServer(Data)
				
				wait(.4)
				
				SkillInUse = false
				HRP.Anchored = false
				
				wait(Cooldowns.Pistol)
				Debounces.Pistol = false
			end)
		end
		
	elseif ActionName == "Pistol" and InputState == Enum.UserInputState.End then
		Charging = false
	end
	
end

script.Parent.Equipped:Connect(function()
	CAS:BindAction("Pistol",ActionHandler,false,Enum.KeyCode.Z)
end)

script.Parent.Unequipped:Connect(function()
	CAS:UnbindAction("Pistol")
end)
-- Server Script --
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TweenService = game:GetService("TweenService")

local Remote = ReplicatedStorage:WaitForChild("Remotes").GumGumRemote

Remote.OnServerEvent:Connect(function(Player, data)

	local Char = Player.Character
	local HRP = Char:FindFirstChild("HumanoidRootPart")
	local Humanoid = Char:FindFirstChild("Humanoid")

	local LeftArm = Char:FindFirstChild("Left Arm")
	local RightArm = Char:FindFirstChild("Right Arm")

	if data.Action == "Pistol" then

		RightArm.Transparency = 1

		local FakeArm = Instance.new("Part",workspace.JunkParts)
		FakeArm.CanCollide = true
		FakeArm.Size = Vector3.new(1,1,2)
		FakeArm.CFrame = CFrame.new(RightArm.Position,data.Direction.Position)
		FakeArm.Color = RightArm.Color
		FakeArm.Material = RightArm.Material

		local Weld = Instance.new("Weld")
		Weld.Part0 = FakeArm
		Weld.Part1 = RightArm
		Weld.Parent = Weld.Part0
		
		local Info = TweenInfo.new(.15,Enum.EasingStyle.Bounce,Enum.EasingDirection.InOut,0,true)
		local ArmTween = TweenService:Create(FakeArm,Info,{Size = Vector3.new(1.5,1.5*30,1.5)})
		local WeldTween = TweenService:Create(Weld,Info,{C0 = Weld.C0 * CFrame.new(0,45/2,0)})
		ArmTween:Play()
		WeldTween:Play()
		
		coroutine.wrap(function()
			ArmTween.Completed:Wait()
			FakeArm:Destroy()
			RightArm.Transparency = 0
			HRP.Anchored = false
		end)()
		
		local PlayersHit = {}
		
		FakeArm.Touched:Connect(function(hit)
			if not hit:IsDescendantOf(workspace.Map) and hit.Parent ~= Char then
				
				local eHumanoid = hit.Parent:FindFirstChild("Humanoid")
				local eHRP = hit.Parent:FindFirstChild("HumanoidRootPart")
				
				if eHRP and eHumanoid and eHumanoid.Health > 0 and not PlayersHit[eHumanoid.Parent.Name] then
					PlayersHit[eHumanoid.Parent.Name] = true
					eHumanoid:TakeDamage(10)
				end
			end
		end)
				
	end

end)
2 Likes

using touched as a hitbox is the worst thing you could do when making an ability, instead make a separate hitbox module by using overlapparams or raycast but NOT touched :sob: , I cant make a whole hitbox system for you but yeah hope this helps

I used :GetPartBoundsInBox and it worked. Can u go into more detail about the module tho?

I mean what would you like to know? By making a module you can do many checks inside it and add statements and allat, like you can make it so you can set the hitbox’s size and cframe everytime you run the module etc, and then obviously you can make the module return a table of all characters found inside the hitbox which then will be very useful

Ok i get it, thanks for your help