Delay between click and bullet visuals?

I’m making a ROBLOX game and I’ve noticed that there is a small but annoying delay between when the player clicks, and when the bullet visuals appear. I’m using a system that does all the raycasting on the server, then sends a remote event to all clients to visualize the bullet. Is there anything I can do to solve this issue?

Server Script:

local function fireBullet(mousePosition: Vector3)
	local origin = muzzleAttachment.WorldPosition
	local direction = (mousePosition - origin).Unit * Constants.BULLET_LENGTH + 
		Vector3.new(random:NextInteger(-Constants.RAY_SPREAD, Constants.RAY_SPREAD),
			random:NextInteger(-Constants.RAY_SPREAD, Constants.RAY_SPREAD),
			random:NextInteger(-Constants.RAY_SPREAD, Constants.RAY_SPREAD))
	local raycastResult = Workspace:Raycast(origin, direction, raycastParams)
	local intersection = raycastResult and raycastResult.Position or origin + direction
	local distance = (origin - intersection).Magnitude
	replicateBulletRemote:FireAllClients(gun, intersection, distance) -- Visualize the bullet for all client
	if raycastResult then
		local part = raycastResult.Instance
		local humanoid = part.Parent:FindFirstChild("Humanoid") or part.Parent.Parent:FindFirstChild("Humanoid")
		if not humanoid then
			return
		end
		if humanoid.Parent:HasTag("Enemy") then
			humanoid:TakeDamage(Constants.BULLET_DAMAGE)
		end
	end
end

Client Side Bullet Visualization Script

local function onReplicateBulletEvent(gun: Tool, intersection: Vector3, bulletLength: number, raycastPosition: Vector3?, raycastNormal: number?)
	if gun and gun:IsDescendantOf(game) then
		local handle = gun.Handle
		local muzzleAttachment = handle:FindFirstChild("Muzzle", true)

		if muzzleAttachment then
			muzzleAttachment.Smoke:Emit(5)
			muzzleAttachment.Flash:Emit(5)
		end

		local newBulletVisual = bulletVisual:Clone()
		newBulletVisual.Size = Vector3.new(0.1, 0.1, bulletLength)
		newBulletVisual.CFrame = CFrame.lookAt(muzzleAttachment.WorldPosition, intersection) *  CFrame.new(0, 0, -bulletLength/2)
		newBulletVisual.Parent = bulletVisualsContainer

		local bulletFadeTween = TweenService:Create(
			newBulletVisual,
			TweenInfo.new(.5, Enum.EasingStyle.Cubic, Enum.EasingDirection.Out),
			{Transparency = 1})

		local bulletSizeTween = TweenService:Create(
			newBulletVisual,
			TweenInfo.new(.5, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out),
			{Size = Vector3.new(0.025, 0.025, bulletLength)})
		local bulletColorTween = TweenService:Create(
			newBulletVisual,
			TweenInfo.new(.5, Enum.EasingStyle.Linear, Enum.EasingDirection.Out),
			{Color = Color3.fromRGB(100, 100, 100)})

		bulletFadeTween:Play()
		bulletSizeTween:Play()
		bulletColorTween:Play()

		task.delay(.5, function()
			newBulletVisual:Destroy()
		end)
	end
end

replicateBulletRemote.OnClientEvent:Connect(onReplicateBulletEvent)

This issue isn’t noticable on a low ping, but I feel like I’ve seen games that counteract this issue even when you are on a high ping? (At least I assume)

1 Like

Solved. You have to visualize the bullet on your client before sending any data to the server.

1 Like

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