What's a good way of replacing .Touched()?

Hello There!

I’m creating a minigun which fires bullets, the only issue with these bullets is that they use .Touched() which is something I want to avoid using. The reason why is quite simple actually, the .Touched() event is too slow to fire and since the bullets move incredibly fast (Which, in my calculation, 1000 Studs per second I think), the bullets sometimes doesn’t register that a humanoid has been hit and simply phases through them.

So what is a better choice of detecting if a bullet hits a humanoid without using .Touched(). Should I use Region3 or something like GetPartsInPart?

1 Like

If you need bullet drop or bullet travel time, consider using fastcast! Otherwise, raycasting should do the trick for arcade-y style weapons. There are many videos and documentation of fastcast online :slight_smile:

Here’s the link for fastcast!

How can I use Fastcast exactly?

The documentation for fastcast goes over everything, but it can be a little uncomfortable to use at first just like any module. Here’s the link to the documentation.

Oh, so Fastcast is a module, right? So does that mean I can globally use Fastcast and don’t need to constantly clone the Fastcast module to each gun using physical projectiles?

GetPartBoundsInBox() is a good way of replacing .Touched()

local RunService = game:GetService("RunService")
local Hitbox = workspace:FindFirstChild("Hitbox")

-- Without OverlapParams.

RunService.Heartbeat:Connect(function(deltaTime)
	if Hitbox then
		
		local PartBoundsInBox = workspace:GetPartBoundsInBox(Hitbox.CFrame, Hitbox.Size)
		
		for i, v in PartBoundsInBox do
			if v.Parent:IsA("Model") and v.Parent:FindFirstChild("Humanoid") then
				
				local Model = v.Parent
				local Humanoid = Model:FindFirstChild("Humanoid")
				
				if Model and Humanoid and Humanoid.Health ~= 0 then
					Humanoid:TakeDamage(3)
				end
			end
		end
	end
end)

-- With OverlapParams.

local Params = OverlapParams.new()
local Filter = {workspace.ExamplePart} -- "ExamplePart" will be ignored even if it's in the hitbox.
Params.FilterType = Enum.RaycastFilterType.Exclude

RunService.Heartbeat:Connect(function(deltaTime)
	if Hitbox then

		local PartBoundsInBox = workspace:GetPartBoundsInBox(Hitbox.CFrame, Hitbox.Size)
		Params.FilterDescendantsInstances = Filter -- Putting it inside of the connection will constantly refresh the filter, just in case if :AddToFilter() is used at any point.
		
		for i, v in PartBoundsInBox do
			if v.Parent:IsA("Model") and v.Parent:FindFirstChild("Humanoid") then

				local Model = v.Parent
				local Humanoid = Model:FindFirstChild("Humanoid")

				if Model and Humanoid and Humanoid.Health ~= 0 then
					Humanoid:TakeDamage(3)
				end
			end
		end
	end
end)

What is “Hitbox” suppose to be?

A BasePart. You can change hitbox to whatever you want. Just make sure it’s a BasePart. BasePart’s are Parts, MeshParts, Unions, etc.

So do I just change the hitbox to the bullet?

Yeah, you can. If you need any further assistance, feel free to let me know.

Well, idk if I correctly placed the lines of code correctly since it didn’t work. Should I increase the size of the bullet?

local Tool = script.Parent
local FireEvent = Tool:WaitForChild("LaazerTime")
--//Functionality
FireEvent.OnServerEvent:Connect(function(Plr,MousePOS)
	local Bullet = Instance.new("Part",workspace.Debris)
	game:GetService("Debris"):AddItem(Bullet,5)
	Bullet.Size = Vector3.new(0.5, 0.5, 0.5)
	Bullet.CanCollide = false
	Bullet.CastShadow = false
	Bullet:SetNetworkOwner(Plr)
	--Pos
	Bullet.Position = Tool.FirePart.Position
	Bullet.CFrame = CFrame.new(Tool.FirePart.Position,MousePOS)
	
	--Moving Bullet
	Bullet.Velocity = CFrame.new(Tool.FirePart.Position,MousePOS).LookVector * 1000
	local AntiGrav = Instance.new("BodyForce")
	AntiGrav.Force = Vector3.new(0, workspace.Gravity * Bullet:GetMass(), 0)
	AntiGrav.Parent = Bullet
	
	--Damaging
	game:GetService("RunService").Heartbeat:Connect(function(deltaTime)
		local PartBoundsInBox = workspace:GetPartBoundsInBox(Bullet.CFrame,Bullet.Size)
		
		for i,v in pairs(PartBoundsInBox) do
			if v:IsA("Model") and v.Parent:FindFirstChild("Humanoid") then
				
				local Model = v.Parent
				local Humanoid = Model:WaitForChild("Humanoid")
				
				if Model and Humanoid and Humanoid.Health ~= 0 then
					Humanoid:TakeDamage(6)
					Bullet:Destroy()
				end
			end
		end
	end)
end)

Change this to if v.Parent:IsA("Model")
Other than that, seems good!

I guess it does work, the only issue is that I want the bullets to disappear after hitting a humanoid, I tried doing Bullet:Destroy(), although it appears to didn’t work.

EDIT: Nvm, using Debris seems to work. Although, I think the bullets need to be reworked a bit, but it’s okay. Thanks!

2 Likes

Oh and btw, I founded out that the quicker the bullet is, the less times the function runs, although I guess I can find a way around it.

1 Like

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