So, I have a code that fires a remote to detect if a something is on the players screen. The problem is that it errors saying “Player appears to be spamming remote events”.
local function checkSight(part)
local success, bool = pcall(function()
return Remotes.CheckOnScreen:InvokeClient(player, part)
end)
return success, bool
end
RunService.Heartbeat:Connect(function()
checkSight(part)
end)
Could you show me a screenshot, or copy-and paste what the error actually says? I’ve never seen this error before.
The reason why you have this error, is because in your script you are invoking the client right before every physics simulation, which occurs several times per second. I’m also not sure what you are trying to do, but it’s not recommended to use RemoteFunction:InvokeClient(player, ...) due to security reasons, and because the client is less guaranteed than the server is to return data from the invoking of the function.
This is a warning, and not an error, but what exactly are you trying to accomplish? Maybe I can help you do it differently so you don’t get this warning.
Edit: I am asking what are you trying to do that needs you to use InvokeClient() on the server? @GameMaster4268
Could you connect the Heartbeat on the client and only fire an event when the client finds something?
--// LocalScript
local function CheckOnScreen()
local Vector, OnScreen = currentCamera:WorldToViewportPoint(part.Position)
return OnScreen
end
RS.Heartbeat:Connect(function()
if CheckOnScreen() then
event:FireServer() --// Regular RemoteEvent
end
end)
--// Server Script
event.OnServerEvent:Connect(function(plr)
print(plr.Name.." sees the thing!"
end)
Edit:
To reduce the number of times the event calls, add a debounce that only fires the event once on it entering the screen. If you want some sample code I can provide it.
local RunService = game:GetService("RunService")
local replicatedStorage = game:GetService("ReplicatedStorage")
local Remotes = replicatedStorage:WaitForChild("Remotes")
local Modules = replicatedStorage:WaitForChild("Modules")
local ToolData = require(script.Parent:WaitForChild("ToolData"))
local character = script.Parent.Parent
local humanoid = character:WaitForChild("Hero")
local animator = humanoid:FindFirstChildOfClass("Animator")
local RemotesFolder = character:WaitForChild("RemotesFolder")
local npcs = workspace:WaitForChild("Npcs")
local animationTable = {
[0] = script:WaitForChild("Attack1"),
}
local tool = character:WaitForChild("Bow")
local hitbox = tool:WaitForChild("Hitbox")
local firePoint = hitbox:WaitForChild("FirePoint")
local range = ToolData.MaxRange
local animationCombo = 0
local currentTime = tick()
local canShoot = true
local damageCooldown = 1.5
local currentTarget = nil
local canAttack = character:WaitForChild("CanAttack")
local track = nil
local function playAnimation()
if animationTable[animationCombo] then
local anim = animationTable[animationCombo]
track = animator:LoadAnimation(anim)
track:Play()
track.Stopped:Wait()
canShoot = true
end
animationCombo += 1
if animationCombo > #animationTable then
animationCombo = 0
end
end
local function castRay(target)
if target.PrimaryPart ~= nil then
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {npcs}
raycastParams.FilterType = Enum.RaycastFilterType.Whitelist
raycastParams.IgnoreWater = true
local rayOrigin = character.PrimaryPart.Position
local rayDestination = target.PrimaryPart.Position
local rayDirection = (rayDestination - rayOrigin)
local raycastResult = workspace:Raycast(rayOrigin, rayDirection, raycastParams)
if raycastResult then
local distance = math.floor(raycastResult.Distance)
if distance <= range then
currentTarget = target
return true, raycastResult.Position, distance
end
end
end
currentTarget = nil
return false, nil, nil
end
local function PredictNextPosition(targetPosition, targetVelocity)
if targetPosition ~= nil and targetVelocity ~= nil then
local t = ToolData.ProjectileTime
local endPosition = targetPosition + targetVelocity * t
return endPosition
end
end
local function getPlayer()
local player = Remotes.GetPlayerBindable:Invoke()
if player then
return player
end
end
local player = getPlayer()
local function reset()
if track ~= nil then
track:Stop()
end
currentTarget = nil
canShoot = true
end
local function findTarget()
local checkRay, position, distance = nil, nil, nil
for i,v in ipairs(npcs:GetChildren()) do
checkRay, position, distance = castRay(currentTarget or v)
if currentTarget ~= nil then
local savedTarget = currentTarget
local targetRoot = currentTarget.PrimaryPart
local human = currentTarget:FindFirstChildWhichIsA("Humanoid")
if human and human.Health > 0 then
if human and human.Health <= 0 then
currentTarget = nil
end
if distance > range then
currentTarget = nil
end
if player and human and human.Health > 0 and currentTarget ~= nil and targetRoot ~= nil and checkRay == true then
local success, bool = pcall(function()
return Remotes.CheckOnScreen:InvokeClient(player, targetRoot, {npcs})
end)
if success and bool then
local characterRoot = character.PrimaryPart
characterRoot.CFrame = CFrame.lookAt(characterRoot.Position, Vector3.new(position.X, characterRoot.Position.Y, position.Z))
if tick() - currentTime >= damageCooldown then
currentTime = tick()
playAnimation()
checkRay, position, distance = castRay(savedTarget)
local nextPosition = PredictNextPosition(position, targetRoot.AssemblyLinearVelocity)
if checkRay ~= nil and checkRay == true and nextPosition ~= nil and canShoot == true and human and human.Health > 0 then
RemotesFolder.FireProjectile:Fire(firePoint, nextPosition)
canShoot = false
else
reset()
end
end
end
end
else
reset()
end
end
end
end
RunService.Heartbeat:Connect(function()
if character.PrimaryPart ~= nil and canAttack.Value == true then
findTarget()
end
end)
Camera Handler:
local player = game.Players.LocalPlayer
local camera = workspace.Camera
local CameraPart = workspace:WaitForChild("CameraPart")
local replicatedStorage = game:GetService("ReplicatedStorage")
local Remotes = replicatedStorage:WaitForChild("Remotes")
local currentCamera = workspace.CurrentCamera
local castParams = RaycastParams.new()
castParams.FilterType = Enum.RaycastFilterType.Whitelist
castParams.IgnoreWater = true
local function checkOnScreen(part, whitelist)
castParams.FilterDescendantsInstances = whitelist
local Vector, OnScreen = currentCamera:WorldToViewportPoint(part.Position, castParams)
return OnScreen
end
Remotes.CheckOnScreen.OnClientInvoke = function(part, whitelist)
return checkOnScreen(part, whitelist)
end
you really really do not want to invoke a remote every frame this causes tons of network lag (huge ping)
change it to only invoke a few times per second
example
local lastSendTick = tick()
local updatesPerSecond = 10
RunService.Heartbeat:Connect(function()
if tick() - lastSendTick > 1 / updatesPerSecond then
-- invoke to client
lastSendTick = tick()
end
end)
This error occours when a player is spamming remote events so much that it may overload the server.
Consider changing the rate that you send remote events, such as a while true loop like blorbee said, or make it so the client does much of the work like rick said
I dont know what exactly what your trying to accolampish but it appears your trying to make it so whilst looking around any enemy you spot has fellow npc’s controlled by the player attack your target
Perhaps consider checking the parts on the client, and when the camera detects a target has entered the camera, fire a remote event to your npc’s the player in controlling which makes them follow the target.
Once your camera has looked away from the target, then fire a remote event to the server which stops the movemnt of your npc’s the player is controlling
This would mean it would only fire remote events around twice instead of a billion times