How would I do this?

I’m making a wall climbing mechanic for my game, and I’m trying to make it so that the player can hang off of walls in the game. I’m having an issue though, I’m not sure how to make it so that the player can hang off of the area that they collided with on the part. I have no solution to this, and have only been making the player’s root part’s CFrame the same as the raycast instance’s CFrame with some offset added.

local char = game.Players.LocalPlayer.Character or game.Players.LocalPlayer.CharacterAdded:Wait()
local humanoid = char:WaitForChild("Humanoid")
local root = char.PrimaryPart

local origion = root.Position
local direction = root.CFrame.LookVector * 1.5

local vizual = Instance.new("Part", workspace)
vizual.Anchored = true
vizual.CFrame = root.CFrame
vizual.CanCollide = false
vizual.Name = "Visualizer"
vizual.BrickColor = BrickColor.random()
vizual.Transparency = .25

local params = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Blacklist
params.IgnoreWater = true
params.FilterDescendantsInstances = {char, vizual}

function nearestNormalId(part, direction)
	local maxDot, maxNormal = 0, nil --Exclude results <= 0
	for _, normalId in ipairs(Enum.NormalId:GetEnumItems()) do
		local normal = part.CFrame:VectorToWorldSpace(Vector3.fromNormalId(normalId))
		local dot = normal:Dot(direction) --Greater the more similar the vectors are
		if dot > 0 and dot > maxDot then
			maxDot = dot
			maxNormal = normal
		end
	end
	return maxNormal
end

game:GetService("RunService").RenderStepped:Connect(function()
	local midpoint = origion + direction/2
	origion = root.CFrame.Position direction = root.CFrame.LookVector * 1.5
	
	vizual.Size = Vector3.new(1, 1, direction.Magnitude)
	vizual.CFrame = CFrame.new(midpoint, origion)
	
	local ray = workspace:Raycast(origion, direction, params)  if ray then
		if ray.Instance ~= nil and ray.Instance.Name == "ledgePart" and root.Position.Y < ray.Instance.Position.Y then
			root.Anchored = true
			
			local normal = nearestNormalId(ray.Instance, direction)
			print(normal)
			
			if normal == Vector3.new(0, 0, -1) then
				root.CFrame = ray.Instance.CFrame - Vector3.new(0, 2.5, -2) 
				
				task.wait(2)
				
				root.Anchored = false
			elseif normal == Vector3.new(0, 0, 1) then
				root.CFrame = ray.Instance.CFrame * CFrame.Angles(0, math.rad(-180), 0) - Vector3.new(0, 2.5, 2)
				
				task.wait(2)

				root.Anchored = false
			elseif normal == Vector3.new(1, 0, 0) then
				root.CFrame = ray.Instance.CFrame * CFrame.Angles(0, math.rad(-90), 0) - Vector3.new(2, 2.5, 0)

				task.wait(2)

				root.Anchored = false
			elseif normal == Vector3.new(-1, 0, 0) then
				root.CFrame = ray.Instance.CFrame * CFrame.Angles(0, math.rad(90), 0) - Vector3.new(-2, 2.5, 0)

				task.wait(2)

				root.Anchored = false
			end
		end
	end
end)

-- CFrame.Angles(0, math.rad(-90), 0)

bump

When they hang should the player be able to shuffle along the edge or just dangle there?

Shuffle, I’m also not sure how to do that either…

you could use a combination of raycasting and setting the character’s CFrame. Here’s a basic example of how you might implement this:

Create a ray that starts from the player’s root part and point forward from the root. This ray will be used to detect when the player is colliding with a wall.

In the player’s “Touched” event, check if the ray has hit anything. If it has, store the hit part’s CFrame.

Create a variable to store the player’s desired CFrame, and set it to be the same as the hit part’s CFrame with an offset added. This offset can be used to position the player so that they are hanging off of the wall.

In the player’s “RenderStepped” event, set the player’s root part’s CFrame to the desired CFrame.

To make the player move along the wall, you can use the mouse or arrow key to change the offset and make the player move up or down the wall.

You may need to tweak the above code to work with your specific game, but this should give you a good starting point.

-OpenAI

I used an AI to answer this question and after reading it I can vouch, this is a good starting point to utilise offsets relative to the part you are climbing and raycasts to determine the exact part/position of the climb.