The way the cross product works is it returns a vector perpendicular to the two you put in. So, you have the normal of the terrain, which is going kind of sideways-and-up. Then you have the Up vector which is
Vector3.new(0,1,0). Using right-hand rule we know that the resultant, which is facing stage right (of the video). The model will always face left on the hill because you are crossing with the up vector.
Here’s my suggestion: instead of crossing against the up vector, you cross against the orientation of the model itself. This will give you the best approximation of the model’s CFrame while making its Up direction face the direction of the hill.
You can do this by creating 3 orthagonal vectors, Binormal, Normal, and Tangent – the X, Y, and Z axis respectively – and create a CFrame out of those component vectors (plus position). To do that, you can use two cross products.
Stage 1: cross PrimaryPartCFrame.rightVector with raycast Normal. This produces the Tangent
Stage 2: cross raycast Normal with Tangent to create the Binormal
You can then create a CFrame with the components of these vectors plus position components, like so:
CFrame.new(Position.X, Position.Y, Position.Z, Binormal.X, Normal.X, Tangent.X, Binormal.Y, Normal.Y, Tangent.Y, Binormal.Z, Normal.Z, Tangent.Z)