Search Unity

Trying to animate UI Image

Discussion in 'Animation' started by antzaras, Nov 15, 2019.

  1. antzaras

    antzaras

    Joined:
    Aug 25, 2019
    Posts:
    10
    I'm trying to animate a UI Image using an animator. I found a technique to do this here: http://boiagames.blogspot.com/2015/08/reusing-your-unity-in-game-animations.html.

    The Hierarchy and Inspector for the Image I'm trying to animate is here:

    upload_2019-11-15_15-54-29.png

    The code for the ImageCanvasAnimator script (which is pretty much the same as from the link above) is here:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.UI;
    5.  
    6. public class ImageCanvasAnimator : MonoBehaviour {
    7.  
    8.     // set the controller you want to use in the inspector
    9.     public RuntimeAnimatorController controller;
    10.  
    11.     // the UI/Image component
    12.     Image imageCanvas;
    13.     // the fake SpriteRenderer
    14.     SpriteRenderer fakeRenderer;
    15.     // the Animator
    16.     Animator animator;
    17.     [SerializeField] Sprite sprite;
    18.  
    19.  
    20.     void Start() {
    21.         imageCanvas = gameObject.GetComponent<Image>();
    22.         fakeRenderer = gameObject.AddComponent<SpriteRenderer>();
    23.         // avoid the SpriteRenderer to be rendered
    24.         fakeRenderer.enabled = false;
    25.         animator = gameObject.AddComponent<Animator>();
    26.  
    27.         // set the controller
    28.         animator.runtimeAnimatorController = controller;
    29.     }
    30.  
    31.     void Update() {
    32.         // if a controller is running, set the sprite
    33.         if (animator.runtimeAnimatorController) {
    34.             sprite = fakeRenderer.sprite; // this assignment works
    35.             imageCanvas.sprite = fakeRenderer.sprite; // this assignment DOES NOTHING
    36.         }
    37.     }
    38.  
    39. }
    It seems to me that maybe the problem is that if you have a UnityEngine.UI Image and you try to change it's sprite to the .sprite of a Sprite, like so:

    Code (CSharp):
    1. UnityEngine.UI image;
    2. Sprite sprite;
    3.  
    4. ...
    5.  
    6. image.sprite = sprite.sprite
    it will not work. I can't seem to make it work, so I don't know.

    Does anyone have any ideas on why this does not work?

    Clearly, the variable named "sprite" in the script above is getting assigned based on the values in the Inspector (see screenshot):

    upload_2019-11-15_15-59-55.png

    They match. But the Image Component's Source Image is still empty. So I don't know what I'm doing wrong.
     
    Last edited: Nov 15, 2019
  2. gersomr

    gersomr

    Joined:
    Apr 11, 2020
    Posts:
    1
    No0or and pmain8 like this.
  3. Man0li

    Man0li

    Joined:
    Jan 13, 2020
    Posts:
    6
    This worked for me but my animation has 81 pictures. Is there a better/faster way of adding each image or do I have to manually drag them one by one?
     
  4. d1a9n8a8

    d1a9n8a8

    Joined:
    Mar 29, 2020
    Posts:
    1
    yes in two simple steps :

    1. on the top right of the inspector there is a lock icon -
    click that to prevent the inspector from changing when clicking another asset

    Asset 24@4x.png


    2. select all the sprites you want to add and drag them to the Image animation component on top of the Sprites list:

    Asset 25@4x.png
     
    BjoUnity3d, No0or, bobby55 and 2 others like this.
  5. BjoUnity3d

    BjoUnity3d

    Joined:
    Jul 24, 2012
    Posts:
    60
    Honestly, that script should be frame rate independent or the animation will play at different speeds on different devices. Something like:

    Code (CSharp):
    1. public class ImageFlipAnimation : MonoBehaviour
    2.     {
    3.         [SerializeField] Sprite[] sprites;
    4.         [SerializeField] Image image;
    5.  
    6.         [SerializeField] float fps = 10;
    7.  
    8.         public void Play()
    9.         {
    10.             Stop();
    11.             StartCoroutine(AnimSequence());
    12.         }
    13.  
    14.         public void Stop()
    15.         {
    16.             StopAllCoroutines();
    17.             ShowFrame(0);
    18.         }
    19.  
    20.         IEnumerator AnimSequence()
    21.         {
    22.             var delay = new WaitForSeconds(1 / fps);
    23.             int index = 0;
    24.             while(true)
    25.             {
    26.                 if (index >= sprites.Length) index = 0;
    27.                 ShowFrame(index);
    28.                 index++;
    29.                 yield return delay;
    30.             }
    31.         }
    32.  
    33.         void ShowFrame(int index)
    34.         {
    35.             image.sprite = sprites[index];
    36.         }
    37.     }
    That will work as long as your animation frame rate is lower than your actual frame rate. It's not totally fps independent but close enough for most use cases.
     
    StalemateZ likes this.