CFrame from normal

When using the findpartonray, I get the position and normal of where the ray hits

If I wanted to make a CFrame on this position, how would I calculate in the normal?

also, once I do get the cframe of an object with the normal of the surface its ‘stuck to’ calculated, what if I wanted to rotate the object around its local space y axis, how would that factor into the cframe?

Thanks.

I think what I am asking is… how would I create a cframe where the upVector is pointing in the same direction of the normal.

1 Like
local _,hitPos,hitNormal,_ = workspace:FindPartOnRay(...)

local hitCFrame = CFrame.new(hitPos, hitPos+hitNormal)

This will create a CFrame from the hit position/normal with the frontVector aligned to the hit normal. If you want the upVector aligned, you can rotate the CFrame by 90 degrees on the Y axis.

17 Likes

Awesome, thanks, I had to do it -90 deg on the X axis, but yeah, it worked, thanks :slight_smile:

2 Likes

i’ve been working countless hours on a bodygyro to keep a bike standing upright along it’s Z or roll axis.

A thing i’ve learned about adding a CFrame.new(hitPos, hitPos+hitNormal) is that it’s relative to the world space so it’s going to point in 1 direction but the orientation won’t be the same as the orientation as the bike that needs to go in different spaces.

I think this can be solved with the new CFrame.lookAt, since it allows you to specify an ‘up’ vector.

CFrame.lookAt ( Vector3 at, Vector3 lookAt, Vector3 up = Vector3.new(0, 1, 0) )
Creates a new CFrame located at at and facing towards lookAt , optionally specifying the upward direction (by default, (0, 1, 0)).

This function replaces the CFrame.new(Vector3, Vector3) constructor (see above) which accomplished a similar task. This function allows you to specify the up Vector, using the same default as the old constructor.

2 Likes

Hello echo Reaper I have been working on an engine and I have not found out yet how to do the slope alignment but sense I have found this thread it has helped tremendously so I first wanna just say thanks for giving the solution for this CFrame normal thing. now for the second thing I need some help on turning this into something that only affects the X,Z axis and no other axis’s if you could help me out on this it would be very help full for me and I would be heavily grateful.

If you want it to not affect the Y axis, then you can just manually put in the numbers like so:

-- first I would use workspace:Raycast as :FindPartOnRay is deprecated
local result = workspace:Raycast(...)
if result then
    local hitPos = result.Position
    local hitNormal = result.Normal
    -- remove the Y axis from the position
    local pos = Vector3.new(hitPos.X, 0, hitPos.Z)
    local hitCF = CFrame.lookAt(pos, pos+hitNormal)
end

local hitCFrame = CFrame.lookAt(hitPos, hitPos+hitNormal)
1 Like

Like this firecestnewt?

pos = Vector3.new(result.Position.X, 0, result.Position.Z)
root.CFrame = CFrame.lookAt(pos, pos+result.Normal)

Well, it depends on what exactly you want, but based on what I got out of your question, that should work. That will cause the Y axis of the position to not be changed at all.

oh dang then how would I make it to that the Y axis of the rotation of the part will not change FiercestNewt

if you can help me with trying to achieve that

Do you mean rotation along the Y axis? Like in the video below?

Then this should work also an alternative method for this topic: