Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Animation Question: Linking sprite animation to async progression

Discussion in 'Scripting' started by Richard_Roth, Aug 11, 2017.

  1. Richard_Roth

    Richard_Roth

    Joined:
    Dec 29, 2014
    Posts:
    61
    Cross-posting from the animation board.

    I've done some research this morning and can't find an eloquent way (2 lines of code) to do this efficiently. Unfortunately, I am not that familiar with animation and the animator, so any help is appreciated.

    I've got a sprite animation of a hexagonal loading bar with six sides. I would like to link it to the async loading progress, so that at intervals of 14.28% (of loading), the next frame of the animation plays.

    This is what the code looks like for the status text (0 - 100%), which gets its value from a progress bar (which I may or may not implement visually). (This is all in update)

    Code (CSharp):
    1.         progressBar.value = loadingProcess.progress;
    2.         status.text = Mathf.Round(progressBar.value * 100f).ToString() + "%";
    So, what I was thinking was maybe a line to access the animation clip and manually move the frames forward by a percentage (there are 7 frames at 0:01 intervals) linked to progressBar.value. I think that's it really, I could set the animation time to zero to stop it from looping.

    Any help greatly appreciated. I've got a feeling there is an extremely simple solution to this, but I just can't seem to see it.
     
  2. andymads

    andymads

    Joined:
    Jun 16, 2011
    Posts:
    1,614
    Do you need to do this via animation? Personally I would probably just use the progress value to determine which sprite to render.
     
  3. listener

    listener

    Joined:
    Apr 2, 2012
    Posts:
    179
    Moving animation frame by frame forward would be an ok option since clearly you need to control every aspect to it. You just need to calculate is progress bar moved from last frame move >= 14.28% and then move one frame and repeat.

    Usually you would use animation if its some complex looking progress bar that is hard to update trough code, otherwise you can update simple bars or pies, spinners and similar things just trough code no need for animating.
     
  4. Richard_Roth

    Richard_Roth

    Joined:
    Dec 29, 2014
    Posts:
    61
    Yeah, I just don't know how to access the animation clip or how to move the frames. I've been through the API and I haven't really found a function that sets the frame.
     
  5. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,199
    Yeah, setting the frame of an animation clip is going to be horrible. Unity's animation system does not handle going directly to a certain time in the animation at all.

    For this purpose, switching the sprites is going to be a lot easier than doing things through animation.
     
  6. listener

    listener

    Joined:
    Apr 2, 2012
    Posts:
    179
    If you wish to jump to specific time in animation you can use:

    https://docs.unity3d.com/ScriptReference/Animator.Play.html

    And then to pause it would be actually setting speed to 0 of animator but that would also mean you need to confirm that animation is at time x where you want to stop it.

    So its a bit hacky approach.
     
  7. Richard_Roth

    Richard_Roth

    Joined:
    Dec 29, 2014
    Posts:
    61
    Well, I solved it eventually. I'm putting my solution up here for anyone who wants to do this in future.

    Unity added a new feature to animation recently, I found a good explanation of how to implement it here.

    First, I turned off looping on the animation. Now it finishes on full load, which is what I want.

    Next, I added a new variable to Animator in the animator editor window. This became my animation speed multiplier.

    Then, I added the following to my code.

    Code (CSharp):
    1.     void ChangeStateSpeed(float speed)
    2.     {
    3.         animator.SetFloat("VariableAnimSpeed", speed);
    4.     }
    5.  
    6.     void Update()
    7.     {
    8.         // Update loading status
    9.  
    10.  
    11.         progressBar.value = loadingProcess.progress;
    12.         status.text = Mathf.Round(progressBar.value * 100f).ToString() + "%";
    13.         ChangeStateSpeed(progressBar.value);
    14. }
    Now, when there is a lot to load, it slows down the animation to keep in line with the async load process. As the loading processes continues, the animation speeds up. In this way, the loading progress of the sprites will always stay in line with the loading progress of the async function.