Raycast Kind of Wonky

So I’m making this wallrunning code by editing one I found online. However, it keeps saying there is a wall on the left when there is literally nothing there. Also the code only works on one side of the wall? How do I fix it? Any help is appreciated


local uis = game:GetService("UserInputService")

local player = game.Players.LocalPlayer
local c = player.Character or player.CharacterAdded:Wait()

local holdingKey = false

local leftAnim = c.Humanoid:LoadAnimation(script:WaitForChild("WallrunLeft"))
local rightAnim = c.Humanoid:LoadAnimation(script:WaitForChild("WallrunRight"))


uis.InputBegan:Connect(function(inp, p)

	if not p and inp.KeyCode == Enum.KeyCode.F then

		holdingKey = true
	end
end)

uis.InputEnded:Connect(function(inp)

	if inp.KeyCode == Enum.KeyCode.F then

		holdingKey = false
	end
end)
	
local l = Instance.new("Part")
l.Name = "L"
l.Parent = c
l.CanCollide = false
l.Size = Vector3.new(0.1,0.1,0.1)

local r = Instance.new("Part")
r.Name = "R"
r.Parent = c
r.CanCollide = false
r.Size = Vector3.new(0.1,0.1,0.1)

game:GetService("RunService").Heartbeat:Connect(function()
	l.Position = c.HumanoidRootPart.Position-c.HumanoidRootPart.CFrame.RightVector
	--r.Position = c.HumanoidRootPart.Position+c.HumanoidRootPart.CFrame.RightVector
	if holdingKey then
		local raycastParams = RaycastParams.new()
		raycastParams.FilterType = Enum.RaycastFilterType.Blacklist; raycastParams.FilterDescendantsInstances = {c}; raycastParams.IgnoreWater = true
		
		local rayL = workspace:Raycast(c.HumanoidRootPart.Position, c.HumanoidRootPart.Position-c.HumanoidRootPart.CFrame.RightVector*0.5, raycastParams)
		local rayR = workspace:Raycast(c.HumanoidRootPart.Position, c.HumanoidRootPart.Position+c.HumanoidRootPart.CFrame.RightVector*0.5, raycastParams)
		
		local ray = rayL or rayR
		
		if ray then
			
			local newray
			if ray == rayL then
				if not leftAnim.IsPlaying then leftAnim:Play() end
				rightAnim:Stop()
				print("OnLeft")
				local lv = c.HumanoidRootPart.CFrame.LookVector
				local pos = c.HumanoidRootPart.Position
				local left = c.HumanoidRootPart.Position+c.HumanoidRootPart.CFrame.LookVector-c.HumanoidRootPart.CFrame.RightVector * 3
				newray = workspace:Raycast(pos+lv, Vector3.new(left.X, lv.Y, left.Z),raycastParams)
			else
				if not rightAnim.IsPlaying then rightAnim:Play() end
				leftAnim:Stop()
				print("OnRight")
				local lv = c.HumanoidRootPart.CFrame.LookVector
				local pos = c.HumanoidRootPart.Position
				local right = c.HumanoidRootPart.Position+c.HumanoidRootPart.CFrame.LookVector+c.HumanoidRootPart.CFrame.RightVector * 3
				newray = workspace:Raycast(pos+lv, Vector3.new(right.X, lv.Y, right.Z),raycastParams)
			end
			
			local part = ray.Instance
			
			local weld = c.HumanoidRootPart:FindFirstChild("WallrunWeld") or Instance.new("WeldConstraint")
			weld.Name = "WallrunWeld"
				
			weld.Part0 = c.HumanoidRootPart
			weld.Part1 = part

			local bp = c.HumanoidRootPart:FindFirstChild("WallrunBodyPosition") or Instance.new("BodyPosition", c.HumanoidRootPart)
			bp.Name = "WallrunBodyPosition"
			bp.MaxForce = Vector3.new(math.huge, math.huge, math.huge)
			bp.Position = c.HumanoidRootPart.Position + c.HumanoidRootPart.CFrame.LookVector * 10
			
			local target = c:FindFirstChild("Target") or Instance.new("Part", c)
			target.Name = "Target"
			if newray then
				local pos = newray.Position
				local oldpos = ray.Position
				target.CFrame = CFrame.new(oldpos,Vector3.new(pos.X,oldpos.Y,pos.Z))
				target.Anchored = true
				target.CanCollide = false
				
				local a0 = Instance.new("Attachment", c.HumanoidRootPart)
				local a1 = Instance.new("Attachment", target)
				
				local ao = c.HumanoidRootPart:FindFirstChild("WallrunOrientation") or Instance.new("AlignOrientation", c.HumanoidRootPart)
				ao.Name = "WallrunOrientation"
				ao.MaxTorque = Vector3.new(math.huge, math.huge, math.huge)
				ao.RigidityEnabled = true
				ao.Attachment0 = a0
				ao.Attachment1 = a1
			else
				for i, child in pairs(c.HumanoidRootPart:GetChildren()) do
					if child.Name == "WallrunWeld" or child.Name == "WallrunBodyPosition" or child.Name == "WallrunOrientation" or child.Name == "Attachment" then

						child:Destroy()
					end
				end
				if c:FindFirstChild("Target") then
					c:FindFirstChild("Target"):Destroy()
				end

				leftAnim:Stop()
				rightAnim:Stop()
			end
		end
	else
		
		for i, child in pairs(c.HumanoidRootPart:GetChildren()) do
			if child.Name == "WallrunWeld" or child.Name == "WallrunBodyPosition" or child.Name == "WallrunOrientation" or child.Name == "Attachment" then
			
				child:Destroy()
			end
		end
		if c:FindFirstChild("Target") then
			c:FindFirstChild("Target"):Destroy()
		end
		
		leftAnim:Stop()
		rightAnim:Stop()
	end
end)
2 Likes

The second parameter isn’t an end point it’s the ray’s length and direction. You should not be adding the Position back into it since it will do that on it’s own

I like your code! nice easy to follow example! The only small change I’d make is to place the raycast params outside the function so they aren’t re-created every frame, that can be somewhat taxing.

1 Like

Oh dang I never knew that- I always just assumed its just the direction position. I will try in a sec :smiley:

Edit: WORKS TYSM

1 Like