basically i figured out how to rotate around that weird axis (but i don’t know where to rotate it to to make it finally relative! )

local normalCFrame = CFrame.lookAt(hitPosition, hitPosition + normal)
local _rotation: CFrame = rotation
if relativeRotation then
local rotationRelativeToTarget: CFrame = CFrame.fromAxisAngle(normal, math.rad(abc)) * normalCFrame
_rotation = (rotationRelativeToTarget - rotationRelativeToTarget.Position)
end

local rotation = CFrame.Angles(math.atan2(-normal.Y, normal.X), math.asin(normal.Z), 0)
local translation = CFrame.new(position) -- position is the part's position you want to make it relative to
part.CFrame = translation * rotation

So I ain’t even that good at trigo but I think it should work.

Basically it’s 12:30am here so I can’t open my pc.

I don’t think so because each time you want to place a part on the surface exactly aligned with the part you’re placing it on you have to get real finnicky and exactly get the rotation right

And I think that for my game that’s going to be a big no-no

I think this post has the info. But I think this post has some cases which is only applicable to character like RightVector of the HumanoidRootPart is always perpendicular to SurfaceNormal.

Hey, this is almost working! Like i explained earlier, but now on two sides it doesn’t work because then the normal is parallel to the rightvector of the part. Have a look at the code. And the rotation was relative!

if relativeRotation then
-- makes it so the RightVector and UpVector run parellel to the surface and LookVector = surface normal
--local EXTRASPIN = CFrame.fromEulerAnglesXYZ(math.pi/2, 0, 0)
--local EXTRASPIN = CFrame.fromEulerAnglesXYZ(math.pi/2, 0, 0)
--_rotation = --getRotationBetween(Vector3.new(0, 1, 0), normal , Vector3.new(0,0, 1)) * EXTRASPIN
_rotation = CFrame.fromMatrix(
Vector3.new(), -- POSITION OF THE OBJECT
-normal:Cross(target.CFrame.RightVector), -- LOOKVECTOR
target.CFrame.RightVector, --RIGHTVECTOR
normal --UPVECTOR
)
end

I think there’s a lot of methods you can do this, so I’m just trying to understand the specific scenario. The method I personally use for getting an object to be aligned upward given the vector normal is:

local result : RaycastResult
local normal : Vector3
local relative_vector = Vector3.yAxis -- This makes it so it's similar to a user's camera
local right_vector = normal:Cross(relative_vector)
local look_vector = right_vector:Cross(normal)
local object_size : Vector3
local cframe = CFrame.fromMatrix(
result.Position + (normal * object_size.Y * 0.5),
right_vector,
normal,
-look_vector
)

okay, so this is the problem i’m having.
when on a part with a rotation on one axis, all is well. But if on two or more axes rotated it doesn’t work anymore

Plus I think the primary caveat to trying to do what you are trying is when you add a mesh or abnormal surface like a sphere (not cylinder) it’ll be very weird. My initial thought to completing this is to compare the orientation of the object which the raycast result returned and see the difference in the yAxis so then you can orientate the object by that amount; I haven’t done this myself yet so I don’t know how it’ll look.

That’s alright, I haven’t done it before so I’m running through some tests before I let you know precisely how it could be done (not saying it will be pretty or good).

Alright, so this is a bit wonky and it could definitely been done better but hopefully this satisfies what you’ll use it for.

totally not copy pasting some of code I sent here

local result : RaycastResult
local normal : Vector3
local relative_vector = Vector3.yAxis -- This makes it so it's similar to a user's camera
-- // As far as I know, this might not look pretty with mesh parts
-- // Also checking because I think result.Instance could be terrain
-- // I do not apologize for my use of ternaries
if (result.Instance and result.Instance:IsA("BasePart")) then
local result_cframe = result.Instance.CFrame
relative_vector = result_cframe.UpVector ~= result.Normal and result_cframe.UpVector or result_cframe.RightVector
end
local right_vector = normal:Cross(relative_vector)
local look_vector = right_vector:Cross(normal)
local object_size : Vector3
local cframe = CFrame.fromMatrix(
result.Position + (normal * object_size.Y * 0.5),
right_vector,
normal,
-look_vector
)

Oh my, when I wrote this I accidentally deleted the if statement and the local variable to turn it into a ternary; It’s local result_cframe = result.Instance.CFrame

Oh my god. You actually f#@^$ng did it
Okay, it works, but could you please tell me what
result_cframe.UpVector ~= result.Normal and result_cframe.UpVector or result_cframe.RightVector
means? I have never seen a CFrame operated on by boolean operations. how does that work?