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)```
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