How to Reorient Npc with ground using raycast?

So,I have a mount on my game where you can ride it and I want to make my mount Orientate with the ground like this:
IWantThis
I read some articles and tried some sollutions but none worked, so, I tried to make a code to see if it worked but turns out Im no good with CFrames, my mount did this:
tilted

Here’s my code

    local rayDirection = Vector3.new(0,-10,0)
   	local ray1result = workspace:Raycast(mount.Head.Position,rayDirection,RayParams)
	local ray2result = workspace:Raycast(mount.RayPart2.Position,rayDirection,RayParams)

     if ray1result and ray2result then
		local PrimaryPart = mount.PrimaryPart
		PrimaryPart.Orientation = Vector3.new(math.deg(math.atan2(ray1result.Position.Y,ray2result.Position.X)),0,0)
	 end

So this script basically makes 2 rays to hit the ground and then I TRIED to get the angle of the two ray positions to orientate the primarypart.

I tried using atan2, but seems like I couldn’t figure it out, but it was my last hope since I did not find anything useful on other articles or tutorials. I absolutely do not know how to make this mount(npc) orientate relatively with the ground, if anyone could help me I would be greatful.

1 Like

RayResult has a field called Normal which tells the surface direction of the surface hit by the ray. You can use this as the Up parameter to CFrame.lookAt, using the NPCs current direction as the other input, for example:

npc.CFrame = CFrame.lookAt(Vector3.zero, npcDirection, rayResult.Normal)

npcDirection can be any direction vector that is suitable, such as the root part times -Z. For stability, you should prefer to use some direction not derived from the current CFrame (such as a direction dictated by the NPCs control script), otherwise you might get oscillations.

Don’t use inverse trig or orienting things, for this reason excerpted from a paper I wrote:

Trigonometry deals with circles. Circles are two dimensional. If you convert a 3D problem into trigonometry, you are throwing away part of the information required to solve the problem and it may be extremely difficult to get back. Inverse trigonometry may not even give you a real answer and thus requires extra checks to make sure it is being used correctly.

Trigonometry can also be used to solve right triangles.

You can still apply trigonometry to solve 3d problems.

Im not trying to be mean but why have you posted this reply?

No offense, but I just felt like the end of your post was a bit misleading.

Inverse trig and the Orientation property have historically been a “noob trap”, as is the case here. This is why I would discourage their use outside of a really simple 2D problem like measuring minumum angle between vectors. I know that Dot and Cross have trig definitions for vectors in general.

1 Like

the way i’d tackle this problem is by casting a ray downwards, getting the normal of the part it intersects with and create a CFrame orienting the part looking at it and offset it by a rotational amount to face forward. before setting the CFrame of the part, log its current local Y orientation so you can do math to figure out what its orientation should be on the Y axis.

So I did not understand the npcDirection part and I set the npcDirection variable to PrimaryPart.CFrame.LookVector but it causes the mount to look at random directions and sometimes spin randomly.

Can you show how you did this?

local NpcDirection = PrimaryPart.CFrame.LookVector
PrimaryPart.CFrame = CFrame.lookAt(PrimaryPart.Position,NpcDirection,ray1result.Normal)

Should be
PrimaryPart.CFrame = CFrame.lookAt(PrimaryPart.Position, PrimaryPart.Position + NpcDirection, ray1result.Normal)

slighlty
So the code is somewhat working, it doesnt rotate 100%, what sould I do? make it PrimaryPart.Position + NpcDirection * 2??
–NpcDirection * 2 did not work I tested
Also getting the front normal of the PrimaryPart and putting it as the NpcDirection has the same effect

Agreed trigonometry is a bit difficult in 3d space especially when the axis of rotation keeps changing,

I recommend this Quaternion solution, although difficult to understand you can just use @EgoMoose formula which has been ported to Roblox which works great, also there is a CFrame.fromAxisAngle version which is more understandable:

yoooo, I tried using your solution earlier but it did not work.