Calculate new rotation for an object along two axis

I have a cube that I want to rotate. I want to randomly calculate a new rotation for the cube and slerp to the new rotation. I want to be able to rotate it around the y and x axis but I don’t want it to rotate around the z axis.

Here is the code I tried to use for this purpose but it seems to rotate along only the z axis even though my “newRotation” vector3 has a z value that never changes. I’m sure this is just something about Quaternion rotation that I don’t understand, please help! :slight_smile:

private void slowMove()
{
    // if we're in our origin rotation, then pick a new random rotation
    // x +/- 90 degrees, y +/- 90 degrees and z +/- 90 degrees from our
    // current rotation
    float rotationVariance = 90;

    var newRotation = new Vector3(_originalRotation.x + UnityEngine.Random.Range(rotationVariance * -1, rotationVariance), _originalRotation.y + UnityEngine.Random.Range(rotationVariance * -1, rotationVariance), _originalRotation.z);

    _toRotation = Quaternion.FromToRotation(_originalRotation.eulerAngles, newRotation);

    //UnityEngine.Random.rotation;
}

void Update()
{
    if (_toRotation != null)
    {
        // slowly move to our new rotation over time
        transform.rotation = Quaternion.Slerp(transform.rotation, _toRotation.Value, Mathf.Clamp01(Time.deltaTime * 10));

        // until the difference in angle between our current rotation and
        // our destination rotation is < 1
        if (Quaternion.Angle(transform.rotation, _toRotation.Value) < 1)
        {
            _toRotation = null;
        }
    }
}

Here’s an ani gif showing the rotation. Each time it rotates again it’s after I have clicked it.

As you can see it’s only rotating on the z axis for some reason even though the z value should not be changing.

Change your _toRotation to a Vector3 and set it to the new rotation vector. Use Vector3.RotateTowards(or Vector3.Slerp) instead of Quaternion.Slerp and then update transform.rotation with Quaternion.Euler.

BOOM! That worked, thanks! My final code if anyone is interested.

private void slowMove()
{
    // if we're in our origin rotation, then pick a new random rotation
    // x +/- ? degrees and y +/- ? degrees from our current rotation
    float rotationVariance = 45;

    _toRotation = Quaternion.Euler(_originalRotation.x + UnityEngine.Random.Range(rotationVariance * -1, rotationVariance), _originalRotation.y + UnityEngine.Random.Range(rotationVariance * -1, rotationVariance), _originalRotation.z);
}

void Update()
{
    if (_toRotation != null)
    {
        // slowly move to our new rotation over time
        transform.rotation = Quaternion.Slerp(transform.rotation, _toRotation.Value, Mathf.Clamp01(Time.deltaTime * 10));

        // until the difference in angle between our current rotation and
        // our destination rotation is < 1
        if (Quaternion.Angle(transform.rotation, _toRotation.Value) < 1)
        {
            _toRotation = null;
        }
    }
}

I updated my reply with Vector3 methods that might be slightly faster than the Quaternion functions.