Using raycast normal

How can i get the correct orientation values of based off of a normal vector, as in being able to calculate the correct x y and z orientation to set to when a part is at an angle
like this;
an example of part being on a slant


example of part being turned while on slant correctly

I do not have any working code i would love for some help on this issue.

I don’t remember what orientation is relative to but I think it’s just the worldspace vectors. So just go through every axis vector and get their angle (remember that if dot product is equivalent to the product of the magnitudes times cos(k) then if they are unit vectors it is just what equals the cos(k) and itself in other words it is the inverse cosine of the dot product of them) remember to put a negative sign in the orientation or it will make it wrong

1 Like

You can use CFrame.lookAt for making a part face the direction of the ray result, then apply respective offsets if the part is flipped, tilted, and so on.

local cframe = CFrame.lookAt(rayresult.Position, rayresult.Position + rayresult.Normal)
cframe *= CFrame.fromOrientation(math.pi/2, 0, 0) -- example: flip by 90 degs
cframe *= CFrame.new(0, 0, -size.Z/2) -- example: move forwards by half its z size (to not clip in the surface)

You might have to experiment a little, but this is really all you need.

1 Like

How can i get the orientation from this?

1 Like

If you insist on getting the orientation, which you don’t need, you can call :ToOrientation on the CFrame to get the orientational x, y, and z value then convert them to degrees like so:

local cframe = CFrame.lookAt(rayresult.Position, rayresult.Position + rayresult.Normal)
local radx, rady, radz = cframe:ToOrientation()
local orientation = Vector3.new(math.deg(radx), math.deg(rady), math.deg(radz))
1 Like

i need the orientation to be able to put into a balance controller im trying to make that uses a pid and i want to be able to make the the orientation the setpoint on the pid and use the humanoidrootpart orientation as the processvalue

1 Like

hey this is giving me numbers like 90, 90, 0 why is that?

1 Like

It means that the normal is facing straight up and is perpendicular to the ground.

1 Like

also i was under the presumption that the cframe stuff would make it be able to move around flat in context to the surface but it appears that it only does that one direction like this

1 Like

Didn’t understand your question , do you want to align the part to the surface?

1 Like

yeah and to be able to rotate around with it still being flat to the surface

1 Like

What happens exactly when you try to do this?

1 Like

i sent a diagram kind of thing, it doesnt know which way the part is facing so if it goes 180 degrees it doesnt try and go negative

1 Like

I don’t get what you’re illustrating, could you elaborate?

1 Like

so this being an example of a part on a slope


this is what it would like like if it was 90 degrees to the right
and here a full 180

what im saying is instead of doing the correct orientation it is trying to do positive 15 degrees instead of the proper -15
so it ends up something like this

1 Like

Ah, that’s because of how you apply the rotation offset. You’d want to apply the rotation to the CFrame before it’s converted to a Vector3 orientation.

local cframe = ...
cframe *= CFrame.fromOrientation(0, math.pi, 0) -- +180 degs
...
1 Like

is cframe *= CFrame.fromOrientation(0, math.pi, 0) the same as cframe = cframe * CFrame.fromOrientation(0, math.pi, 0)

1 Like

how can i apply the rotation at runtime

1 Like

You simply convert the CFrame when the rotation changes.

function ApplyRotation(cf, rady)
    cf *= CFrame.fromOrientation(0, rady, 0)
    local radx, rady, radz = cf:ToOrientation()
    local orientation = Vector3.new(math.deg(radx), math.deg(rady), math.deg(radz))
    return orientation
end

local cframe = CFrame.lookAt(rayresult.Position, rayresult.Position + rayresult.Normal)
local orientation = ApplyRotation(cframe, math.pi)

Yes.

1 Like

why wont this work?

cframe *= CFrame.fromOrientation(0, math.pi, 0)+ Vector3.new(0,hrp.Orientation.Y,0)

i cant just + by hrp.Orientation.Y cause it needs a vector3

1 Like