How to align character to surface normal?

Hello. I’m trying to align the character to the floor he’s standing on, but i have no idea how to do this. I’ve tried looking around the DevForum, but all the solutions i found either just don’t work or make the character jitter like crazy. I’ve also tried asking ChatGPT and the Assistant, but no luck. Here’s what i’m trying so far:

local Params = RaycastParams.new()
Params.FilterType = Enum.RaycastFilterType.Exclude
Params.FilterDescendantsInstances = {Character}
--------------------------------------
RunService.RenderStepped:Connect(function()
    local Raycast = workspace:Raycast(Root.Position, -Root.CFrame.UpVector * 4, Params)
    if Raycast then
        if Raycast.Instance then
            Root.CFrame = CFrame.new(Raycast.Position, Raycast.Position + Raycast.Normal)
        end
    end
end)

But it results in this:

It looks orientation based. Are you trying to allow players to walk up the walls as well? or just have them walk on the ground? If so you can try adding a vector3 value to the CFrame i think?

I’m trying to make the player only align on the floor, not walls or ceilings.

Okay hm, could you try this? I am not home so im unable to boot up studio and verify myself :confused: If i am correct + Vector3.new(0,1,0) should set the rotation to make the character stand upwards. You could also maybe take a browse in roblox’s player movement handler and see how they move their characters if thats accessible im unsure.

local Params = RaycastParams.new()
Params.FilterType = Enum.RaycastFilterType.Exclude
Params.FilterDescendantsInstances = {Character}

RunService.RenderStepped:Connect(function()
    local Raycast = workspace:Raycast(Root.Position, -Root.CFrame.UpVector * 4, Params)
    if Raycast then
        if Raycast.Instance then
            local hitPos = Raycast.Position
            Root.CFrame = CFrame.new(hitPos, hitPos + Vector3.new(0, 1, 0))
        end
    end
end)
1 Like


This is what happens now, very weird behavior.

Ah, well i won’t be much help as i cant use roblox studio to test, Although on the brighter side i did find the core scripts for the Roblox Player check out how the movement is handled, Maybe you can reference this?
– Keyboard Movement

– Master Controller (Handles all player movement positioning)

1 Like

Apologies for the late reply, but i don’t really understand how this can help me with the issue.

Adding the normal to the raycast position at the

Root.CFrame = CFrame.new(Raycast.Position, Raycast.Position + Raycast.Normal)

part is causing the issue

You’re basically telling the character to look at the point where the ray landed plus the normal (which is a vector with a magnitude/length of 1) so it doesn’t change the orientation.

For example let’s say the ray hit at point (100, 100, 100)
and the normal is (0, 1, 0) you’re asking the character to at the raycast hit position at a stud above which is causing the orientation issue

I can’t get on Studio at the moment so I can’t provide any solution to actually fix this issue

1 Like
local RunService = game:GetService("RunService")
local Player = game:GetService("Players").LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Root = Character.PrimaryPart

local Params = RaycastParams.new()
Params.FilterType = Enum.RaycastFilterType.Exclude
Params.FilterDescendantsInstances = {Character}
--------------------------------------
RunService.RenderStepped:Connect(function()
	local Raycast = workspace:Raycast(Root.Position, -Root.CFrame.UpVector * 4, Params)
	if Raycast then
		if Raycast.Instance then
			Root.CFrame = CFrame.lookAt(
				Raycast.Position + Vector3.new(0,3,0),
				Raycast.Position + Vector3.new(0, 3, 0) + Vector3.new(Root.CFrame.LookVector.X, 0, Root.CFrame.LookVector.Z),
				Vector3.new(0, 1, 0)
			)
		end
	end
end)

I was able to get this to work in studio, although the camera is jittery. It aligns the character to the surface. The camera is jittery because it is attached to the player’s character, and its constantly updating the player’s character. If you want i can try and fix this so it doesn’t look as jittery but the player is unable to jump as well.

1 Like

Thanks, and you’re right, the camera is jittery. But the character CAN jump but for some reason isn’t aligning to the surface still.

You can smooth it out using Lerp. Also, consider using a 60Hz loop using
while true do foo() task.wait(1/60) end

Ah i see what you want., let me see if i can mock up a mini area like yours, I was able to jump but not get off the ground only sometimes, but judging by you have a custom jumping i assume that’s why you are able to get off the ground. I never tried something like this so hopefully i can get it.

Yeah but it’s not a custom jump, it’s the regular roblox one.

Where do i put that?

charlimit

Hey, i was just browsing seeing anything else have you ever looked at this? Is this what you want to achieve?

Nah, basically what i wanna do is this:

Like, the humanoidrootpart tilts according to the surface it’s on (as well as the whole body), no momentum gain or physics stuff or whatever. If what the player’s trying to climb up is out of the raycast’s range, then it shouldn’t let him tilt, simple

1 Like