How do I align the player to the slope?

I would like the player’s orientation to align with the slope.

Adding -90 to the lookpart’s X and Y orientation to the player messes up the players orientation

I have tried messing with the lookpart’s X and Z orientations, but to no avail.

image
This is how the lookPart looks when not on a slope.
(The hinge shows where the front of the lookPart is)


This is how I want the lookPart to face when on a slope.

Instead, it faces 90 degrees to the left on the slope:

If anyone can help, it would be greatly appreciated.

NOTE: This script is made with the Juke's Towers of Hell 5.5 kit in mind.

local ts = game:GetService'TweenService'

return function ()
	local plr = game.Players.LocalPlayer
	local char = plr.Character
	
	wait()
	
	local torso = game.Players.LocalPlayer.Character:FindFirstChild("Torso")
	
	local attach = Instance.new("Attachment", torso)
	local vectorf1 = Instance.new("VectorForce", attach)
	local vectorf2 = Instance.new("VectorForce", attach)
	
	attach.Orientation = Vector3.new(0,0,90)
	
	vectorf1.Force = Vector3.new(0,torso.AssemblyMass * workspace.Gravity,0)
	vectorf1.Attachment0 = attach
	vectorf1.RelativeTo = "World"
	vectorf1.Enabled = false
	vectorf1.Name = "GravityCounteract"
	
	vectorf2.Force = Vector3.zero
	vectorf2.Attachment0 = attach
	vectorf2.RelativeTo = "Attachment0"
	vectorf2.Enabled = false
	
	local params = RaycastParams.new()
	params.FilterType = Enum.RaycastFilterType.Include
	params.FilterDescendantsInstances = {script.Parent}
	
	local playerholder = Instance.new("Part", game.Players.LocalPlayer.Character)
	playerholder.Size = Vector3.one
	playerholder.Shape = "Ball"
	playerholder.CFrame = torso.CFrame * CFrame.new(0, -2.5, 0)
	playerholder.CanCollide = false
	
	local phWeld = Instance.new("WeldConstraint", playerholder)
	phWeld.Part0 = playerholder
	phWeld.Part1 = torso
	
	local lookPart = Instance.new("Part", game.Players.LocalPlayer.Character)
	lookPart.Anchored = true
	lookPart.CanCollide = false
	lookPart.Size = Vector3.new(2,2,1)
	lookPart.FrontSurface = "Hinge"
	
	local ph2 = Instance.new("Part", char)
	ph2.Size = Vector3.new(3, 0.4, 3)
	
	local hrp = game.Players.LocalPlayer.Character:FindFirstChild("HumanoidRootPart")
	local joint = hrp.RootJoint
		
	spawn(function()
		local rsLoop = game:GetService'RunService'.RenderStepped:Connect(function()
			local result = workspace:Raycast(torso.Position, torso.CFrame.UpVector * -3, params)
			if result then
				vectorf1.Enabled = true
				vectorf2.Enabled = true
				lookPart.CFrame = CFrame.lookAt(result.Position, result.Position + result.Normal) * CFrame.Angles(math.rad(-90), math.rad(-90), 0)
				vectorf2.Force = Vector3.new(0 -((workspace.Gravity * torso.AssemblyMass) * 2), 0)
			end
		end)
	end)
end

I believe this is what you are looking for:

The game is open-sourced, so you can view & use the code as needed! :slight_smile:

I was looking for something similar, but simpler script wise.

I see…

The caveat here is that the design of Rthro characters is explicitly built for upright travel, and to create adaptation to sloped travel requires adjustments to the character controller and the camera for smooth gameplay.

In what ways are you looking for it to be simplified?

the system is supposed to work with r6, and i would only like for it to only affect a folder of parts.

If this is all you are looking to do, I recommend casting a ray against the floor, then calculating the normal using:

local raycastResult = workspace:Raycast(rayOrigin, rayDirection)
local rayNormal = raycastResult.Normal

From here, you can take the cross product with the right vector (right hand rule) to align the parts parallel to the surface normal.

local rayResult = raycastResult.Instance
local parallelOrientation = rayNormal:Cross(rayResult.CFrame.RightVector)