I need Help With My Lightning Beam Magic

I just wanted to create lightning beam which is accurate and goes to little random attachments to make it look like proper lightning but my lightning went crazy, it doesn’t really go to where i point my mause and its path goes so random.
The Problem:


Here is the Server Script:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RemoteEvent = ReplicatedStorage:WaitForChild("HowToLightning")

local OnCoolDown = {}

local PartsFolder = Instance.new("Folder")
PartsFolder.Parent = workspace
RemoteEvent.OnServerEvent:Connect(function(Player,MouseHit,CameraCF)
	if OnCoolDown[Player.UserId] then return end
	OnCoolDown[Player.UserId] = true
	local RightArm = Player.Character:WaitForChild("Right Arm")
	local RayOrigin = RightArm.Position
	local RayDirection = MouseHit.LookVector * 100 
	local TheBigRay = RaycastParams.new()
	TheBigRay.FilterDescendantsInstances = {Player.Character,PartsFolder}
	TheBigRay.FilterType = Enum.RaycastFilterType.Blacklist
	local RayCastResult = workspace:Raycast(RayOrigin,RayDirection,TheBigRay)
	local lenght
	local HitPart
	if RayCastResult then
		HitPart = RayCastResult.Instance
		print(HitPart.Name)
		if HitPart and HitPart.Parent:FindFirstChild("Humanoid") then
			HitPart.Parent.Humanoid:TakeDamage(30)
			
		end
		lenght = (RightArm.Position - HitPart.Position).Magnitude
	else
		lenght = (RightArm.Position - RayDirection ).Magnitude
	end
	print(lenght)
	
	local NumPoints = math.random(3,25)
	local Increment = lenght/NumPoints
	
	
	local BeamPart = Instance.new("Part")
	BeamPart.Anchored, BeamPart.CanCollide,BeamPart.Transparency,BeamPart.Parent = true,false,1, PartsFolder
	
	local beams = {}
	for i = 1, NumPoints do
		local Attachment = Instance.new("Attachment")
		Attachment.Parent = BeamPart
		Attachment.Name = "LightAttachment".. i
		Attachment.Orientation = Vector3.new(0,0,0)
		
		local NewInc = Increment / 2
		local x,y,z = math.random(-NewInc*100, NewInc *100)/100,math.random(-NewInc*100, NewInc *100)/100,math.random(-NewInc*100, NewInc *100)/100
		local Offset = Vector3.new(x,y,z)
		
		Attachment.WorldPosition = (RightArm.Position) +((i -1)* Increment * RayDirection.Unit) * (Offset)
		
		if i == 1 then
			Attachment.WorldPosition = RightArm.Position
		elseif i == NumPoints and RayCastResult then
			Attachment.WorldPosition = HitPart.Position
		elseif i == NumPoints then
			Attachment.WorldPosition = RayDirection
		end
		
		if i ~= 1 then
			
			local lightning = Instance.new("Beam")
			lightning.FaceCamera = true
			lightning.Width0, lightning.Width1 = 0.3,0.3
			lightning.Color = ColorSequence.new(Color3.fromRGB(0,174,255))
			lightning.Transparency = NumberSequence.new(0)
			lightning.LightEmission = 1
			
			lightning.Attachment0 = BeamPart["LightAttachment".. (i-1)]
			lightning.Attachment1 =Attachment
			lightning.Parent = BeamPart
			
			table.insert(beams,lightning)
			
			game:GetService("Debris"):AddItem(lightning,0.3)
		end
		game:GetService("Debris"):AddItem(Attachment,0.3)
	end
	wait(0.1)
	beams = {}
	game:GetService("Debris"):AddItem(BeamPart,0.3)
	OnCoolDown[Player.UserId] = false
end)

Here is the local script if you need to test it:

local UserInputService = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RemoteEvent = ReplicatedStorage:WaitForChild("HowToLightning")

local Player = game:GetService("Players").LocalPlayer
local Mouse = Player:GetMouse()
local Camera = workspace.CurrentCamera

local Holding = false

UserInputService.InputBegan:Connect(function(input,busy)
	if busy then return end
	
	if input.KeyCode == Enum.KeyCode.F then
		Holding = true
	end
	
end)
UserInputService.InputEnded:Connect(function(input,busy)
	if busy then return end

	if input.KeyCode == Enum.KeyCode.F then
		Holding = false
	end

end)
game:GetService("RunService").Heartbeat:Connect(function()
	
	if Holding then
		RemoteEvent:FireServer(Mouse.Hit,Camera.CFrame)
		
	end
	wait(0.3)
end)

I’m not gonna go through this entire script, but you should never loop fireserver. Instead you should send a request when the player starts holding and stops holding. You can simply use a name for the argument and check it > which would look like this.

RemoteEvent:FireServer(Mouse.Hit,Camera.CFrame, 'StartLightning')
RemoteEvent:FireServer(Mouse.Hit,Camera.CFrame, 'EndLightning')

RemoteEvent.OnServerEvent:Connect(function(Player,MouseHit,CameraCF, request)

if request == 'StartLightning' then
--do code
elseif request == 'EndLightning' then
--do code

If you need a place to put the effects I will occasionally put a folder inside the players where I can parent the effects so I can accurately destroy them. Sorry tho I would help with the rest of the script, but it’s just too long and I’m pretty lazy.

1 Like

I see but it has nothing to do with the main problem can you help with it?