For more mega awesome detections join my AC discord
Info:
Instead of using complex trignometric functions or math.
Just detect when the player's camera is moving without the mouse moving. Simple, right?
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")
local LocalPlayer = Players.LocalPlayer
local lastCameraLook = nil
local isRotatingCamera = false
local gameStartTime = tick()
local lastDetectionDecreaseTime = tick()
local initialDelay = 1
local lastMovementTime = 0 -- Last time mouse moved
local timeThreshold = 1 -- Time in seconds to wait before considering camera as "not moving"
local detections = 0
local Detected = false
local detectionDecreaseInterval = 1
local camera = workspace.CurrentCamera
local lastMouseDelta = Vector2.zero
local isRotationInput = function(input)
return input.UserInputType == Enum.UserInputType.MouseButton1 or
input.UserInputType == Enum.UserInputType.MouseButton2 or
input.UserInputType == Enum.UserInputType.MouseButton3 or
input.KeyCode == Enum.KeyCode.Left or
input.KeyCode == Enum.KeyCode.Right or
input.KeyCode == Enum.KeyCode.Up or
input.KeyCode == Enum.KeyCode.Down or
input.KeyCode == Enum.KeyCode.Q or
input.KeyCode == Enum.KeyCode.E
end
local isOnPC = function()
return UserInputService.KeyboardEnabled and UserInputService.MouseEnabled and not UserInputService.TouchEnabled
end
local roundVector3 = function(v3) -- due to floating point precision issues
return Vector3.new(
math.round(v3.X * 10^4) / 10^4,
math.round(v3.Y * 10^4) / 10^4,
math.round(v3.Z * 10^4) / 10^4
)
end
local connection:RBXScriptConnection;
local connection2:RBXScriptConnection;
local connection3:RBXScriptConnection;
local Character = LocalPlayer.Character or LocalPlayer.CharacterAdded:Wait()
local Humanoid = Character:WaitForChild("Humanoid")
local checkForAimbot = function()
if detections > 75 and not Detected then
Detected = true
connection:Disconnect()
connection2:Disconnect()
connection3:Disconnect()
LocalPlayer:Kick('Banned')
return
end
if not Character then
Character = LocalPlayer.Character or LocalPlayer.CharacterAdded:Wait()
return
end
if tick() - gameStartTime < initialDelay then return end -- add a delay for loading in
local currentCameraLook = roundVector3(camera.CFrame.LookVector)
local MouseDelta = UserInputService:GetMouseDelta()
-- Decrease detections over time (every detectionDecreaseInterval seconds)
if tick() - lastDetectionDecreaseTime >= detectionDecreaseInterval then
if detections > 0 then -- Only decrease if there are detections to decrement
detections -= 1
print(`Decreased detection count to: {detections} `)
lastDetectionDecreaseTime = tick()
end
end
if not lastCameraLook then
lastCameraLook = currentCameraLook
lastMovementTime = tick()
return
end
if
currentCameraLook ~= lastCameraLook
and MouseDelta == Vector2.zero
and not isRotatingCamera
and not Character.Humanoid.Sit
and lastMouseDelta == Vector2.zero
then
detections += 1
print(`Detection: {detections}`)
lastMovementTime = tick()
elseif tick() - lastMovementTime > timeThreshold and not isRotatingCamera then
return -- Camera hasn't moved significantly for a while and no rotation input.
end
lastMouseDelta = MouseDelta -- Update mouse delta for next frame check to prevent moving the mouse fast and stopping false flag.
lastCameraLook = currentCameraLook -- Update camera look vector for next frame check.
end
if not isOnPC() then
return
end
-- Input connections for detecting rotation input
connection = RunService.RenderStepped:Connect(checkForAimbot)
connection2 = UserInputService.InputBegan:Connect(function(input, gameProcessed)
if not gameProcessed and isRotationInput(input) then
isRotatingCamera = true
end
end)
connection3 = UserInputService.InputEnded:Connect(function(input, gameProcessed)
if not gameProcessed and isRotationInput(input) then
isRotatingCamera = false
end
end)
Unproductive things not to say under this topic:
Just delete the script
Just hookfunction (INSERT FUNCTION NAME HERE)
Never trust the client
It only takes one person to bypass blah blah blah
I made this without ANY protection against hookfunctions, deleting the script, etc. These are your responsibility to protect the code since this is a RESOURCE. Instead of commenting this, try to identify weak points or false flags.
and yes obviously if the cheater artifically moves the mouse this wont work. instead of thinking just this think about how many hundreds of aimbot scripts dont do this
False Flags:
I have found 0 false flags that caused you to be kicked unless you move the camera externally.
local isRotationInput = function(input)
return input.UserInputType == Enum.UserInputType.MouseButton1 or
input.UserInputType == Enum.UserInputType.MouseButton2 or
input.UserInputType == Enum.UserInputType.MouseButton3 or
input.KeyCode == Enum.KeyCode.Left or
input.KeyCode == Enum.KeyCode.Right or
input.KeyCode == Enum.KeyCode.Up or
input.KeyCode == Enum.KeyCode.Down or
input.KeyCode == Enum.KeyCode.Q or
input.KeyCode == Enum.KeyCode.E
end
It checks for the arrow keys in the isRotationInput function.
Most aimbots/aimlocks are going to use mousemoverel which is a function built into most of the execution software out there. So they move the mouse, which moves the camera.
if you’re acknowledging that your script can be easily bypassed then why post it, I’m not trying to be mean, but this seems like more of a hassle for the developer than an anti-cheat. A decent amount of scripts already use VirtualInputManager and mousemoverel which @CompilerError said.
Not only that, but this makes any custom camera movement unusable, for example, camera sway or gun recoil.
side note, i just tested the script and even without any type of aimbot script being used its still “detecting” and kicks me
Hi, as stated before, this is a resource for competent anticheat developers. I mostly misspoke since it cannot be easily bypassed as you have to use an entire different category of aimbot to bypass it. (Mouse aimbot)
It doesn’t false flag unless you have something moving the camera without it being approved by the anti aimbot. If this still isn’t working try using it in a baseplate.
Wow, did not think of that.
This would probably fix it.
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")
local LocalPlayer = Players.LocalPlayer
local lastCameraLook = nil
local isRotatingCamera = false
local gameStartTime = tick()
local lastDetectionDecreaseTime = tick()
local initialDelay = 1
local lastMovementTime = 0 -- Last time mouse moved
local timeThreshold = 1 -- Time in seconds to wait before considering camera as "not moving"
local detections = 0
local Detected = false
local detectionDecreaseInterval = 1
local camera = workspace.CurrentCamera
local lastMouseDelta = Vector2.zero
local isRotationInput = function(input)
return input.UserInputType == Enum.UserInputType.MouseButton1 or
input.UserInputType == Enum.UserInputType.MouseButton2 or
input.UserInputType == Enum.UserInputType.MouseButton3 or
input.KeyCode == Enum.KeyCode.Left or
input.KeyCode == Enum.KeyCode.Right or
input.KeyCode == Enum.KeyCode.Up or
input.KeyCode == Enum.KeyCode.Down or
input.KeyCode == Enum.KeyCode.Q or
input.KeyCode == Enum.KeyCode.E
end
local isOnPC = function()
return UserInputService.KeyboardEnabled and UserInputService.MouseEnabled and not UserInputService.TouchEnabled
end
local roundVector3 = function(v3) -- due to floating point precision issues
return Vector3.new(
math.round(v3.X * 10^4) / 10^4,
math.round(v3.Y * 10^4) / 10^4,
math.round(v3.Z * 10^4) / 10^4
)
end
local connection:RBXScriptConnection;
local connection2:RBXScriptConnection;
local connection3:RBXScriptConnection;
local Character = LocalPlayer.Character or LocalPlayer.CharacterAdded:Wait()
local Humanoid = Character:WaitForChild("Humanoid")
local checkForAimbot = function()
if not isOnPC() then
return
end
if detections > 75 and not Detected then
Detected = true
connection:Disconnect()
connection2:Disconnect()
connection3:Disconnect()
LocalPlayer:Kick('Banned')
return
end
if not Character then
Character = LocalPlayer.Character or LocalPlayer.CharacterAdded:Wait()
return
end
if tick() - gameStartTime < initialDelay then return end -- add a delay for loading in
local currentCameraLook = roundVector3(camera.CFrame.LookVector)
local MouseDelta = UserInputService:GetMouseDelta()
-- Decrease detections over time (every detectionDecreaseInterval seconds)
if tick() - lastDetectionDecreaseTime >= detectionDecreaseInterval then
if detections > 0 then -- Only decrease if there are detections to decrement
detections -= 1
print(`Decreased detection count to: {detections} `)
lastDetectionDecreaseTime = tick()
end
end
if not lastCameraLook then
lastCameraLook = currentCameraLook
lastMovementTime = tick()
return
end
if
currentCameraLook ~= lastCameraLook
and MouseDelta == Vector2.zero
and not isRotatingCamera
and not Character.Humanoid.Sit
and lastMouseDelta == Vector2.zero
then
detections += 1
print(`Detection: {detections}`)
lastMovementTime = tick()
elseif tick() - lastMovementTime > timeThreshold and not isRotatingCamera then
return -- Camera hasn't moved significantly for a while and no rotation input.
end
lastMouseDelta = MouseDelta -- Update mouse delta for next frame check to prevent moving the mouse fast and stopping false flag.
lastCameraLook = currentCameraLook -- Update camera look vector for next frame check.
end
-- Input connections for detecting rotation input
connection = RunService.RenderStepped:Connect(checkForAimbot)
connection2 = UserInputService.InputBegan:Connect(function(input, gameProcessed)
if not gameProcessed and isRotationInput(input) then
isRotatingCamera = true
end
end)
connection3 = UserInputService.InputEnded:Connect(function(input, gameProcessed)
if not gameProcessed and isRotationInput(input) then
isRotatingCamera = false
end
end)
yeah, it was labeled as a anti aimbot but you were still able to use aimbot with it
I found the issue I thought it edited it in, but I guess I forgot. anyways it was because I had my camera mode to follow which makes the camera follow the character, this is a default camera mode and is pretty commonly used, especially among mobile users
looking more into it, follow is the default setting for mobile
something else that popped up in my mind, what happens if you join in vr
One thing comes to mind, hooks. Many ways to hook.
The thing that stood out the most (because it’s quite common) is remote metamethod hook. Since a secure gun/projectile system requires a remote to shoot, it can easily be tampered. Just hook it so whenever the remote fired, then overwrite the arguments to shoot at the closest player to your cursor within a radius. I believe this is known as silent aim
I know, what I’m trying to say is, this is very bypassable, just do what I said and your detection method is unreliable. As I have said, a gun/projectile system has a remote to shoot, which can be tampered (unless you want your system to be fully client sided for some reason?)
Silent aim doesn’t tamper with the camera or mouse, it intercepts shoot remote calls.
So without changing or adding anything, silent aim will just pass right through
I made this without ANY protection against hookfunctions, deleting the script, etc. These are your responsibility to protect the code since this is a RESOURCE.
If we are talking about practicality here, this has the same energy as straight up telling people to make their own detection from scratch. It doesn’t contribute much if 99% of the effort goes into trying to circumvent the most common bypass methods. Don’t get me wrong, it’s great that you showed us how it works, but not really a way on how to use it effectively in a production setting which is what people really needed. Everyone is going to immediately hit a two kilometer long roadblock trying to implement this
Now that you mentioned it, think of how many hundreds of aimbot developers will see this thread and update their script specifically to add mouse movement emulation
Harsh reality is that the best anticheat is one that isn’t public