Search Unity

  1. Check out the Unite LA keynote for updates on the Visual Effect Editor, the FPS Sample, ECS, Unity for Film and more! Watch it now!
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. Improved Prefab workflow (includes Nested Prefabs!), 2D isometric Tilemap and more! Get the 2018.3 Beta now.
    Dismiss Notice
  4. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice
  5. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice

Are rhythm games supposed to be possible or not?

Discussion in 'Scripting' started by Raemon, Nov 2, 2009.

  1. Raemon

    Raemon

    Joined:
    Jun 14, 2009
    Posts:
    62
    I just did some searches to try and find help, and got conflicting answers from over the course of several years of forum history.

    I'm trying to make a 2D sidescroller that rewards you for performing actions (mainly jumping) in time with the rhythm of the music. The "rhythm game" aspect isn't intended to be all the complicated (beats come about every half second, there's no variety, just keep your actions falling along the beats).

    What I had been using was:

    Code (csharp):
    1.  
    2. static var rhythmAble = false;
    3.  
    4. function FixedUpdate () {
    5.     beat += 1;
    6.     if (beat == 10) {
    7.         rhythmAble = true;
    8.     }
    9.     if (beat == 23) {
    10.         rhythmAble = false;
    11.     }
    12.     if (beat == 25) {
    13.         beat = 0;
    14.     }
    15. }
    16.  
    I came up with the numbers via trial and error. 25 fixed frames happened to match up with the beat and 13 frames seemed a reasonable amount of leeway to give to human reflexes. They worked fine for a few weeks in the editor (and I think I even published it a few times and it worked), but then I changed a graphic setting and suddenly it's out of sync everywhere.

    Some older threads said that Unity's audiosync capabilities just plain aren't good enough to do a rhythm game. Some newer threads suggested it might be possible but those threads also about fairly simple games that didn't seem to have bad guys attacking and whatnot which I suspect could complicate things.

    A few of the later threads said "use deltaTime" which makes sense but I'm not actually sure how to implement it.
     
  2. Timmer

    Timmer

    Joined:
    Jul 28, 2008
    Posts:
    330
    Hello,

    Generally FixedUpdate is for physics stuff only. You probably want to use Update and then use deltaTime.

    deltaTime keeps the elapsed time since the previous call to Update. This way you know how much time has gone by between calls.
    You could also take a look at the other Time class members such as time and timeSinceLevelLoad.

    Then you could record the time since the song (or event starts) and from then on keep track of the beat offsets since then.
     
  3. spectre1989

    spectre1989

    Joined:
    Oct 6, 2009
    Posts:
    80
    Yes rhythm games are entirely possible, I've made fully dynamic ones in Flash before, and if that can be done then Unity certainly can! As Timmer said, you probably should use Time.deltaTime in the regular Update function and then interpolate the position of the jump based on how close to dead on the beat you are.

    Good luck!
    Spec
     
  4. Raemon

    Raemon

    Joined:
    Jun 14, 2009
    Posts:
    62
    First off, I'm still fairly new to programming so bear with me.

    I'm not quite sure how to use Time.deltaTime. I understand that deltaTime is what you need to be framerate independent but I don't what understand what deltaTime actually IS. I know, "The time in seconds it took to complete the last frame" but then how do the example functions such as

    Code (csharp):
    1.  
    2. function Update () {
    3.     // Move the object 10 meters per second!
    4.     var translation = Time.deltaTime * 10;
    5.     transform.Translate (0, 0, translation);
    6. }
    7.  
    work exactly? Strictly speaking I'd think the "The time in seconds it took to complete the last frame" would be something like 1/60th a second. Time.deltaTime X 10 should almost always be about equal to 1/6th, which would result in the object in the example object remaining pretty much in the same place. Obviously that's not how it works so I'm not really sure what deltaTime actually means or how to use it intelligently.

    Meanwhile, I've been trying using the "AudioSource.time" which seems to be working, using the following code:

    Code (csharp):
    1.  
    2. var beat = 0.0;
    3. var beatSub = 0;
    4. var beatTot = 0.0;
    5. static var rhythmAble = false;
    6. var guiPop : GUITexture;
    7. var Mo : AudioSource;
    8.  
    9. function Start()
    10. {
    11.     audio.Play();
    12. }
    13.  
    14. function Update()
    15. {
    16.     beat = Mo.time;
    17.     beatSub = Mo.time;
    18.     beatTot = beat - beatSub;
    19.     guiPop.pixelInset.x = beatTot*100 + 220;
    20.     if ((beatTot > 0)  (beatTot < .4)) {
    21.         rhythmAble = true;
    22.     } else {
    23.         rhythmAble = false;
    24.     }
    25.     var beatStr = beatTot.ToString();
    26.     guiText.text = beatStr;
    27. }
    28.  
    I subtract the int value of audioTime from the float value, leaving me with a range between 0 and .9999, and then players are rewarded for taking actions when the beatTot value is between 0 and .4. I need to adjust those numbers to actually sync with the music but it seems to be working in general (unless there's more that I'm not aware of).
     
  5. Timmer

    Timmer

    Joined:
    Jul 28, 2008
    Posts:
    330
    No worries on being new -- glad to help out :)

    One way to think of deltaTime is if you've taken any physics classes, the deltaTime is like your t variable in kinematic equations.

    Basically to update an object's position you need to know 1) original position, 2) speed and 3) elapsed time. You end up with the equation that says "an object's position based on time is that of the starting position plus it's speed multiplied by the amount of time it's been traveling".

    In Unity code this would be:

    Code (csharp):
    1. // assuming just moving on X-axis
    2. transform.location.x = transform.location.x * speed * Time.deltaTime
    Where speed is some defined variable. In your pasted code example, it is 10.

    Since it's running this every frame, as you say deltaTime will be say 1/60th of a second so every update it will be moved Speed * 1/60 units, which of course is the same as 10 Units/second which is what we want.