How do you execute code every X angles reliably?

How would you execute code every X angles? To provide some context, in the VR game I’m working on, I want to play an audio file every 30 degrees that a crank turns. When using my current code, turning the crank slowly works mostly fine, but turning it quickly results in it missing certain angles, so that it doesn’t play the audio file reliably.

Below is a snippet of the code in my Update function (not fixed update).

if(drum.angularVelocity.z < -1)
        {
            if((int)drum.rotation.eulerAngles.z % 30 == 0)
            {
                if(shouldPlayClick)
                {
                    if(clickCount > crankClicks.Length -1)
                    {
                        clickCount = 0;
                    }
                    crankAudio.clip = crankClicks[clickCount];
                    crankAudio.Play();
                    clickCount++;
                    shouldPlayClick = false;
                }
                
            }
            else
            {
                shouldPlayClick = true;
            }
        }

Any ideas? Am I going about the problem wrong, or is there something I can add to my code to make it more reliable?

You could track the changes to the angle each frame, then add that change to a counter variable. Anytime that counter gets over 30, reset it to zero and play the sound. Something like this:

private float zRotCounter = 0f;
private float zRotLimit = 30f;
private float lastEulerZ; //initialize this to starting z rotation

private void Update()
{
    var dif = (drum.rotation.eulerAngles.z - lastEulerZ);
    lastEulerZ = drum.rotation.eulerAngles.z;
    zRotCounter += dif;
    if (zRotCounter > zRotLimit){
        zRotCounter = 0f;
        //play sound
    }
}

You’ll have to deal with negative rotations correctly.

The other way to handle this would be keep track of the last angle the audio was played at, then on every update check the current angle with the last angle the audio was played at. If they are greater than 30 degrees apart, play the sound and set the last angle to the current angle. In fact this might be the better way to do it - would be easier to handle negatives.

Well, after a bit of tinkering and some debugging, I realized that @jdean300 's solution works incredibly well as long as you change the if statement to check if the absolute value of zRotCounter is greater than zRotLimit, like so:

        zRotCounter += handle.rotation.eulerAngles.z - lastEulerZ;
        lastEulerZ = handle.rotation.eulerAngles.z;

        if (Mathf.Abs(zRotCounter) > zRotLimit)
        {
            zRotCounter = 0;
            crankAudio.Play();
        }

Thank you for your help everyone!!