Hello, when I was very new to programming in Roblox Lua, I had no idea how to incorporate raycasting into my models. One problem I had while making a game is that players would get stuck in the walls of the game. To fix this, I decided to use a method which is made for anti-noclip. I tried making this script on my own for about a month but had failed a lot, so I’m hoping this tutorial will help a lot of beginner programmers in combatting exploiting and stopping some bugs.
To get started, you’re going to want to make a new script in ServerScriptService, you can name it anything you’d like. Inside the script, you’re going to put the following script:
Source code
game:GetService("Players").PlayerAdded:Connect(function(plr)
plr.CharacterAdded:Connect(function(char)
spawn(function()
local root = char.HumanoidRootPart
local LastVec = root.Position
game:GetService("RunService").Heartbeat:Connect(function()
local r = Ray.new(LastVec, root.Position - LastVec)
local Hit, Position = workspace:FindPartOnRayWithIgnoreList(r, {char})
pcall(function()
if Hit and Hit.CanCollide == true then
root.CFrame = CFrame.new(LastVec)
end
end)
LastVec = root.Position
print(LastVec)
end)
end)
end)
end)
Let’s go through what this script does step by step.
game:GetService("Players").PlayerAdded:Connect(function(plr)
plr.CharacterAdded:Connect(function(char)
The above script waits for a player to join, and then waits for their character to load.
local root = char.HumanoidRootPart
local LastVec = root.Position
game:GetService("RunService").Heartbeat:Connect(function()
This will assign the variable root
to char.HumanoidRootPart
, and then keep track of it’s current position in the variable LastVec
. The last line will run the function every heartbeat of RunService. I’m not good at explaining how heartbeat works, so feel free to check out this roblox api page on it.
local r = Ray.new(LastVec, root.Position - LastVec)
local Hit, Position = workspace:FindPartOnRayWithIgnoreList(r, {char})
This creates a new ray with the humanoid root part’s last position and then fires the ray in the direction of the current position.
pcall(function()
if Hit and Hit.CanCollide == true then
root.CFrame = CFrame.new(LastVec)
end
end)
LastVec = root.Position
-- print(LastVec)
This piece of code sets the humanoid root part’s CFrame to the last vector recorded only if the ray found a collide-able part intersecting between it, like a wall.
Note: if the player has extreme lag while going around corners, then this may have false positives and send the player back when they were rounding a corner. If this is the case, then this method is not for you.
I hope you enjoyed my first tutorial, feel free to ask any questions or give me criticism in the replies. Thank you for reading : )