How would I rotate a skinned mesh character based on a slope?

I am creating a game that uses skinned meshes. The starter character is small and light so I thought of adding “slope rotation” to him.

It is hard to find any posts that have a good solution to this.
I know this might be a crude drawing but it is a good enough example.

I’ve tried casting a ray down and using the normal to rotate the character. The character usually either vibrates(glitchy) or faces a completely different direction.

Another solution I found worked in a 2d game I’ve also created. But unsurprisingly it does not work in 3d.

I’ve also tried solutions other people have given, however, none of them work usually due to it being a skinned mesh and all.

local speedy = 0
local hrp = script.Parent.HumanoidRootPart
hrp.CFrame *=,50,0)
local uis = game:GetService("UserInputService")
local speedxz = 0
local onground = false
local dnray,dnray2
local dvector = hrp.CFrame.UpVector*-2.8
local movedir = Vector3.zAxis
local function ray(origin:Vector3,dir:Vector3,filtertype:Enum.RaycastFilterType,filter,ignorewater:boolean)
	local rcp =
	rcp.FilterType = filtertype
	rcp.FilterDescendantsInstances = filter
	rcp.IgnoreWater = ignorewater
	return workspace:Raycast(origin,dir,rcp)
local function getRotationBetween(u, v, axis) --thanks, dthecoolest!
	local dot, uxv = u:Dot(v), u:Cross(v)
	if (dot < -0.99999) then return CFrame.fromAxisAngle(axis, math.pi) end
	return, 0, 0, uxv.x, uxv.y, uxv.z, 1 + dot)
	speedy -= .5
	hrp.CFrame *=,speedy/10,0)
	onground = false
	if ray(hrp.Position,dvector,Enum.RaycastFilterType.Blacklist,{script.Parent},true)then
			hrp.CFrame *=,.05,0)
			dnray2 = ray(hrp.Position,dvector,Enum.RaycastFilterType.Blacklist,{script.Parent},true)
			dnray = dnray2 or dnray
		until not dnray2
		hrp.CFrame = hrp.CFrame:Lerp(hrp.CFrame*getRotationBetween(hrp.CFrame.UpVector,dnray.Normal,movedir),.1)
		onground = true
		speedy = 0
	dvector = hrp.CFrame.UpVector*-2.8
	if not onground then
		hrp.CFrame = hrp.CFrame:Lerp(CFrame.lookAt(hrp.Position,hrp.Position+movedir),.4)

	if uis:IsKeyDown(Enum.KeyCode.Space)and onground then
		speedy = 11
	if uis:IsKeyDown(Enum.KeyCode.E)then
		speedy = 0
		speedxz = 0
		hrp.CFrame = workspace.SpawnLocation.CFrame *,10,0)
	if script.Parent.Humanoid.MoveDirection ~= then
		movedir = script.Parent.Humanoid.MoveDirection
		if onground then
			hrp.CFrame = hrp.CFrame:Lerp(CFrame.lookAt(hrp.Position,hrp.Position+script.Parent.Humanoid.MoveDirection)*getRotationBetween(hrp.CFrame.UpVector,dnray.Normal,hrp.CFrame.LookVector),.4)
			hrp.CFrame = hrp.CFrame:Lerp(CFrame.lookAt(hrp.Position,hrp.Position+script.Parent.Humanoid.MoveDirection),.4)
		speedxz += onground and .1 or .02
	speedxz *= onground and .8 or .95
	hrp.CFrame *=,0,-speedxz)

Here’s a video of what that looks like:

A good example of what a game with slope rotation looks like would be Sonic Speed Simulator.


@Prvqx it looks perfect to me mate it has no issues don’t worry about it

1 Like

It clearly looks broken, especially compared to another game with slope rotation. While moving, the character is only half-rotated, and on another slope, it’s rotated differently than it should. It’s very glitchy, and the player doesn’t even rotate when walking down the slope.


@Prvqx yea mate your right the code is differently broken but I think just redo it and see how it goes like change it a little bit add something else in

1 Like

The thing is that I don’t know what exactly to code since I don’t have any solutions.
henceforth, why I posted here.

1 Like

Look, I appreciate you trying to help me but I opened this thread for me to get help on this specific situation. If I found a solution from a tutorial or somewhere else I wouldn’t have posted.

1 Like