Rotate object in random direction

I am writing a script to rotate my object in a random direction. My object is a cube that starts facing a single direction and I want it to generally face that same direction forever but I want to apply a random rotation at sporadic intervals to create the illusion that the cube is alive and looking around. Since I want the cube to generally face the same direction over the lifetime of the game object my plan is to start out by storing the cube forward rotation and then pick a random number for Z and Y. I would then add those numbers to the original forward rotation and slowly rotate the cube to the new rotation.

I’m not really sure how to do this, but here’s what I’ve got so far (slowMove will be called at a random interval to give the appearance of not being predetermined.

private void slowMove()
{
      
    if (_fromOrigin)
    {
        _fromOrigin = false;

        // 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
        _toRotation = Quaternion.LookRotation(new Vector3(UnityEngine.Random.Range(-90, 90), UnityEngine.Random.Range(-90, 90), UnityEngine.Random.Range(-90, 90)) + _originalRotation.eulerAngles, transform.up);
    }
    else
    {
        // if we're rotated away from our origin rotation, rotate back
        _toRotation = _originalRotation;
    }
}

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

        // 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;
        }
    }
}

Obviously the _toRotation value isn’t being calculated correctly because it’s not taking into account my current rotation so it can’t be an offset like I would like, but I don’t really know how to do that.

Thanks for the help friends!

Store:
Original localRotation.
Target localRotation.

And then slerp between those in update.

Do not slerp between current and desired rotation.

float t = 0.0f;
Quaternion targetRotation;
Quaternion originalRotation;
void Start(){
     originalRotation = transform.localRotation;
     t = 0;
     targetRotation = someRandomQuaternionGeneratorFunction();
}

Update(){
    t = Mathf.Clamp01(t + Time.deltaTime);
    localRotation = Quaternion.Slerp(originalRrotaiton, targetRotation, t);     
}

^^Pseudocode, untested.

slerping between start and end position made it really jumpy. It would move a bit on each frame, then reset and move the same distance on the next frame. It looks like slerping from current and target is what I want because that’s nice and smooth. localRotation, rotation, tried them both and they both have the same look. My big problem is the rotation calculation. I need to calculate a rotation that is no more than +/- 90 degrees from my starting rotation in all three directions (x,y,z). If I use UnityEngine.Random.rotation everything works perfectly, I just need a rotation that is clamped to that 180 degree range in all directions.

This code works perfectly for what I’m doing other than that clamping.

private void slowMove()
    {
        if (_fromOrigin)
        {
            _fromOrigin = false;

            // 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
            _toRotation = UnityEngine.Random.rotation;
        }
        else
        {
            _fromOrigin = true;

            // if we're rotated away from our origin rotation, rotate back
            _toRotation = _originalRotation;
        }
    }

    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;
            }
        }
    }

Hmmmm, I found a method called Quaternion.FromToRotation that is supposed to create a rotation between two vectors which looked promising but didn’t really work. I still get a rotation that is beyond the 90 degrees I want to go.

float rotationVariance = 90;

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

Actually, nevermind, that looks like it’s sort-of working. although, oddly, whether I have the rotationVariance to 90 or 1 it seems to work exactly the same way…