I made a noclip script that works but feels terribly unoptimized here are the main things that annoy me:
- I have a serverscript
- How input detection is handled
- How moving diagonal and stuff is handled
- Using coroutine
Things to note:
- I have a server script so that the command to toggle noclip can delete it
- The values in NoclipC are not important
- I am not very experienced with CFrame a lot of the CFrame stuff was done via the help of a tutorial
Things to note for the Rbxl File.rbxl (116.9 KB):
- Noclip is engaged by using cmdr with F8
- Default toggle keybind is LeftAlt if not specified
Hierarchy:
--Noclip Toggler (simplified due to a bunch of code specifically for cmdr)
if player.Character:FindFirstChild("Noclip") then
local HRP = player.Character.HumanoidRootPart
HRP.Parent.Animate.Enabled = true
if HRP:FindFirstChild("AlignPosition") then
HRP:FindFirstChild("AlignPosition"):Destroy()
end
if HRP:FindFirstChild("AlignOrientation") then
HRP:FindFirstChild("AlignOrientation"):Destroy()
end
game:GetService("RunService"):UnbindFromRenderStep("noclip")
HRP.Parent.NoclipS:Destroy()
HRP.Parent.NoclipC:Destroy()
else
local NoclipScript = script.NoclipC:Clone()
NoclipScript.ToggleKeybind.Value = if togglekeybind then togglekeybind.Name else "LeftAlt"
NoclipScript.Speed.Value = if speed then speed else 5
Instance.new("AlignPosition", player.Character.HumanoidRootPart).Enabled = false
Instance.new("AlignOrientation", player.Character.HumanoidRootPart).Enabled = false
NoclipScript.Parent = player.Character
script.NoclipS:Clone().Parent = player.Character
end
--Noclip Character Local Script (used to actually position the player)
local s, eM = pcall(function()
--[[ Services ]]--
local UIS = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
--[[ Parts ]]--
local Camera = workspace.CurrentCamera
local HRP = script.Parent.HumanoidRootPart
--[[ Variables ]]--
local Speed = script.Speed.Value
local Keybind = Enum.KeyCode[script.ToggleKeybind.Value]
local Noclipping = false
local Thread --Global so the thread can be closed
local WalkSpeed = 16
local R6 = if HRP.Parent.Humanoid.RigType == Enum.HumanoidRigType.R6 then true else false
--[[ Configure Align Objects ]]--
HRP.AlignPosition.Responsiveness = 50
HRP.AlignPosition.MaxForce = (99^99)^99
HRP.AlignPosition.Mode = Enum.PositionAlignmentMode.OneAttachment
HRP.AlignPosition.Attachment0 = HRP.RootAttachment
HRP.AlignOrientation.Mode = Enum.OrientationAlignmentMode.OneAttachment
HRP.AlignOrientation.Attachment0 = HRP.RootAttachment
HRP.AlignOrientation.Responsiveness = 50
HRP.AlignOrientation.MaxTorque = (99^99)^99
--[[ Noclip toggler ]]--
UIS.InputBegan:Connect(function(Input, Busy)
if Input.KeyCode == Keybind and not Busy then
if not Noclipping then
Noclipping = true
--[[ Configure AlignPosition for updating Player Pos ]]--
local AP = HRP.AlignPosition
AP.Position = HRP.CFrame.Position
AP.Enabled = true
--[[ Configure AlignOrientation for updating Player Ori ]]--
local AO = HRP.AlignOrientation
AO.Enabled = true
--[[ Table to store key inputs ]]--
local Move = "____"
--[[ Prevent animations and sounds from playing ]]--
WalkSpeed = script.Config:InvokeServer(1)
--[[ Disable Collision ]]--
for _, v in pairs(script.Parent:GetChildren()) do
if v:IsA("Part") or v:IsA("MeshPart") then
v.CollisionGroup = "NoCollide"
end
end
--[[ Bind function to rendering for smooth noclipping ]]--
RunService:BindToRenderStep("noclip", 300, function()
--[[ Orient the player ]]--
AO.CFrame = CFrame.new(Camera.CFrame.Position, HRP.Position)
--[[ Position the player ]]--
if Move == "W___" or Move == "WA_D" then
AP.Position = CFrame.new(HRP.CFrame.Position + (HRP.CFrame.LookVector * Speed)).Position
elseif Move == "_A__" or Move == "WAS_" then
AP.Position = CFrame.new(HRP.CFrame.Position + (HRP.CFrame.RightVector * -Speed)).Position
elseif Move == "__S_" or Move == "_ASD" then
AP.Position = CFrame.new(HRP.CFrame.Position + (HRP.CFrame.LookVector * -Speed)).Position
elseif Move == "___D" or Move == "W_SD" then
AP.Position = CFrame.new(HRP.CFrame.Position + (HRP.CFrame.RightVector * Speed)).Position
elseif Move == "WA__" then
AP.Position = CFrame.new((HRP.CFrame.Position + (HRP.CFrame.LookVector * Speed)) + (HRP.CFrame.RightVector * -Speed)).Position
elseif Move == "W__D" then
AP.Position = CFrame.new((HRP.CFrame.Position + (HRP.CFrame.LookVector * Speed)) + (HRP.CFrame.RightVector * Speed)).Position
elseif Move == "_AS_" then
AP.Position = CFrame.new((HRP.CFrame.Position + (HRP.CFrame.LookVector * -Speed)) + (HRP.CFrame.RightVector * -Speed)).Position
elseif Move == "__SD" then
AP.Position = CFrame.new((HRP.CFrame.Position + (HRP.CFrame.LookVector * -Speed)) + (HRP.CFrame.RightVector * Speed)).Position
end
end)
--[[ Thread for detecting player input ]]--
Thread = coroutine.create(function()
UIS.InputBegan:Connect(function(Input, Busy)
if not Busy then
if Input.KeyCode == Enum.KeyCode.W then
Move = "W"..Move:sub(2)
elseif Input.KeyCode == Enum.KeyCode.A then
Move = Move:sub(1,1).."A"..Move:sub(3)
elseif Input.KeyCode == Enum.KeyCode.S then
Move = Move:sub(1,2).."S"..Move:sub(4)
elseif Input.KeyCode == Enum.KeyCode.D then
Move = Move:sub(1,3).."D"
end
end
end)
UIS.InputEnded:Connect(function(Input, Busy)
if Move then
if Input.KeyCode == Enum.KeyCode.W then
Move = "_"..Move:sub(2)
elseif Input.KeyCode == Enum.KeyCode.A then
Move = Move:sub(1,1).."_"..Move:sub(3)
elseif Input.KeyCode == Enum.KeyCode.S then
Move = Move:sub(1,2).."_"..Move:sub(4)
elseif Input.KeyCode == Enum.KeyCode.D then
Move = Move:sub(1,3).."_"
end
end
end)
end)
--[[ Start thread ]]--
coroutine.resume(Thread)
else
--[[ Unbind and close threads ]]--
Noclipping = false
RunService:UnbindFromRenderStep("noclip")
coroutine.close(Thread)
--[[ Disable Align objects ]]--
HRP.AlignPosition.Enabled = false
HRP.AlignOrientation.Enabled = false
--[[ Enable collision ]]--
for _, v in pairs(script.Parent:GetChildren()) do
if v:IsA("Part") or v:IsA("MeshPart") then
v.CollisionGroup = "Default"
end
end
--[[ Restore animations and sounds ]]--
script.Config:InvokeServer(2, WalkSpeed)
end
end
end)
end)
if not s then
script.Config:InvokeServer(3)
game:GetService("RunService"):UnbindFromRenderStep("noclip")
warn("Error occured during noclip : "..eM)
script:Destroy()
end
--Noclip Character Server Script (used for things that should be done on the server, lots of issues came from changing things back like walkspeed on the server when it was changed on the client)
script.Parent.NoclipC.Config.OnServerInvoke = function(Player: Player, Id: number, WalkSpeed: number)
if Player == game:GetService("Players"):GetPlayerFromCharacter(script.Parent) then
if Id == 1 then
local HRP = script.Parent.HumanoidRootPart
local WalkSpeed = HRP.Parent.Humanoid.WalkSpeed
HRP.Parent.Humanoid.WalkSpeed = 0
wait(0.1)
HRP.Parent.Animate.Enabled = false
return WalkSpeed
elseif Id == 2 then
local HRP = script.Parent.HumanoidRootPart
HRP.Parent.Humanoid.WalkSpeed = WalkSpeed
HRP.Parent.Animate.Enabled = true
elseif Id == 3 then
local HRP = script.Parent:FindFirstChild("HumanoidRootPart")
if HRP then
HRP.Parent.Humanoid.WalkSpeed = 16
HRP.Parent.Animate.Enabled = true
if HRP:FindFirstChild("AlignPosition") then
HRP:FindFirstChild("AlignPosition"):Destroy()
end
if HRP:FindFirstChild("AlignOrientation") then
HRP:FindFirstChild("AlignOrientation"):Destroy()
end
end
script.Parent.NoclipC:Destroy()
script:Destroy()
end
else
pcall(function()Player:Destroy()end)
end
end