Alright, lets get in to it!
First thing you should keep in mind when writing a script for this is that anything on the client can be manipulated! This is extremely important for what we’re trying to achieve as we don’t want users to be able to bypass our anti-cheat by using metatables in order to spoof there location. So everything like this should be handled on the server for the maximum efficiency, but you should keep in mind that this also may cause random lagbacks if users have extremely bad ping.
Now you can do this two ways, checking the magnitude/distance by the players current location and there last location… or you could cast a ray and then figure out how long that said ray is. We’ll use the first way for now, if you want to learn the second way then feel free to ask!
So firstly we’ll want a table, your table could be named anything but for the sake of this anti-teleportation we’ll just call it lastLocations!
local lastLocations = {}
Boom, now we have a table. So this table is going to store all of the users last locations, we can then take the users current location and check the distance from there last location.
I’m assuming you want this anti-cheat to activate when the player first joins, so with that being said we will just use a join event.
local lastLocations = {}
local Players = game:GetService("Players")
function antiTeleport(Player)
end
Players.PlayerAdded:connect(antiTeleport)
Alright, now we have that. So where do we go from here? Well we know that a teleportation is a user moving from one location to another instantly/extremely quickly. So how do we go about fixing this? We can first make a loop which will saves the users old location.
while wait(timeBetweenChecks) do
--- This is the loop which will contain our checks!
end
Inside of this loop we need to make sure the player is alive, to do this we can just check if there character is a thing.
local Character = Player.Character
if Character and Character:FindFirstChild("HumanoidRootPart") then
end
That should do the trick! Okay, so we know the player is alive and in the game… now we actually make our anti-teleport at its core.
We will be using DistanceFromCharacter for this. So as it says we need a vector value, which is the value we will be storing inside our table (the users location from x amount of seconds ago)
local lastLocations = {} -- A table full of players and there last location
local Players = game:GetService("Players")
function antiTeleport(Player) -- Function that handles our antiTeleport
local Character = Player.Character
if Character and Character:FindFirstChild("HumanoidRootPart") then -- making sure the character is a thing!
if lastLocations[Player] then -- Assuring our player is in the table!
local distanceFromLast = Player:DistanceFromCharacter(lastLocations[Player])
if distanceFromLast >= MAX_DISTANCE then
-- Punish user accordingly, for this example we'll just teleport the player back!
Character.HumanoidRootPart.Position = lastLocations[Player] -- Users current location for the next check
end
lastLocations[Player] = Character.HumanoidRootPart.Position
else -- User isn't in our table, lets put them in!
lastLocations[Player] = Character.HumanoidRootPart.Position -- A vector3 value
end
end
end
Players.PlayerAdded:connect(antiTeleport)
Disclaimer!
Everything here is untested and scripted within the devforums reply button, if something is wrong let me know!