I’m attempting to make a wall-climbing system. I don’t have any idea on how to make the character be locked in front of a wall while still being able to move up, down, right and left. (I’m gonna worry about movements later.)
humanoid.Jumping:Connect(function(isActive)
if not isActive then return end
local raycastResult = workspace:Raycast(rootPart.Position, rootPart.CFrame.LookVector * 3)
if raycastResult and not onWall then
onWall = true
print(onWall)
character:SetPrimaryPartCFrame(CFrame.lookAt(raycastResult.Position + raycastResult.Normal, raycastResult.Position))
else
onWall = false
print(onWall)
end
end)
I’ve tried doing this a while ago and found this post Making a "Wall Climbing" System - #12 by Stealthied which was really helpful if you haven’t came across this already you should check it out it could help you out.
1 Like
That’s what I’ve actually found before posting. I still don’t understand it.
Yeah I didn’t understand it at first, but once you start messing with the code removing and changing things you figure out what does what or at least what I did. Anyways here’s the code I ended up with feel free to use it it’s not great, but yeah lol it works.
--| Services
local UIS = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
--| Variables
local Player = Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local HRP = Character:WaitForChild("HumanoidRootPart")
local Humanoid = Character:WaitForChild("Humanoid")
local IsClimbing = false
local Connections = {}
local function IsKeyDown(Key)
return UIS:IsKeyDown(Enum.KeyCode[Key])
end
UIS.InputBegan:Connect(function(Input,IsTyping)
if IsTyping then return end
local Key = UIS:GetStringForKeyCode(Input.KeyCode)
if Key == "F" then --You can replace this with any key
--warn("WALL CLIMB")
local Face = nil
local Actions = {0;0;0;0;}
local Buttons = {"A";"D";"S";"W"}
if not IsClimbing then
--warn("START WALL CLIMB")
local Params = RaycastParams.new()
Params.CollisionGroup = ("Climbable")
Params.FilterDescendantsInstances = {Character}
Params.FilterType = Enum.RaycastFilterType.Blacklist
Params.IgnoreWater = true
--Climb Moving/Speed
local BV = Instance.new("BodyVelocity")
BV.Name = "WallClimbBV"
BV.MaxForce = Vector3.new(1,1,1)*math.huge
BV.P = math.huge
BV.Velocity = Vector3.new()
--BV.Name = ("Climb Speed")
--Keeps the player position the same (so they don't rotate around and stuff)
local BG = Instance.new("BodyGyro")
BG.Name = "WallClimbBG"
BG.CFrame = CFrame.new()
BG.D = 100
BG.MaxTorque = Vector3.new(1,1,1)*math.huge
BG.P = 3000
local Origin = HRP.Position
local Direction = HRP.CFrame.LookVector
local Result = workspace:Raycast(Origin, Direction, Params)
if Result then
if not Result.Instance.Parent:FindFirstChild("Humanoid") then
Connections["Connection1"] = UIS.InputBegan:Connect(function(Input,IsTyping)
if IsTyping then return end
local Key = UIS:GetStringForKeyCode(Input.KeyCode)
--warn(Key)
local Test = table.find(Buttons, Key)
if Test then
Actions[Test]=1
end
end)
Connections["Connection2"] = UIS.InputEnded:Connect(function(Input,IsTyping)
if IsTyping then return end
local Key = UIS:GetStringForKeyCode(Input.KeyCode)
--warn(Key)
local Test = table.find(Buttons, Key)
if Test then
Actions[Test]=0
end
end)
Connections["Connection3"] = RunService.RenderStepped:Connect(function()
--warn("TEST")
local Strafe = Actions[2] - Actions[1]
local Surge = Actions[3] - Actions[4]
BV.Velocity=HRP.CFrame.RightVector*(Strafe*8)+Vector3.new(0, Surge*-8, 0)
end)
IsClimbing = true
HRP.CFrame = CFrame.new(HRP.CFrame.p, Vector3.new(HRP.Position.X - Result.Normal.X, HRP.Position.Y, HRP.Position.Z - Result.Normal.Z))
Face = CFrame.new(Result.Position+Result.Normal, Result.Position)
Humanoid.AutoRotate=false
Humanoid.PlatformStand=true
BV.Parent=HRP
BG.Parent=HRP
repeat
RunService.RenderStepped:Wait()
BG.CFrame=Face or CFrame.new()
--When you reach the top of the part
if HRP.Position.Y > Result.Instance.Size.Y+3 then
IsClimbing = false
_G[Player.Name]:StopAnimation("Climb")
BG.Parent=nil
BV.Parent=nil
Face=nil
end
local sideOrigin = HRP.CFrame*CFrame.new(0, 0, -1).Position
local sideDirection = HRP.CFrame.RightVector*(IsKeyDown("D") and -2 or 2)
local Hit = workspace:Raycast(sideOrigin, sideDirection, Params)
if Hit and (IsKeyDown("D") or IsKeyDown("A")) then
Face=CFrame.new(Hit.Position+Hit.Normal, Hit.Position)
end
until (not IsClimbing)
Humanoid.AutoRotate=true
Humanoid.PlatformStand=false
end
end
else
--warn("STOP WALL CLIMB")
if IsClimbing then --just make sure they all climbing
Connections["Connection1"] = nil
Connections["Connection2"] = nil
Connections["Connection3"] = nil
IsClimbing = false
_G[Player.Name]:StopAnimation("Climb")
HRP:FindFirstChild("WallClimbBG").Parent = nil
HRP:FindFirstChild("WallClimbBV").Parent = nil
Face = nil
end
end
end
end)
To get this to work though you need to make some collision groups and if you don’t know how to do that you can do it by going to the model section at the top in studio and at the very end you’ll see a button called collision groups and it will open up this panel
all you gotta do is where it says “+ Add Group” type “Climbable” and then “Unclimable”. Hopefully this made sense!
1 Like