How to align part to surface normal

this solution is bad and this post should be removed.

If you are looking for a better solution head here: Aligning Object to Surface using CFrame:fromMatrix()

I believe that the HumanoidRootPart doesn’t actually change direction, so if you want to know where the player is looking at, you should get the lookVector of the torso instead.

Getting the MoveDirection property of the humanoid also might work, since it updates even if the humanoid isn’t actually moving (even if you set the walkspeed to 0, it will still update according to user input)

how is the arrow attached to the humanoid?

and the test part’s can collide is turned off right?

yeah, its anchored, collisions disabled, massless and transparency 0.5

also about the arrow part not looking the same way the humanoid is thing, why not just do like

testpart.CFrame = humanoidRootPart.CFrame + Vector3.new(0, 2, 0);

I’m confused, what is the end goal here? it seems like the sliding is working, and the arrow part looks like it’s just a visualisation of whatever

As i said, i wanna align the player to the ground’s normal but save its look vector so that he will be aligned in the direction he is sliding, e.g. he wouldnt slide backward

the “visualization part” is aligned to normal of the ground but its look vector isnt the same as humanoid root part so even when player rotate, the part is still in the same X axis

the second thing is when i update the HumanoidRootPart cframe , player will fly

If you want to get the CFrame pointing downards of a slope you can use cross product.

However keep in mind this only works if the slope is uneven and not perfectly flat or else the cross product will fail.

local char = script.Parent

local HRP = char:WaitForChild("HumanoidRootPart")

local part =Instance.new("Part")
part.Anchored = true
part.Size = Vector3.new(2,1,5)
part.CanCollide = false
part.Parent = workspace
part.FrontSurface = Enum.SurfaceType.Motor

local downVector = -Vector3.yAxis

local rayParams = RaycastParams.new()
rayParams.FilterDescendantsInstances = {char}
while true do
	task.wait()
	local ray = workspace:Raycast(part.Position, Vector3.new(0,-1000,0), rayParams)
	local upVector = Vector3.yAxis
	if ray then
		upVector = ray.Normal
	end
	local rightVector = downVector:Cross(upVector)
	
	part.CFrame = CFrame.fromMatrix(HRP.Position+Vector3.yAxis*5,rightVector,upVector)
end

This is because of this

cache.goal = CFrame.new(class.humanoidRootPart.Position, cache.lookVector)
samething as 
cache.goal = CFrame.new(class.humanoidRootPart.Position, position + cache.raycastResult)

This will make the character LookVector, look at the sky or surface normal and turn the char 90 degrees on the x Axis which will confuse the humanoid which wants to turn back “Upright” using physics and fly.

is the sliding mechanism not finished?

have you tried setting the Humanoid max slope angle to 0?

no, but im trying to align Part/HumanoidRootPart , facing the slope up/down but with humanoidRootPart look vector

So that player can slide in 2 directions, up and down

what? what does that mean? could you explain in more simple words?

For the second one set state doesn’t matter I the force occurs always unless in sitting state, or physics state or platform stand. Basically when the humanoid isn’t exerting force.

If you want to only align the normal vector you can use this method.

This allows for other rotation along the local normal vector.

Either way with any method you will definitely need to add on and use AssemblyLinearVelocity vector to align with the sliding direction, I’ll leave this up to you.

okay I think I get what you’re trying to do here now, so you haven’t done the acceleration yet?

in that case it seems easier so just make a part and give it a velocity and attach the character to that part and then set the cframe of the root part to CFrame.lookAt(Vector3.new(0, 0, 0), part.AssemblyLinerVelocity);