Beam Not Dealing Damage Despite Detecting Hits

I’m working on a beam mechanic using Beam and RemoteEvent in Roblox, but I’m facing an issue where the beam detects a hit on a player, but doesn’t apply damage.

The beam is created and moved based on player input, and I use a raycast to check if the beam hits a player. The damage should be applied when a player is hit, but it doesn’t work.

Local Script

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")

local localPlayer = Players.LocalPlayer
local mouse = localPlayer:GetMouse()

local beamEvent = ReplicatedStorage:WaitForChild("BeamEvent")

RunService.RenderStepped:Connect(function()
	local character = localPlayer.Character
	if not character then
		return
	end

	local head = character:FindFirstChild("Head")
	if not head then
		return
	end

	local origin = head.Position
	local finish = mouse.Hit.p

	beamEvent:FireServer(origin, finish)
end)

ServerScript

local Players = game:GetService("Players")
local damageAmount = 10

local beamEvent = Instance.new("RemoteEvent")
beamEvent.Name = "BeamEvent"
beamEvent.Parent = ReplicatedStorage

local playerBeams = {}

local function createBeam(player, origin, finish)
	local beam = Instance.new("Beam")
	beam.Segments = 1
	beam.Width0 = 0.2
	beam.Width1 = 0.2
	beam.Color = ColorSequence.new(Color3.new(1, 0, 0))
	beam.FaceCamera = true

	local attachment0 = Instance.new("Attachment")
	local attachment1 = Instance.new("Attachment")
	beam.Attachment0 = attachment0
	beam.Attachment1 = attachment1

	beam.Parent = workspace.Terrain
	attachment0.Parent = workspace.Terrain
	attachment1.Parent = workspace.Terrain

	attachment0.Position = origin
	attachment1.Position = finish

	playerBeams[player] = beam

	local rayOrigin = origin
	local rayDirection = (finish - origin).unit * (finish - origin).magnitude
	local raycastParams = RaycastParams.new()
	raycastParams.FilterDescendantsInstances = {beam}
	raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
	local raycastResult = workspace:Raycast(rayOrigin, rayDirection, raycastParams)

	if raycastResult then
		local hitPart = raycastResult.Instance
		if hitPart and hitPart.Parent then
			local hitPlayer = Players:GetPlayerFromCharacter(hitPart.Parent)
			if hitPlayer and hitPlayer ~= player then
				local character = hitPlayer.Character
				if character then
					local humanoid = character:FindFirstChild("Humanoid")
					if humanoid then
						humanoid:TakeDamage(damageAmount)
					end
				end
			end
		end
	end
end

beamEvent.OnServerEvent:Connect(function(player, origin, finish)
	if playerBeams[player] then
		local beam = playerBeams[player]
		beam.Attachment0.Position = origin
		beam.Attachment1.Position = finish
	else
		createBeam(player, origin, finish)
	end

	for _, otherPlayer in pairs(Players:GetPlayers()) do
		if otherPlayer ~= player then
			beamEvent:FireClient(otherPlayer, origin, finish)
		end
	end
end)```

If you’re testing on a Player or a Dummy, and they have an Accessory On, then that’s the Problem since the Raycast hits the Accessory’s Handle, and the Parent of the Handle is obviously an Accessory Instance… not the Character with the Humanoid… But if the hit Character didn’t have any Accessories, you can try making it print out the name of the Hit Part and see if that helps

Thank you for your response and suggestion. I went ahead and implemented the approach you mentioned, using raycasting with the accessory handling logic, and made sure to ignore the beam’s attachments and the player’s character if needed. However, despite these changes, the issue still persists.

The beam is still not dealing damage properly, and the hit detection seems to be inconsistent. I’ve checked the raycast results and ensured the accessory parts are handled correctly, but it doesn’t seem to be fully resolving the issue.

If you have any further suggestions or if there’s something I might have overlooked, I’d really appreciate any additional help!

Thanks again, Here are the script

local Players = game:GetService("Players")
local Workspace = game:GetService("Workspace")
local damageAmount = 10

local beamEvent = Instance.new("RemoteEvent")
beamEvent.Name = "BeamEvent"
beamEvent.Parent = ReplicatedStorage

local playerBeams = {}

local function getHumanoidFromHit(hitPart)
    if not hitPart then return nil end
    local accessory = hitPart:FindFirstAncestorWhichIsA("Accessory")
    local model = nil
    if accessory then
        model = accessory:FindFirstAncestorWhichIsA("Model")
    else
        model = hitPart:FindFirstAncestorWhichIsA("Model")
    end
    if model then
        return model:FindFirstChild("Humanoid")
    end
    return nil
end

local function updateBeam(player, origin, finish)
    local beam
    if playerBeams[player] then
        beam = playerBeams[player]
        beam.Attachment0.Position = origin
        beam.Attachment1.Position = finish
    else
        beam = Instance.new("Beam")
        beam.Segments = 1
        beam.Width0 = 0.2
        beam.Width1 = 0.2
        beam.Color = ColorSequence.new(Color3.new(1, 0, 0))
        beam.FaceCamera = true
        
        local attachment0 = Instance.new("Attachment")
        local attachment1 = Instance.new("Attachment")
        beam.Attachment0 = attachment0
        beam.Attachment1 = attachment1
        
        beam.Parent = Workspace.Terrain
        attachment0.Parent = Workspace.Terrain
        attachment1.Parent = Workspace.Terrain
        
        attachment0.Position = origin
        attachment1.Position = finish
        
        playerBeams[player] = beam
    end

    for _, otherPlayer in pairs(Players:GetPlayers()) do
        if otherPlayer ~= player then
            beamEvent:FireClient(otherPlayer, origin, finish)
        end
    end
end

local function raycastAndDamage(player, origin, finish)
    local direction = (finish - origin)
    local distance = direction.Magnitude
    if distance == 0 then return end
    local rayDirection = direction.Unit * distance

    local raycastParams = RaycastParams.new()
    raycastParams.FilterType = Enum.RaycastFilterType.Blacklist

    local ignoreList = {}
    if playerBeams[player] then
        local beam = playerBeams[player]
        table.insert(ignoreList, beam)
        if beam.Attachment0 then table.insert(ignoreList, beam.Attachment0) end
        if beam.Attachment1 then table.insert(ignoreList, beam.Attachment1) end
    end
    local character = player.Character
    if character then
        table.insert(ignoreList, character)
    end
    raycastParams.FilterDescendantsInstances = ignoreList

    local raycastResult = Workspace:Raycast(origin, rayDirection, raycastParams)
    if raycastResult then
        local hitPart = raycastResult.Instance

        local humanoid = getHumanoidFromHit(hitPart)
        if humanoid then
            local hitPlayer = Players:GetPlayerFromCharacter(humanoid.Parent)
            if hitPlayer and hitPlayer ~= player then
                humanoid:TakeDamage(damageAmount)
            end
        end
    end
end

beamEvent.OnServerEvent:Connect(function(player, origin, finish)
    if typeof(origin) ~= "Vector3" or typeof(finish) ~= "Vector3" then
        return
    end
    updateBeam(player, origin, finish)
    raycastAndDamage(player, origin, finish)
end)

Players.PlayerRemoving:Connect(function(player)
    if playerBeams[player] then
        playerBeams[player]:Destroy()
        playerBeams[player] = nil
    end
end)```

Hi! Here’s reworked piece of the script:

	local rayOrigin = origin
	local rayDirection:Vector3 = (finish - origin).unit * (finish - origin).magnitude
	local raycastParams = RaycastParams.new()
	raycastParams.FilterDescendantsInstances = {beam, unpack(player.Character:GetDescendants())}
	raycastParams.FilterType = Enum.RaycastFilterType.Exclude
	local raycastResult = workspace:Raycast(rayOrigin, rayDirection, raycastParams)
	
	if raycastResult then
		local Parent = raycastResult.Instance.Parent
		if Parent:IsA("Accessory") then
			local Humanoid = Parent.Parent:FindFirstChild("Humanoid")
			if Humanoid then
				Humanoid:TakeDamage(damageAmount)
			end
		elseif Parent:IsA("Model") then
			local Humanoid = Parent:FindFirstChild("Humanoid")
			if Humanoid then
				Humanoid:TakeDamage(damageAmount)
			end
		end
	end

In my case it works every test

1 Like

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