# Rotating on a slanted surface?

I want to rotate (change it's yaw) an object when its sitting on slanted ground. Pretty much I want to rotate around the ground's normal.

Right now I ray cast down, get the ground's normal. Then I do:

Tick(deltaTime)
{
Quaternion rotationDelta = QuatFromAxisAngle(groundNormal, rotationRate * deltaTime);
ObjectRotation = rotationDelta * ObjectRotation;
}


But this isn't giving me quite the right results. Any suggestions?

Before Rotation:

A rotation of 90 degrees:

• What's not quite right about the results you're getting now? – DMGregory Apr 6 '19 at 21:32
• @DMGregory not sure how to describe it. It is not rotating around the axes of the the ground normal. It is rotating, but lets say I rotate on a slope 90 degrees, the object will be not be flush with the ground like it was at the start, but instead it will be properly yawed but incorrectly rolled. – Dan Apr 6 '19 at 21:39
• Sounds like pictures or an animation might help make this problem clearer. – DMGregory Apr 6 '19 at 21:39
• Okay I'll submit some. – Dan Apr 6 '19 at 21:41
• Can you please post more of your code? Preferrably the part where you get groundnormal. I'm also thinking that maybe something is wrong with the collisions - is it possible that your raycasts hits something else than the ground itself? – lilKriT Apr 7 '19 at 20:38

I think you should do this:

1. Find where the object "hits" the ground
2. Find the normal of that hit
3. Rotate around the normal

If you need explanation on how to do any of that, I will try to help :)

• It looks like OP is already doing that here, no? QuatFromAxisAngle(groundNormal, rotationRate * deltaTime); – DMGregory Apr 7 '19 at 13:40
• Good point. I should be more specific - there's no code of the raycasts etc, so maybe there's something wrong with them. – lilKriT Apr 7 '19 at 20:36
• I meant to imply that I did the ray cast already. That is not my issue, as im almost certain the ground normal I have is correct. I was looking for a sanity check on my mathematics. – Dan Apr 7 '19 at 23:41
• In the second image, the pink ray is a debug line in the direction of the ground normal. – Dan Apr 7 '19 at 23:42

You could try rotating the object in its local space or change its local rotation

for example, Here, assume the brown plane is the ground and the cube is the artillary.

In the second image I have rotated the cube around 90 degree in its local space so that might be the solution for you

I have used the following code for the test

public class Test : MonoBehaviour
{
private Vector3 rotationVector;

private void Start()
{
rotationVector = new Vector3(0f, 5f, 0f); // I am rotating in Y
//because Y is the up Vector for the cube
}

private void Update()
{

if (Input.GetKeyDown(KeyCode.A))
{
transform.Rotate(rotationVector, Space.Self);
}
if (Input.GetKeyDown(KeyCode.D))
{
transform.Rotate(-rotationVector, Space.Self);
}

}
}