UPDATE: Today (December 12 2021) Roblox has patched corner clipping themselves, meaning this script is now useless. I highly doubt this post has anything to do with it getting patched, as due to the way Roblox rolls out updates the change that fixed corner clipping is likely at least 3 weeks old, but just today was enabled. I will leave the post up just because I don’t want to delete it, and who knows, it might come back in the future (although I doubt it).
This is a simple script that completely patches corner clipping. It works with both R6 and R15. I discovered this around a year ago and decided to post this here just now. I really don’t know why it works, just that it does. Looking at the script, it may not seem like it would do anything, but I assure you it works. Get someone who can corner clip to test it if you don’t believe me.
For those that don’t know, corner clipping is a bug that can be done anywhere there is a corner. It lets you teleport to the other side of the object. It is one of the biggest and most widely known glitches on Roblox. It is possible to do with both R6 and R15, though it is harder to do with R15. While there are ways to prevent it at certain corners (using cylinders), I believe this is the first script that completely fixes it (besides disabling first person and shiftlock).
An example of corner clipping:
Please note that while corner clipping is one of the biggest and most commonly known glitches, there are still other ways to clip through walls, thus you should not rely on this entirely to prevent players from getting out of bounds. Laugh clipping and dance clipping are the two other main glitches that let you clip through walls, you can do research into these if you wish to know more. While you can use this script as an easy fix to corner clipping, I recommend you put in safeguards that activate when a player reaches an area they shouldn’t be able to.
Here is a link to the model. It should be inserted into StarterPlayerScripts.
Alternatively, here is the code (it should be a LocalScript in StarterPlayerScripts):
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local Player = Players.LocalPlayer
RunService.Stepped:Connect(function()
local character = Player.Character
if character then
--For R6
local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
if humanoidRootPart then
local rootJoint = humanoidRootPart:FindFirstChild("RootJoint")
if rootJoint then
rootJoint.Enabled = false
rootJoint.Enabled = true
end
end
--For R15
local lowerTorso = character:FindFirstChild("LowerTorso")
if lowerTorso then
local root = lowerTorso:FindFirstChild("Root")
if root then
root.Enabled = false
root.Enabled = true
end
end
end
end)
Do [""] instead of FindFirstChild, ESPECIALLYin loops.
other than that, cool.
Also, important thing. Exploiters can delete it as it’s a local script, try to make a serversided version instead
(ik .Stepped is only in local, but you can do humanoid.Running or .HeartBeat)
The issue is that the character model could change at any given point so I don’t want to rely on caching these instances. Also, the performance gain from this would be so minimal it’s not even worth it. There are MUCH better ways to make the game run better than microoptimization. The difference here is so minimal it probably couldn’t even be measured without doing this thousands of times.
Direct indexing to get children is not recommended, ever. Sure, in this case you could get away with it since they would never add properties with these names, however it is still a bad practice so I don’t recommend it. Again, this is microoptimization, there are much better ways to improve performance.
Exploiters can also just teleport through the wall. The purpose isn’t to prevent exploits, but to prevent glitches. Very few people would go through the trouble of downloading an exploit just to corner clip, especially when there are better things to do with exploits. Also this wouldn’t work on the server, the change likely wouldn’t even replicate and it is essential it gets changed every frame, which isn’t ensured due to ping.
The issue is that if a new property gets added that shares the same name, then your code will break. In this case, it is unlikely to happen, as Roblox understands these are common instance names, however it is considered a bad practice (this has been stated in announcement posts before) so I would recommend avoiding it altogether.
An easy way would be to connect a .Changed or .AncestryChanged event which changes the variable, instead of using FindFirstChild every frame. It is a micro-optimisation I think, but might be worth seeing if it makes it perform a bit faster.