Something i cannot explain in words

so basically I’ve been trying to make this

but this is the closest thing I can get to getting what I want but I don’t know how to achieve it

can anyone help me please
I’m about to go insane

this is the script in startercharacterscripts

local plr = game.Players.LocalPlayer
local char = plr.Character or plr.CharacterAdded:Wait()
local root = char:WaitForChild("HumanoidRootPart")
local head = char:WaitForChild("Head")
local hum = char:WaitForChild("Humanoid")
local ha = hum:LoadAnimation(script:WaitForChild('ha'))
local tg = plr:WaitForChild("PlayerGui"):FindFirstChild("TouchGui")
local uis = game:GetService("UserInputService")
local ledgeavailable = true
local holding = false

local function c()
	local velo = Instance.new("BodyVelocity",root)
	root.Anchored = false
	velo.MaxForce = Vector3.new(1,1,1) * math.huge
	velo.Velocity = root.CFrame.LookVector * 10 + Vector3.new(0,30,0)
	ha:Stop()
	game.Debris:AddItem(velo,.15)
	holding = false
	char:WaitForChild('Torso').Anchored = false
	wait(.75)
	ledgeavailable = true
end

local function onInputBegan(input, gameProcessed)
	if not holding then return end 
	if input.KeyCode == Enum.KeyCode.Space and not gameProcessed then
		c()
	end
end

local function onJumpButtonClicked()
	if not holding then return end 
	c()
end

uis.InputBegan:Connect(onInputBegan)

if tg then
	local jumpButton = tg:WaitForChild("TouchControlFrame"):WaitForChild("JumpButton")
	jumpButton.MouseButton1Click:Connect(onJumpButtonClicked)
end

while true do
	local r = Ray.new(head.CFrame.p, head.CFrame.LookVector * 3)
	local part,position = workspace:FindPartOnRay(r,char)

	if part and ledgeavailable and not holding then
		if part.Size.Y >= 7 then
			if head.Position.Y >= (part.Position.Y + (part.Size.Y / 2)) - 1 and head.Position.Y <= part.Position.Y + (part.Size.Y / 2) and  root.Velocity.Y <= 0 then
				for _, descendant in ipairs(workspace.uwu:GetDescendants()) do
					if descendant:IsA("Part") then
						local partpos = descendant.Position
						
						local t = char:WaitForChild('Torso')
						local playerpos = t.CFrame.Position
						local lookAt = Vector3.new(partpos.X, playerpos.Y, partpos.Z)

						root.Anchored = true
						holding = true
						ha:Play()
						ledgeavailable = false
						t.Anchored = true
						t.CFrame = CFrame.lookAt(playerpos, lookAt)
					end
				end
			end
		end
	end
	
	wait()
end```
1 Like

Is it that you aren’t lined up perfectly against the wall? I don’t really understand the problem.

The ray function should also return a normal.

With this normal, subtract it from the position the player’s humanoid root part is currently at, and make the player face that.

I also recommend using workspace:Raycast() rather than the deprecated workspace:FindPartOnRay().

3 Likes

the problem is that when you climb looking at an angle, it ends up like this

i want the player to look directly at the wall when they climb like this

I don’t quite understand this, but using workspace:Raycast() breaks the whole script

That’s what @d0cter_oof mentioned with the normal Property.
It tells you which way the wall is facing so you can calculate the angle the Player needs to face.

1 Like

Raycast() works differently to FindPartOnRay():

local root = character.HumanoidRootPart
local head = character.Head

-- Raycast() requires RaycastParams, which give us considerable control over raycasts.
local params = RaycastParams.new()
-- params.FilterType = Enum.RaycastFilterType.Include
-- params.FilterDescendantsInstances = Ledges
params.RespectCanCollide = true

local raycastResults = workspace:Raycast(head.Position, head.CFrame.LookVector * 3, params)
local normal = raycastResults.Normal
root.CFrame = CFrame.lookAt(root.Position, root.Position - normal)

3 Likes