I think in this case the best explanation how things work is to go through the algorithm.
Let’s say the tobsprite array has 4 sprites and initial state value is 0:
// state = 0, tobsprite.Length = 4
spriteRenderer.sprite = tobsprite[state % tobsprite.Length]; // 0 % 4 = 0, so this assigns the first sprite in the array
state++ // state = 1
// next Update loop iteration
// state = 1, tobsprite.Length = 4
spriteRenderer.sprite = tobsprite[state % tobsprite.Length]; // 1 % 4 = 1, second sprite
state++ // state = 2
// next Update loop iteration
// state = 2, tobsprite.Length = 4
spriteRenderer.sprite = tobsprite[state % tobsprite.Length]; // 2 % 4 = 2, third sprite
state++ // state = 3
// next Update loop iteration
// state = 3, tobsprite.Length = 4
spriteRenderer.sprite = tobsprite[state % tobsprite.Length]; // 3 % 4 = 3, fourth sprite
state++ // state = 4
// next Update loop iteration
// state = 4, tobsprite.Length = 4
spriteRenderer.sprite = tobsprite[state % tobsprite.Length]; // 4 % 4 = 0, first sprite again, so you can see it loops the array
state++ // state = 5
// next Update loop iteration
// state = 5, tobsprite.Length = 4
spriteRenderer.sprite = tobsprite[state % tobsprite.Length]; // 5 % 4 = 1, second sprite again and so on..
state++ // state = 6
the timer variable is for slowing down the rate of sprite changes, without that the renderer will display different sprite every frame which could be simply too fast and depending on the framerate.
The timer works like this, values of course may vary and are for explanation purpose:
// initial values
// timeThreshold = 0.1
// timer = 0
// state = 0
if (Time.time > timer) // Time.time = 0, timer = 0, 0 > 0 => false (sprite does not change)
// next iteration
if (Time.time > timer) // Time.time = 0.01, timer = 0, 0.01 > 0 => true (sprite does change)
timer = Time.time + timeThreshold; // timer = 0.01 + 0.1 = 0.11
state++ // state = 1
// next iteration
if (Time.time > timer) // Time.time = 0.02, timer = 0.11, 0.02 > 0.11 => false (sprite does not change)
// next iteration
if (Time.time > timer) // Time.time = 0.04, timer = 0.11, 0.04 > 0.11 => false (sprite does not change)
// next iteration
if (Time.time > timer) // Time.time = 0.07, timer = 0.11, 0.07 > 0.11 => false (sprite does not change)
// next iteration
if (Time.time > timer) // Time.time = 0.09, timer = 0.11, 0.09 > 0.11 => false (sprite does not change)
// next iteration
if (Time.time > timer) // Time.time = 0.11, timer = 0.11, 0.11 > 0.11 => false (sprite does not change)
// next iteration
if (Time.time > timer) // Time.time = 0.12, timer = 0.11, 0.12 > 0.11 => true (sprite does change again, about 0.1s has passed so it's time-dependent, not frame-dependent)
timer = Time.time + timeThreshold; // timer = 0.12 + 0.1 = 0.22
state++ // state = 2
// next iteration
if (Time.time > timer) // Time.time = 0.13, timer = 0.22, 0.13 > 0.22 => false (sprite does not change and so on..)
I hope it helps.