Anyways as you can see in the video i have a wallclimb system which is not great but for my first time doing something like that im happy with it, it allows for you to switch walls while climbing. However as you can see that only works if the wall is directly to the right or left of the players root part. I would like to be able to switch walls in the second scenario shown in the video too. I am new to humanoid movers and dont know how to raycast in such a way to allow for what I want
local sript
local flyEvent = game.ReplicatedStorage:WaitForChild("Wall")
local UIS = game:GetService("UserInputService")
local RS = game:GetService("RunService")
local RParams = RaycastParams.new()
RParams.FilterType = Enum.RaycastFilterType.Exclude
local nearWall = false
UIS.InputBegan:Connect(function(input, gp)
if gp or nearWall == false then return end
if input.KeyCode == Enum.KeyCode.W then
flyEvent:FireServer("Up", true)
end
if input.KeyCode == Enum.KeyCode.D then
flyEvent:FireServer("Right", true)
end
if input.KeyCode == Enum.KeyCode.A then
flyEvent:FireServer("Left", true)
end
if input.KeyCode == Enum.KeyCode.S then
flyEvent:FireServer("Down", true)
end
end)
UIS.InputEnded:Connect(function(input, gp)
if gp or nearWall == false then return end
if input.KeyCode == Enum.KeyCode.W then
flyEvent:FireServer("Up", false)
end
if input.KeyCode == Enum.KeyCode.D then
flyEvent:FireServer("Right", false)
end
if input.KeyCode == Enum.KeyCode.A then
flyEvent:FireServer("Left", false)
end
if input.KeyCode == Enum.KeyCode.S then
flyEvent:FireServer("Down", false)
end
end)
repeat task.wait()
until game.Players.LocalPlayer.Character
RParams.FilterDescendantsInstances = {game.Players.LocalPlayer.Character}
local animationPlaying = false
local track = game.Players.LocalPlayer.Character.HumanoidRootPart.Parent.Humanoid.Animator:LoadAnimation(script.Animation)
local SwitchingWalls = false
RS.Heartbeat:Connect(function()
local humanoidRootPart = game.Players.LocalPlayer.Character:FindFirstChild("HumanoidRootPart")
if not humanoidRootPart then return end
local raycastResult = workspace:Raycast(
humanoidRootPart.Position,
humanoidRootPart.CFrame.LookVector * 1.3,
RParams
)
local raycastResultRight = workspace:Raycast(
humanoidRootPart.Position,
humanoidRootPart.CFrame.RightVector * 1.3,
RParams
)
local raycastResultLeft = workspace:Raycast(
humanoidRootPart.Position,
humanoidRootPart.CFrame.RightVector * -1.3,
RParams
)
if raycastResult and raycastResult.Instance then
if raycastResult.Instance:GetAttribute("CanClimb") then
if animationPlaying == false then
track:Play()
animationPlaying = true
end
nearWall = true
if raycastResultLeft and raycastResultLeft.Instance and raycastResultLeft.Instance:GetAttribute("CanClimb") and SwitchingWalls == false then
SwitchingWalls = true
humanoidRootPart.CFrame = CFrame.new(humanoidRootPart.Position, humanoidRootPart.Position + -raycastResultLeft.Normal)
task.wait(1)
SwitchingWalls = false
elseif raycastResultRight and raycastResultRight.Instance and raycastResultRight.Instance:GetAttribute("CanClimb") and SwitchingWalls == false then
SwitchingWalls = true
humanoidRootPart.CFrame = CFrame.new(humanoidRootPart.Position, humanoidRootPart.Position + -raycastResultRight.Normal)
task.wait(1)
SwitchingWalls = false
else
humanoidRootPart.CFrame = CFrame.new(humanoidRootPart.Position, humanoidRootPart.Position + -raycastResult.Normal)
end
end
else
if not raycastResult and not raycastResultLeft and not raycastResultRight then
nearWall = false
animationPlaying = false
track:Stop()
flyEvent:FireServer("Stop")
end
end
end)
server:
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local flyEvent = ReplicatedStorage:WaitForChild("Wall")
local WHeld = false
local AHeld = false
local SHeld = false
local DHeld = false
local YPower = 0
local RightPower = 0
local lv
local humanoidRootPart
local character
Players.PlayerAdded:Connect(function(player)
character = player.Character or player.CharacterAdded:Wait()
humanoidRootPart = character:WaitForChild("HumanoidRootPart")
local rootAttachment = humanoidRootPart:FindFirstChild("RootAttachment")
if not rootAttachment then
rootAttachment = Instance.new("Attachment")
rootAttachment.Name = "RootAttachment"
rootAttachment.Parent = humanoidRootPart
end
lv = Instance.new("LinearVelocity")
lv.MaxForce = math.huge
lv.RelativeTo = Enum.ActuatorRelativeTo.World
lv.Parent = humanoidRootPart
lv.VectorVelocity = Vector3.new(0, 0, 0)
end)
flyEvent.OnServerEvent:Connect(function(player, key, bool)
lv.Attachment0 = humanoidRootPart.RootAttachment
player.Character.Humanoid.AutoRotate = false
if key == "Up" then
if bool == true then
YPower = 20
WHeld = true
else
YPower = 0
WHeld = false
end
end
if key == "Down" then
if bool == true then
YPower = -20
SHeld = true
else
YPower = 0
SHeld = false
end
end
if key == "Right" then
if bool == true then
RightPower = 20
DHeld = true
else
RightPower = 0
DHeld = false
end
end
if key == "Left" then
if bool == true then
RightPower = -20
AHeld = true
else
RightPower = 0
AHeld = false
end
end
if key == "Stop" then
RightPower = 0
YPower = 0
lv.Attachment0 = nil
WHeld = false
SHeld = false
DHeld = false
AHeld = false
player.Character.Humanoid.AutoRotate = true
end
end)
repeat task.wait()
until character
local RParams = RaycastParams.new()
RParams.FilterType = Enum.RaycastFilterType.Exclude
RParams.FilterDescendantsInstances = {character}
game:GetService("RunService").Heartbeat:Connect(function()
if lv then
local rootCFrame = humanoidRootPart.CFrame
local moveDirection = Vector3.new(RightPower, YPower, 0)
local worldMoveDirection = rootCFrame:VectorToWorldSpace(moveDirection)
lv.VectorVelocity = worldMoveDirection
local raycastResultDown = workspace:Raycast(
humanoidRootPart.Position,
humanoidRootPart.CFrame.UpVector * -3,
RParams
)
local raycastResult = workspace:Raycast(
humanoidRootPart.Position,
humanoidRootPart.CFrame.LookVector * 2,
RParams
)
if raycastResultDown then
if raycastResultDown.Instance then
RightPower = 0
YPower = 0
lv.Attachment0 = nil
WHeld = false
SHeld = false
DHeld = false
AHeld = false
character.Humanoid.AutoRotate = true
end
end
end
end)
Okay so if you have a wall that is adjacent, it should be able to hit if you raycast in the direction of the LeftVector / RightVector of the wall the player is on from the wall’s position.
also sorry for the long wait. I had to really sit and think about how to solve this lol
so…
Raycast from the wall the player is currently on
Have 2 ray casts, one going left, one going right (LeftVector, RightVector)
Check if the ray hit anything, and if it is a valid surface
I’ve honestly got no idea what im talking about so if anyone more knowledgeable sees this, could you correct me?
I looked at just about every post about wallclimbing and none of them really helped me in the issue that I have. They all explain how to do just up down left right which I have working, none of them address the issue with changing walls that I have
I don’t really have any other guesses other than rotating the position you’re raycasting from by 90deg and -90deg and moving it a little bit in that direction.
local flyEvent = game.ReplicatedStorage:WaitForChild("Wall")
local UIS = game:GetService("UserInputService")
local RS = game:GetService("RunService")
local RParams = RaycastParams.new()
RParams.FilterType = Enum.RaycastFilterType.Exclude
local nearWall = false
UIS.InputBegan:Connect(function(input, gp)
if gp or nearWall == false then return end
if input.KeyCode == Enum.KeyCode.W then
flyEvent:FireServer("Up", true)
end
if input.KeyCode == Enum.KeyCode.D then
flyEvent:FireServer("Right", true)
end
if input.KeyCode == Enum.KeyCode.A then
flyEvent:FireServer("Left", true)
end
if input.KeyCode == Enum.KeyCode.S then
flyEvent:FireServer("Down", true)
end
end)
UIS.InputEnded:Connect(function(input, gp)
if gp or nearWall == false then return end
if input.KeyCode == Enum.KeyCode.W then
flyEvent:FireServer("Up", false)
end
if input.KeyCode == Enum.KeyCode.D then
flyEvent:FireServer("Right", false)
end
if input.KeyCode == Enum.KeyCode.A then
flyEvent:FireServer("Left", false)
end
if input.KeyCode == Enum.KeyCode.S then
flyEvent:FireServer("Down", false)
end
end)
repeat task.wait()
until game.Players.LocalPlayer.Character
RParams.FilterDescendantsInstances = {game.Players.LocalPlayer.Character}
local animationPlaying = false
local track = game.Players.LocalPlayer.Character.HumanoidRootPart.Parent.Humanoid.Animator:LoadAnimation(script.Animation)
local SwitchingWalls = false
RS.Heartbeat:Connect(function()
local humanoidRootPart = game.Players.LocalPlayer.Character:FindFirstChild("HumanoidRootPart")
if not humanoidRootPart then return end
local raycastResult = workspace:Raycast(
humanoidRootPart.Position,
humanoidRootPart.CFrame.LookVector * 1.3,
RParams
)
local raycastResultRight = workspace:Raycast(
humanoidRootPart.Position,
humanoidRootPart.CFrame.RightVector * 1.3,
RParams
)
local raycastResultLeft = workspace:Raycast(
humanoidRootPart.Position,
humanoidRootPart.CFrame.RightVector * -1.3,
RParams
)
local rayCastResultFrontRight = workspace:Raycast(
humanoidRootPart.Parent.RightHand.Position,
humanoidRootPart.CFrame.RightVector * -1.3,
RParams
)
if raycastResult and raycastResult.Instance then
if raycastResult.Instance:GetAttribute("CanClimb") then
if animationPlaying == false then
track:Play()
animationPlaying = true
end
nearWall = true
if raycastResultLeft and raycastResultLeft.Instance and raycastResultLeft.Instance:GetAttribute("CanClimb") and SwitchingWalls == false then
SwitchingWalls = true
humanoidRootPart.CFrame = CFrame.new(humanoidRootPart.Position, humanoidRootPart.Position + -raycastResultLeft.Normal)
task.wait(1)
SwitchingWalls = false
elseif raycastResultRight and raycastResultRight.Instance and raycastResultRight.Instance:GetAttribute("CanClimb") and SwitchingWalls == false then
SwitchingWalls = true
humanoidRootPart.CFrame = CFrame.new(humanoidRootPart.Position, humanoidRootPart.Position + -raycastResultRight.Normal)
task.wait(1)
SwitchingWalls = false
elseif rayCastResultFrontRight and rayCastResultFrontRight.Instance and rayCastResultFrontRight.Instance:GetAttribute('CanClimb') and SwitchingWalls == false then
SwitchingWalls = true
humanoidRootPart.CFrame = CFrame.new(humanoidRootPart.Position, humanoidRootPart.Position + -rayCastResultFrontRight.Normal)
task.wait(1)
SwitchingWalls = false
else
humanoidRootPart.CFrame = CFrame.new(humanoidRootPart.Position, humanoidRootPart.Position + -raycastResult.Normal)
end
end
else
if not raycastResult and not raycastResultLeft and not raycastResultRight then
nearWall = false
animationPlaying = false
track:Stop()
flyEvent:FireServer("Stop")
end
end
end)
it detects the wall but i dont get aligned properly
im REALLY SORRY about delaying a response for 3 hours!! Completely forgot again
to
--[[ spaced out
so you can see
the change(s)
I made
]]
humanoidRootPart.CFrame = CFrame.new(humanoidRootPart.Position,
humanoidRootPart.Position
+ -rayCastResultFrontRight.Normal
+ Vector3.new(10, 0, 0)
)
I chose (10, 0, 0) to move your character to the right a bit (hopefully I’m not tripping today)
So if I were you, I would just experiment with the numbers. But I’m pretty sure there’s a better way to make this type of thing if somebody who’s made one could come around