The tricky part of this problem is determining which range to clamp to. One approach is to find the nearest min/max bound to the value, then clamp according to the corresponding range.
Assuming that your ranges are represented as an array of value pairs (two-value arrays), we can join them together and find the nearest min/max value by adapting the approach in this answer. Then, it's fairly easy to work backwards to determine which range the min/max value is from, and clamping accordingly:
// Clamps given value to nearest of given min/max pairs
private float ClampToNearestRange(float value, float[][] ranges)
{
// First, let's flatten the values into a single list
List<float> flattenedRanges = ranges.SelectMany(item => item).ToList();
// Now, we'll find the closest value in the list, and then get its index
float nearestValue = flattenedRanges.Aggregate((x,y) => Mathf.Abs(x-value) < Mathf.Abs(y-value) ? x : y);
int valueIndex = flattenedRanges.IndexOf(nearestValue);
// With the value index, we can deduce the corresponding range index
int rangeIndex = (valueIndex % 2 == 0) ? valueIndex / 2 : (valueIndex - 1) / 2;
// Finally, we'll clamp according to the range we selected
return Mathf.Clamp(value, ranges[rangeIndex][0], ranges[rangeIndex][1]);
}
You would then use the method like so:
// First, declaring your ranges somewhere in your class
float[] range1 = new float[]{0, 60};
float[] range2 = new float[]{80, 100};
float[] range3 = new float[]{150, 200};
float[][] ranges;
Start ()
{
ranges = new float[][]{range1, range2, range3};
float clampedAngle1 = ClampToNearestRange(120, ranges); // returns 100
float clampedAngle2 = ClampToNearestRange(126, ranges); // returns 150
float clampedAngle3 = ClampToNearestRange(170, ranges); // returns 170
}
Note: This does use LINQ, meaning if you need to do this often you might want to expand the logic into more Unity-friendly loops. Won't be as succinct, but it could affect your game performance.
Hope this helps! Let me know if you have any questions.