- Home /
perfect synch with music
Hi guys, I need a little help here. I want to create a rhythm game for android and I need enemy to appear on screen on a specific time matching with the music. I've wrote this piece of script that makes me go out of sync:
for(var k = 1; k < time_s.Length; k++){
if(gameover)
return;
var lack : double = Time.time;
print(Time.time);
Instantiate(enemy_s[k-1],myTransform.position,myTransform.rotation);
lack-=Time.time;
print(Time.time);
yield new WaitForSeconds(wait[k] -lack);
}
Problem is that Instantiate does take it's time and it's added to the instantiation of the enemy, making the game out of sync after 20-30 enemys. I've tried to evade this problem by using the lack variable that should store the instantiation time and subtract to the wait, but Time.time only have 4-5 decimal and lack is always 0. Does exist a Time.time more precise or can you guys help me finding another way to do it?
Why not have them all instantiated already, but disabled? Then you can just enable them when the time is right.
Lack is always 0 because you are defining it as being both equal to Time.time and then you are subtracting Time.time off of it. These cancel each other out and you are left with 0. You should ins$$anonymous$$d be += Time.time on to lack.
@$$anonymous$$leptomaniac I need to find the estimated time for instantiating that object, how can I do that by adding Time.time to lack? @asafsitner I have to change all my script to adapt it, but it's not a bad idea if I can evade the delay
Sorry, yes I think the system you are currently using is rather unreliable. @asafsitner's solution would probably be the best in terms of the fact that this is a rhythm game.
unfortunatly @asafsitner's solution create the same effects, still having delay
Answer by aldonaletto · Mar 18, 2012 at 04:35 PM
You can sync to audio.timeSamples instead of Time.time - this property shows the current sample number being played, thus it's in perfect sync with the music. In order to use your present array time_s, you can convert the time to the timeSamples equivalent (multiply by audio.clip.frequency):
for (var k = 1; k < time_s.Length; k++){ if (gameover) return; // find the sample number equivalent to time_s[k]: var nSample = time_s[k] * audio.clip.frequency; while (audio.timeSamples < nSample) yield; // wait till the desired sample Instantiate(enemy_s[k-1],myTransform.position,myTransform.rotation); }
NOTE: time_s must contain the times at which the enemies should appear, not the intervals between them.
you... I LOVE YOU $$anonymous$$AN! It's in perfect sync in every device! Thanks! I still have to understand how timeSamples is working, but it's almost perfect now! Thanks again!
timeSamples shows the number of the current sound sample: in a CD-like sound, for instance, the sampling rate is 44100Hz, what means that 44100 samples are sent to the output mixer per second. If you want to do something at 1.5s after the beginning of the sound, yield while timeSamples < 44100 * 1.5 - Unity will wait until the desired sample has been played.
hey everbody, iam having a similar problem, but i am using c#, how would you translate that part with yield especially in to a c# code ? actually i think one should use clip.samples ins$$anonymous$$d of frequency, to return the actual sampleamount ..
The whole routine must be declared as a coroutine (it must return IEnumerator) and you must call it with StartCoroutine, like StartCoroutine(SincToAudio()). Yield in C# must return something (no idea why), thus it becomes yield return 0;:
IEnumerator SincToAudio(){ for (int k = 1; k < time_s.Length; k++){ if (gameover) return; // not sure if this should return 0 in CS // find the sample number equivalent to time_s[k]: int nSample = time_s[k] * audio.clip.frequency; while (audio.timeSamples < nSample) yield return 0; // wait till the desired sample Instantiate(enemy_s[k-1], myTransform.position, myTransform.rotation); } }clip.samples is the clip length in samples, but what you really need is to convert a time value in number of samples - that's why the time is multiplied by the audio clip sample frequency (audio.clip.frequency).
Hi sir, I need to use the same logic for my game. where i need spawn some fruits to sync with the music. how can i use your logic. i didn't understand what is time_s in the above. Could you please take moment and help me out of this
Thank you
thanks alot for the quick answers, looks good, i ll try it out ! and oh boy ! you are right, i actually also calculated the amounts of samples that i need to wait completly wrong.. because you have 44100 per second right ? and if i wanted to wait for 1/4 of a musical beat that would of course not(!) be 44100/4.. because one beat has a different length regarding to temp... ;-)
Your answer
![](https://koobas.hobune.stream/wayback/20220613065245im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
GameObjects not syncing with music 1 Answer
Spawning based on Music 1 Answer
How to make a loading feedback for big GameObjects loading? 2 Answers
Inconsistent results with music and synchronization 2 Answers
AudioSource and AudioSettings help needed to keep perfect sync between music audio loops. 0 Answers