Raycasting Tangents(Parallel to surface)

Hello there. I just want to ask a small question of finding tangents using ray casting. The reason why I want to do this is because I want to find a way to get a part parallel to the surface that it is on.

For example.

I know that getting tangents from a raycast is impossible but I want to know if there is a way to get an Orientation that aligns the part parallel to the surface so that the downVector is perpendicular to the surface. I have tried to use the cross and dot product to find a vector that is perpendicular to the normal but I do not know how to turn it into an orientation.

I am trying to create a custom controller for a sort of wall stick for my character. But I need to know how to align the characters root part to the surface it is on.

Thanks for reading.

2 Likes

This is not true, since a RaycastResult yields a normal.

Could you elaborate what you are trying to do exactly (maybe show some code or something)?

I know that you can get a normal from a raycast however I need a way to convert that directional vector into an orientation. I want the part to be level with the ground below.

I am not entirely sure how to explain this. The normal vector that I keep getting is a vector perpendicular to the surface when I need an orientation which is parallel to the surface…Do you know how I could do this?

If you are still not sure I will make a short clip.

https://gyazo.com/008cc0d99a93bb95b5daf1f0b2cdb185

https://gyazo.com/95052717f32b721b5d2fc1a602cd79b1

You can see that when I drag a part onto a surface, the part automatically orientates itself so that it is parallel to the surface. I wish to do this with code.

Let raycastResult and part be defined:

local origin = raycastResult.Position + raycastResult.Normal * part.Size.y / 2
part.CFrame = CFrame.new(
    origin,
    -- Make the rotation align with the normal
    origin + raycastResult.Normal
)

I guess this sort of works. But, I have figured this out myself already. I already know how to set the orientation to the normal but I do not want that. I want it to be set to the tangent.

So you want your part to be rotated?

Yes. Exactly. I only want to rotate the part so that it is parallel to the ground. You should be able to see what I would like in the pictures I draw above but in 3d space… I do not know enough about the orientation of roblox to come up with a formula for this.

To be honest I am sorry I probably didn’t draw the picture clear enough I will post another picture instead

The arrows represent the forward directions of the part

I know how to do this in 2d space but in 3d I have no idea.

The problem arises is that there is 2 choices of a forward vector if I place a part parallel to the ground whereas in 2d space there is only one. I have no idea how to work around this. If I decide to set it to the X axis then the Z axis is not accurate and vice versa. If I set it to the Y axis then that would orient the part looking to the sky which I DO NOT want.

I have tried to change the XYZ values directly but it still seems to not work.

I think the problem with using CFrame .new is that if I do set the part to the look vector I cannot directly orient it properly left to right. If you understand what I mean. If you don’t I can probable show you another clip.

This is the parts “choice” of two vectors. If I use CFrame to look at the direction I want it to face in I cannot control the rotation.

I would like to know if there is a way to do this.

Hold on I have found a workaround. I will use two CFrames I will be able to select both of the directions and combine the orientation. No need to reply thanks for helping me though.

1 Like

I’m trying to do something similar, could you please expand on how you achieved this?

Ah sure!

There are a few workarounds that I found out to be very interesting.

The solution I described above does work however it is very innefficient so this one is better.

This is the code that I used.

local XaxisAngle = math.atan2(raycastNormal.Z,raycastNormal.Y)
local ZaxisAngle = math.atan2(raycastNormal.X,raycastNormal.Y)
		
HRP.CFrame = CFrame.new(raycastPosition + (raycastNormal*LevelHeight)) *  CFrame.Angles(XaxisAngle,0,ZaxisAngle) 

And the result :upside_down_face:
https://gyazo.com/fa474f7228ac4b913b07cb4a0f5d416c
https://gyazo.com/b3e88429b6215417c3b164b4f803b5a6

There is another way that I found out to also be very interesting but I haven’t made the code for it yet.
So I will just stick some Pseudocode instead.#

SET height TO 10
SET Part TO Parent
UPDATE every frame before physics
for startingPositions do
RAYCAST from startingPosition
GET raycastNormal and raycastPosition
STORE TargetCFrame PROCCESS CFrameLookAt raycastPosition + (raycastNormal * height) , Part.Position + raycastNormal
--[[The line above is the code that I used. however there is an option for a third parameter in CFrame.lookAt which is the upVector() So..If we set the upvector to the OPPOSITE 
of the direction we want the part to face in then we just have to rotate the CFrame downwards RELATIVE TO ITSELF so that the look at where we want it to go to.]]
ROTATE TargetCFrame CFrameAngles 0,0,90
PROCCESS Part SET CFRAME TO PART TargetCFrame

Again CFrame.lookAt takes in 3 Parameter actually and the third one I had no idea existed until a few days ago.I use that parameter to set which way the part will face when it is horizontal

Hopefully you understand if you don’t I will post it here once I finish the code. for this method

6 Likes