Confusing behavior with Time.time and Mathf.Sin when changing frequency

So I have

float oscillator = Mathf.Sin(Time.time * frequency) * amplitude;

It works fine if frequency isn’t changing. Lower/higher frequency behaves as expected. But while I’m changing frequency over multiple frames, it oscillates very rapidly and then resumes normal behavior when I stop changing frequency. Longer the game has been running, the more rapidly it oscillates during changes, so I assume it has to do with Time.time always getting bigger.

Any idea how I can get around this? I’d like oscillation speed to smoothly increase/decrease as I increase/decrease frequency.

This is to be expected. When you are at, say, 2 seconds, with a frequency of 2 and then change it to 3 you end up in the middle of a cycle. Now you’re going to say ‘yeah but I slowly increase frequency’, but the longer you are running the bigger this discrepancy gets. (well okay, that’s not quite true, but when 1.00 has done 1000 cycles 1.005 is halfway a cycle).

So you’d have to compensate for that, ie, don’t use time but an alterntive variable, and when you set a new frequency you have to calculate where you were in your cycle and set your timer so that for the new frequency it would be at that point in the cycle, in that case the transition is smoother.

Hope that somehow made sense.

2 Likes

Keep your own timer, and each frame update it by Time.deltaTime * frequency. That way you’ll smoothly move forward at a varying rate from the current position in the waveform, where what you’re currently doing will essentially jump to different parts of the waveform as explained by sourcerer.

2 Likes

No, I think that still wouldn’t work, you’d still have a jump at each frequency change as the next frequency might be somewhere else in the cycle?

I do believe you need to do the reverse calc if you detect a frequency change. and then indeed as you said, use deltaTime*frequency.

It should work; I did something like this in one of my Vectrosity demo scripts.

	timer += Time.deltaTime * Mathf.Lerp(5.0, 20.0, energyLevel);
	energyLinePoints[i].y = Screen.height * (.1 + Mathf.Sin(timer) * .08 * energyLevel);

If I didn’t use my own timer, I got behavior similar to what JTown described when changing energyLevel.

–Eric

Trig wasn’t my favorite class but I think I get it. Thanks.

I’ll try this, thanks. My fallback plan is to use a curve editor and emulate sin.