Need help tweaking a raycast gun

I am currently developing a single-player FPS game with an emphasis on speedy movement.

The primary weapon the player uses is a pistol, but the raycasts used by this script are made in the server, rather than the client.
(original script here: How to make a raycasting gun)

This causes the raycast to be practically impossible to aim whilst moving.

I have tried to put the raycast’s calculations into the local script, but so far none of my attempts have worked.
(Edit: Found a way, and now I have a brand new problem.
(Need help tweaking a raycast gun 2: RemoteFunction Boogaloo))

Script:

local tool = script.Parent
local shoot_part = tool:WaitForChild("Shoot")
local remote = tool:WaitForChild("OnShoot")
local damage = tool:GetAttribute("Damage")
local cooldown = tool:GetAttribute("cooldown")
local gamer

local Workspace = game:GetService("Workspace")
local ServerStorage = game:GetService("ServerStorage")

remote.OnServerEvent:Connect(function(player, position)
	tool.Enabled = false
	tool.Handle.Firesound:Play()
	local origin = shoot_part.Position
	local direction = (position - origin).Unit*300
	local result = Workspace:Raycast(origin, direction)

	local intersection = result and result.Position or origin + direction
	local distance = (origin - intersection).Magnitude

	local bullet_clone = ServerStorage.Bullet:Clone()
	bullet_clone.Size = Vector3.new(0.1, 0.1, distance)
	bullet_clone.CFrame = CFrame.new(origin, intersection)*CFrame.new(0, 0, -distance/2)
	bullet_clone.Parent = Workspace

	if result then
	local part = result.Instance
	local humanoid = part.Parent:FindFirstChild("Humanoid") or part.Parent.Parent:FindFirstChild("Humanoid")

	if humanoid then
		gamer = tool.Parent.Name
		if humanoid.Parent.Name ~= (gamer) then
			humanoid:TakeDamage(damage)
		end
	end
end
tool.Shoot.flame.Enabled = true
wait(0.05)
tool.Shoot.flame.Enabled = false
	bullet_clone:Destroy()
	wait(cooldown)
	tool.Enabled = true
end)

Localscript:

local tool = script.Parent
local remote = tool:WaitForChild("OnShoot")
local ammo = tool:GetAttribute("Ammo")
local Players = game:GetService("Players")
local client = Players.LocalPlayer
local cursor = client:GetMouse()

tool.Pistol.SurfaceGui.ammo.Text = ammo
tool.Pistol.SurfaceGui.ammo.Visible = true
tool.Activated:Connect(function()
	if tool.Enabled == true and ammo > 0 then
		remote:FireServer(cursor.Hit.Position)
		ammo = ammo - 1
		tool.Pistol.SurfaceGui.ammo.Text = ammo
	end
end)
3 Likes

Is the problem that the laser isn’t at the player, or the shots aren’t accurate?

The laser starts at where the gun was rather than where it is.

You could do a for loop to keep the laser’s position staying near the gun for a period of time.

for i = 0, 10, 1 do
-- laser position setting code here
wait(something)
end

Or you could just do a slight delay before the laser is created.

It didn’t work, since the calculations are done before the beam is fired, adding this loop only delayed the creation of the beam, making it even harder to actually hit something.

The problem isn’t that the raycast is inaccurate or delayed via the script itself, it’s that I need to move the calculations into the LocalScript so the raycast’s trajectory lines up with that of the aim of the player’s client, whilst still allowing it to deal damage via the other script.
However, my attempts to do so have been unsuccessful.

Edit: After some more tinkering, I managed to find a new problem.
(Need help tweaking a raycast gun 2: RemoteFunction Boogaloo)