Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by Doctor_ED · Aug 16, 2019 at 10:00 AM · c#audioaudiosourceaudioclip

[Rhytm game] How to spawn on exact time of music?

I'm working on a simple rhytm game, where enemies spawn to the rhytm of music (maps are premade in form of scriptable objects). Now, as it's a rythm game I need to spawn those enemies in the exact time of the song, otherwise they won't be in sync...

  SongStartTime = AudioSettings.dspTime; // in a coroutine that starts a music
 
 SongCurrentTime = AudioSettings.dspTime - SongStartTime; // in Update
 
 if (SongCurrentTime >= _spawnTime) //in Update as well
 {
       Debug.Log(SongCurrentTime);
       _spawnController.SpawnNote();
       CurrentNoteIndex++;
       RecalculateSpawnTime();
 }

From that debug.log ( and also some tests) I know that the problem is in AudioSettings.dspTime not updating fast enough ( if game is played on 600 fps, I get a mismatch of around 10ms which is already visible), so I need to get another way of spawning enemies on the exact (like 1ms off) time of the song...

Comment
Add comment · Show 4
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image sacredgeometry · Aug 16, 2019 at 10:24 AM 0
Share

DSP time should be sample accurate so I doubt its that. You are sampling it at non specific intervals. Assu$$anonymous$$g everything else is correct. Have you tried running your code in FixedUpdate Ins$$anonymous$$d?

avatar image sacredgeometry · Aug 16, 2019 at 10:36 AM 0
Share

Also:

  1. Who has a screen that can render 600fps?

  2. Can the spawned items be buffered (Pre spawned) into place?

  3. Can you give more of a description of the mechanic/ gameplay please?

avatar image Doctor_ED sacredgeometry · Aug 16, 2019 at 11:20 AM 0
Share
  1. I ment that update loop is executing 600 times per second (once per frame).

  2. Yeah they will be prespawned and added to objectPoll.

  3. Game is basicly a copy of $$anonymous$$useDash : https://youtu.be/_rNTCySxaYY (obviously it won't be publicly aviable).

And with the current method of spawning, the problem is in a fact that AudioSettings.dspTime is updating like ~200 times per second or so (that alone gives at least 5 ms of lag)... Pic describes what I mean : alt text

problem.png (203.0 kB)
avatar image sacredgeometry Doctor_ED · Aug 16, 2019 at 01:18 PM 0
Share

Im at work at the moment but I will try to mock something up later when I get off work.

3 Replies

· Add your reply
  • Sort: 
avatar image
-1

Answer by TonicMind · Aug 16, 2019 at 01:51 PM

So the problem you're having here is:

  SongStartTime = AudioSettings.dspTime; // in a coroutine that starts a music
  
  SongCurrentTime = AudioSettings.dspTime - SongStartTime; // in Update

The above is essentially zero. AudioSettings.dspTime - SongStateTime has to be zero, as they are the same value.

So in your if statement you end up with a greater than or equal condition, and since zero is the result the above code (in all cases) the _spawnTime variable is either negative or zero.

On top of that you are not using the difference in spawn times. You simply call _spawnController.SpawnNote() without changing the time of spawn.

To accomplish your goal:

     public IEnumerator DelayNoteSpawn()
     {
         startTime = AudioSettings.dspTime; //Save the time of start for the note
         
         float difference = Time.sinceLevelLoad -  startTime; //Find the difference between then and now
         
         yield return new WaitForSeconds(difference); //Wait 'difference' seconds
         
         _spawnController.SpawnNote(); //Spawn your enemy/note. 
 
     }

Hope this helps!

Comment
Add comment · Show 7 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image sacredgeometry · Aug 16, 2019 at 01:58 PM 0
Share

They wont be the same if its a value type. Which it is i.e. a double and time has passed.

https://docs.unity3d.com/ScriptReference/AudioSettings-dspTime.html

avatar image TonicMind sacredgeometry · Aug 16, 2019 at 02:04 PM 0
Share

Um... what? You don't understand the code I have written nor do you understand what you're talking about.

avatar image sacredgeometry TonicMind · Aug 16, 2019 at 02:06 PM 0
Share

Interesting position. Ok so you said:


So the problem you're having here is:

   SongStartTime = AudioSettings.dspTime; // in a coroutine that starts a music
   
   SongCurrentTime = AudioSettings.dspTime - SongStartTime; // in Update

The above is essentially zero. AudioSettings.dspTime - SongStateTime has to be zero, as they are the same value.


Why would they be the same value?

Show more comments
avatar image Doctor_ED · Aug 16, 2019 at 02:15 PM 1
Share

Thanks for reply, but you're wrong here : SongStartTime = AudioSettings.dspTime; is called only once, at the start of whole gameplay, the code above is not in the same block, I just pasted it so (and commented) because to show whole code I would have to paste few classes each having like 60 lines or so...

The problem is not that I can't get it to spawn correctly (in a way), the problem is that I need it to be exact perfect with music, and right now I have around 10ms of inconsistency

avatar image
0

Answer by sacredgeometry · Aug 16, 2019 at 02:45 PM

Reading the documentation. There is a code example:

https://docs.unity3d.com/ScriptReference/AudioSettings-dspTime.html

It would appear that you need to read the value inside the context of this method

OnAudioFilterRead()

https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnAudioFilterRead.html

Comment
Add comment · Show 7 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Doctor_ED · Aug 16, 2019 at 02:56 PM 0
Share

Well, I don't think it's the case, since I can read dspTime without an error (it's just that it's updated not frequently enough). And from docs of <OnAudioFilterRead That callback is called like every ~20ms, so that's way, way too inprecise.

avatar image sacredgeometry Doctor_ED · Aug 16, 2019 at 03:00 PM 0
Share

The access doesn't change depending on where you reference it as its public but the amount of times it gets called and the amount of tertiary information you get does.

Have a look at the metronome example. All you are doing thats different is accenting pre deter$$anonymous$$ed beats and having it raise an event on that accent.

avatar image sacredgeometry Doctor_ED · Aug 16, 2019 at 03:02 PM 0
Share

Alternatively there are Unity packages

https://www.youtube.com/watch?time_continue=59&v=DTgn_b$$anonymous$$CWyg

That handle this for you (that one isnt cheap though).

avatar image sacredgeometry Doctor_ED · Aug 16, 2019 at 03:05 PM 0
Share

Oh p.s. I have a colleague that solved a very similar problem I can add more specific information once he is available.

Show more comments
avatar image
0

Answer by Magso · Aug 16, 2019 at 08:58 PM

You could divide the BPM by 60 and check if dspTime is a multiple of that number.

 if (AudioSettings.dspTime % (60f / bpm) == 0){
     //spawn
 }
Comment
Add comment · Show 5 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Doctor_ED · Aug 16, 2019 at 09:52 PM 0
Share

dspTime is a double type value... Let's say a song has a 180 bpm, divide by 60, and we have 3 beats per second. So now if at a time that the check is going, if the dspTime is not "with the beat" then code should wait 1/3 second only for the next check if It goes with the beat? I't would only introduce further inconsistancies to spawning, what if I can't get the right value in dspTime for several frames in a row, It could delay spawn of one note by even seconds... I'm starting to feel like I should completely change the way my "spawning" works... (I think I should spawn them all at Start(), and position them in a way that they arrive at right time...

avatar image sacredgeometry Doctor_ED · Aug 16, 2019 at 10:15 PM 0
Share

You would still need to trigger them some how unless you developed some sort of playhead.

i.e. a constantly moving collider that triggers enemies it collies with may work.

avatar image sacredgeometry Doctor_ED · Aug 16, 2019 at 10:17 PM 0
Share

Oh p.s. I decompiled that package and there isn't anything in there that hasn't been said here

avatar image Magso Doctor_ED · Aug 16, 2019 at 10:41 PM 0
Share

Wouldn't you still have the same problem? You said that dspTime wasn't updating fast enough. Have you tried using OnAudioFilterRead()? There's also a thread here which if I'm not mistaken is discussing the same problem.

avatar image sacredgeometry Magso · Aug 16, 2019 at 10:46 PM 0
Share

You wouldnt need dsp time if you did it that way.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

654 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

I have a shooting script. I have a problem: when firing bursts, my sound of a shot breaks. How to make the sound produced to the end. 0 Answers

How to play "audiosource" component in a prefab from script? 0 Answers

Triggering multiple audio clips to play in sequence 1 Answer

How can I play audio clips depending on the players movement 0 Answers

Audio Clip Playing every frame 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges