So, I was in the middle of reworking my Wall Crawling System that was previously seen at this post:
This time, I dug deeper into this post:
Although, I began to struggle with the movement as the BodyVelocity was moving into directions that I don’t want it to go and whenever I attempt to go in the opposite direction, the Player stops moving.
Footage: https://gyazo.com/0d001c99dac41ef19b1a8510619eb8b0
The solution to this problem was a pain to find and so I crashed into rock bottom and got nowhere. Here is the provided script that is parented in StarterCharacterScripts:
local UserInputService = game:GetService("UserInputService")
local Exit_Threshold = 0.25
local PreviousTime = 0
local Controls = {Up = 0, Down = 0, Left = 0, Right = 0}
local Speed = 25
local RunService = game:GetService("RunService")
local Player = game.Players.LocalPlayer
local Character = Player.Character
local Humanoid = Character:WaitForChild("Humanoid")
local RootPart = Character:WaitForChild("HumanoidRootPart") or Character.PrimaryPart
local BodyVelocity = Instance.new("BodyVelocity", nil)
BodyVelocity.MaxForce = Vector3.new(1, 1, 1) * math.huge
BodyVelocity.P = 100
BodyVelocity.Velocity = Vector3.new(0, 0, 0)
BodyVelocity.Name = "ClimbVelocity"
local BodyGyro = Instance.new("BodyGyro", nil)
BodyGyro.MaxTorque = Vector3.new(1, 1, 1) * math.huge
BodyGyro.CFrame = CFrame.new()
BodyGyro.Name = "ClimbGyro"
local RaycastParameters = RaycastParams.new()
RaycastParameters.FilterDescendantsInstances = {Character}
RaycastParameters.FilterType = Enum.RaycastFilterType.Blacklist
RaycastParameters.IgnoreWater = true
local Climbing = false
local OnWall = false
local Face = nil
function OnClimb()
local Origin, Direction = RootPart.Position, RootPart.CFrame.LookVector
local RaycastResult = workspace:Raycast(Origin, Direction, RaycastParameters)
if RaycastResult then
Face = CFrame.new(RaycastResult.Position + RaycastResult.Normal, RaycastResult.Position)
Climbing = true
OnWall = true
RootPart.CFrame = CFrame.new(RootPart.CFrame.Position, Vector3.new(RootPart.Position.X - RaycastResult.Normal.X, RootPart.Position.Y, RootPart.Position.Z - RaycastResult.Normal.Z))
BodyVelocity.Parent = RootPart
BodyGyro.Parent = RootPart
Humanoid.PlatformStand = true
Humanoid.AutoRotate = false
repeat
RunService.RenderStepped:Wait()
BodyGyro.CFrame = Face or CFrame.new()
local Movement = RootPart.CFrame:VectorToWorldSpace(Vector3.new(Controls.Left + Controls.Right, Controls.Up + Controls.Down, 0)) * Speed
BodyVelocity.Velocity = Movement
until (not Climbing)
end
end
function OffClimb()
Climbing = false
BodyVelocity.Parent = nil
BodyGyro.Parent = nil
Humanoid.PlatformStand = false
Humanoid.AutoRotate = true
end
UserInputService.InputBegan:Connect(function(input, gameProcessedEvent)
if input.KeyCode == Enum.KeyCode.C then
if Climbing == false then
OnClimb()
else
OffClimb()
end
end
if input.KeyCode then
if input.KeyCode == Enum.KeyCode.W then
if OnWall then
Controls.Up = 1
end
elseif input.KeyCode == Enum.KeyCode.S then
if OnWall then
Controls.Down = -1
end
elseif input.KeyCode == Enum.KeyCode.D then
if OnWall then
Controls.Right = 1
end
elseif input.KeyCode == Enum.KeyCode.A then
if OnWall then
Controls.Left = -1
end
end
end
if input.KeyCode == Enum.KeyCode.Space and Climbing == true then
local CurrentTime = tick()
if CurrentTime - PreviousTime <= Exit_Threshold then
OffClimb()
else
PreviousTime = CurrentTime
end
end
end)
UserInputService.InputBegan:Connect(function(input, gameProcessedEvent)
if input.KeyCode then
if input.KeyCode == Enum.KeyCode.W then
if OnWall then
Controls.Up = 0
end
elseif input.KeyCode == Enum.KeyCode.S then
if OnWall then
Controls.Down = 0
end
elseif input.KeyCode == Enum.KeyCode.D then
if OnWall then
Controls.Down = 0
end
elseif input.KeyCode == Enum.KeyCode.A then
if OnWall then
Controls.Down = 0
end
end
end
end)