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

Can't change sprite from code while using Animator?

Discussion in '2D' started by Undead, Dec 6, 2013.

  1. Undead

    Undead

    Joined:
    Nov 13, 2009
    Posts:
    49
    So, I have a sprite, I've animated it using the animation window > sprite renderer > sprite...
    I added some keys made the animation, put it into an animation controller, added a default state, made some transitions with some conditions to play one of 2 animations, all this works fine.

    After the animation finishes it goes back to the default state but I want to swap the sprite once the animation has finished...
    So I added an event to call a method on the script attached to the object which calls the spriterenderer.sprite to try to set it to a referenced sprite but it won't change?

    I added a quick debug check to map it to the keypad so I can just swap the sprites from the keypad and it will not swap the sprites while the animator component is enabled...

    If I disable the animator component in the inspector (while the scene is in play mode...or not) then I can swap the sprites but while it's enabled it won't change...So I know the code I'm using to swap the sprite from code is correct but it seems the animator is blocking it...

    Am I missing something or is this a bug?
     
  2. mcwool

    mcwool

    Joined:
    Jan 8, 2014
    Posts:
    14
    Hi, did you solve this? I am having the exact same problem.
     
  3. DylanYasen

    DylanYasen

    Joined:
    Oct 9, 2013
    Posts:
    50
    Hey mate!
    I suggest you to try turn "apply root motion" off !
    Hope it works!
     
  4. mcwool

    mcwool

    Joined:
    Jan 8, 2014
    Posts:
    14
    Thank you for the answer but it was already off :(
     
  5. Yarbius

    Yarbius

    Joined:
    Apr 29, 2014
    Posts:
    22
    I found a question on stack overflow indicating this will not work at runtime and you need to change the sprite in the animator. Since I had a situation where I only wanted the animation at the end (For an explosion just before the shot object was destroyed) I found I could disable the animator in the prefab then just enable it just before triggering the animation. Works great
     
    rumini22 and Luis0413 like this.
  6. v2-Ton-Studios

    v2-Ton-Studios

    Joined:
    Jul 18, 2012
    Posts:
    237
    In my experience Animator wins out of any code, every time. If someone has found otherwise please let me know, as I've wrestled with from time to time for over a year now.

    Side note: It would be great if Unity would introduce a way for script to win out over the animator. A special interface exposed by the animator perhaps that allows things like position, sprite setting, etc, to "win".

    One work around I've used is to parent the sprite in a game object and then show hide, squash, stretch, move, etc that parent, but never the sprite children. (In my experience, if you edit the sprite in any animation within a single animator it will override it for all code editing attempts.) You can then edit the sprite via code and have it perform as desired in animation. This is how I handle all skinning and equipment swap related stuff in my current project.

    Hope that helps.
     
  7. LoveZelda3

    LoveZelda3

    Joined:
    Apr 11, 2013
    Posts:
    1
    According to the answer in this thread http://answers.unity3d.com/questions/676812/unity-2d-can-you-change-a-2d-animation-clips-sprit.html you can use LateUpdate() to override the animator and they refer to this video 20 minutes in there he says you should do that:

     
    PoRtCuLLiS and MerKi like this.
  8. RockyWallbanger

    RockyWallbanger

    Joined:
    Mar 16, 2014
    Posts:
    85
    Is Write Defaults disabled on the animation clip? It could be that after the animation clip has finished it's resetting it to it's original sprite. Try turning Write Defaults off (if it's not already) and see if that works. If not, you could try setting the sprite in an OnStateExit call of a StateMachineBehavior
     
    Alexandros-A likes this.
  9. MagoParodi

    MagoParodi

    Joined:
    Nov 3, 2017
    Posts:
    1
  10. DevilZ1976

    DevilZ1976

    Joined:
    Apr 19, 2016
    Posts:
    2
    I've had issue that animator was still using sprite in animations.
    So the solution that I used was to create animation Ex. Idle1, Idle2. to default Animator controller I've added Idle1 motion and also created Animator override Controller with Idle2 as Idle motion and in script at runtime I've changed animator controller.

    Try this only if if you didn't succeed with previously mentioned solutions
     
  11. Alexandros-A

    Alexandros-A

    Joined:
    Feb 16, 2019
    Posts:
    7

    You sir solved my problem. Toggling the Write Defaults Off from the main source layer did the trick!
    Screen Shot 2019-05-08 at 11.38.14 AM.png

    For some reason my animator was resetting only the SpriteRendererColor Values of the current object. Everything worked smoothly, rotating angles, scaling, changing sprite source image but not the SpriteRenderer color values. They were constantly being reset after animation.


    new structure
    Screen Shot 2019-05-08 at 11.35.25 AM.png



    End result, alpha morphing marmaros!
    n2.gif
     
    Last edited: May 8, 2019
  12. josephquested

    josephquested

    Joined:
    Oct 21, 2015
    Posts:
    5
    thanks @LoveZelda3 putting the change in late update solved it for me. pretty silly solution though.
     
  13. jaspermc8

    jaspermc8

    Joined:
    Jun 5, 2020
    Posts:
    1
    Just set the Animator to enable = false after setting the new sprite.
     
    Luis0413 likes this.
  14. shibi2017

    shibi2017

    Joined:
    Jan 18, 2018
    Posts:
    153
    my solution is: if your animator do not play any animation that efforts to the game. you can first enable it false and change the value and reopen it to play next animations.
     
  15. rafaelwroobel

    rafaelwroobel

    Joined:
    Sep 4, 2018
    Posts:
    2
    Hello,
    im having alsow a problem with sprite change when a specific animation is added do animator controller. When i have only idle aniamation addet to animator, ship sprite is changed correctly from variable from scriptable object but when i add explosion animation that takes sprite change changes also back ship sprite to the "basic one".

    I turned off root motion and write defaults alsow and tried to disable animator and enable it after changing sprite, but no effects

    LateUpdateWorks, but if i have other animations attached it could generate problem - I sopouse

    1.JPG 2.JPG
     
    Last edited: Jun 30, 2022
  16. rafaelwroobel

    rafaelwroobel

    Joined:
    Sep 4, 2018
    Posts:
    2
    I made a solution for this situation. I have addet an additional SPRITE RENDERER which is respocable for explosion animation. Think it's the easiest way and alsow best perform.
     
  17. BentNai1

    BentNai1

    Joined:
    Apr 20, 2020
    Posts:
    2
    Hey, I'd like to throw my hat in the ring for an alternative solution I found for this. It turns out, that even if you seemingly can't get an animation clip to respect direct re-colors to the sprite renderer, you CAN get it to respect re-colors from another animation clip!

    Basically:

    1 Make an animation clip with exactly one purpose – re-color the sprite from bright to dark over the course of the entire animation.


    2 Put that clip in it’s own layer in the animator, and set its’ speed to 0.


    3 Put in a function to play that animation clip at a particular time. Run this function after changing the guy's health.
    Code (CSharp):
    1. private void ChangeSpriteColorForHealth()
    2. {
    3.     //clamped to 0-0.99, because a value of 1 causes color anim clip to loop; is treated as 0 by unity.
    4.     float lerpHPVal = Mathf.Clamp(Mathf.InverseLerp(maxHealth, 0, health), 0, 0.99f);
    5.     animator.Play("Color.ColorValue", 0, lerpHPVal);
    6. }
    4 Huzzah! It works!


    There's a bit more information on my blog. I hope this helps someone!
    https://rmikelivingstondesign.wordp...le-with-changing-color-on-an-animated-object/
     
  18. rumini22

    rumini22

    Joined:
    Dec 19, 2022
    Posts:
    1
    tyvm, it works really good