Search Unity

Switching Animator Controller via scripts at runtime resets player's Transform

Discussion in 'Animation' started by Eudaimonium, Jan 17, 2017.

  1. Eudaimonium

    Eudaimonium

    Joined:
    Dec 22, 2013
    Posts:
    131
    Hi.

    In toying around with Animator component on a skinned mesh, I discovered that for some reason, when NOT using root motion (works fine otherwise) and switching the runtimeAnimatorController property via code somehow resets the entire player's transform object (position and rotation) to where it was in the world when Play mode began.

    The code for swithing used to be:

    Code (CSharp):
    1. PlayerAnimator.runtimeAnimatorController = //new controller here
    I managed to work around it using the following wrapper function:

    Code (CSharp):
    1. Vector3 position = PlayerTransform.position;
    2.         Quaternion rotation = PlayerTransform.rotation;
    3.         Vector3 velocity = PlayerRigidbody.velocity;
    4.         PlayerAnimator.runtimeAnimatorController = //new controller here
    5.         PlayerTransform.position = position;
    6.         PlayerRigidbody.velocity = velocity;
    7.         PlayerTransform.rotation = rotation;
    Again, it used to be OK when I was using Root motion for the avatar's locomotion, but I decided to switch root motion off and drive the player's Rigidbody manually in order to have more control over what's happening, since it's going to be a relatively complex third person RPG.

    Any ideas what's causing this?

    EDIT - Added velocity saving to the function as well.
     
    Last edited: Feb 7, 2017
  2. Ironmax

    Ironmax

    Joined:
    May 12, 2015
    Posts:
    890
    bump got same issue. They change how the whole hierarchy updates when you change the controller (dont know why they did this).. pretty useless now..because the fix would be glitchy.
     
    Last edited: Feb 5, 2017
  3. Eudaimonium

    Eudaimonium

    Joined:
    Dec 22, 2013
    Posts:
    131
    I believe this is an unintended bug. It's weird how the skinned mesh resets to where it was when the scene began playing, not (0,0,0) as you would expect. You move your player's starting point and it gets reset there.

    Also, it seems my little workaround posted in the opening post is actually working rather nicely. Simply storing and restoring position and rotation appears to be enough. Physics look solid, no glitches, no unintended side effects.
     
    Thorlar and Ironmax like this.
  4. Ironmax

    Ironmax

    Joined:
    May 12, 2015
    Posts:
    890
    Yeah your fix works i am using it now, but we shouldn't be making such workarounds in the first place.
     
  5. Ironmax

    Ironmax

    Joined:
    May 12, 2015
    Posts:
    890
    You can see the bug is there even when your not doing it by code. Just inside the editor manual changing the controller.
     
  6. Eudaimonium

    Eudaimonium

    Joined:
    Dec 22, 2013
    Posts:
    131
    Eh, we're in game development. It's part of the job description :D

    Dunno about you, but the fact that I am switching animation controllers at runtime is already a workaround, to avoid having hundreds of animator parameters, spaghetti controller code, and spaghetti state machine.

    Now I'll have to workaround the jarring, non-interpolated animations when switching controllers.

    After all that, I'm gonna have to workaround something else.
     
    Thorlar and Ironmax like this.
  7. Ironmax

    Ironmax

    Joined:
    May 12, 2015
    Posts:
    890
    Your right but its a annoying new "feature" :p Thought i am happy with the performance in 5.5.1

    I have seperated controller for each weapon type, to avoid the mess in the nod Mecnamim . I show you how it did this pretty clean with enums. I am also working on a RPG :) its all about flexibility and control right?


    Code (CSharp):
    1.     public void SetAnimationMode()
    2.     {
    3.      
    4.         if (combatMode == Condition.Melee)
    5.         {
    6.             ChangeController(CharAniMelee);
    7.         }
    8.         else  if (combatMode == Condition.Ranged)
    9.         {
    10.             ChangeController(CharAniRanged);
    11.         }
    12.         else  if (combatMode == Condition.Ranged2Hand)
    13.         {
    14.             ChangeController(CharAniRanged2Hand);
    15.         }
    16.         else  if (combatMode == Condition.Mount)
    17.         {
    18.             ChangeController(FlyStance);
    19.         }
    20.         else
    21.         {
    22.             ChangeController(CharAni_None);
    23.         }
    24. //        RefreshAniControllerContent ();
    25.     }
    26.  
    27.     public void ChangeController(RuntimeAnimatorController Newctrl)
    28.     {
    29.         Vector3 position = Player.Script.transform.position;
    30.         Quaternion rotation = Player.Script.transform.rotation;
    31.  
    32.         anim.runtimeAnimatorController = Newctrl;
    33.         Player.Script.transform.position = position;
    34.         Player.Script.transform.rotation = rotation;
    35.     }
     
    siddharth3322 likes this.
  8. Ironmax

    Ironmax

    Joined:
    May 12, 2015
    Posts:
    890
    Just so every one knows. This is not permanent fix for this bug, the bug must be fixed else i see no point on using a newer version of Unity Engine. This leads to all strange things and glitches where the object transform allaround the place and back on Animation controller change.. Animation controller is a pretty core feature in Unity..
     
  9. Eudaimonium

    Eudaimonium

    Joined:
    Dec 22, 2013
    Posts:
    131
    Well, I'd argue there's some significantly worse stuff that needs fixing before this. It's not deal breaking.

    In my RPG, we started off by using a skeleton rig from Third Person Camera asset pack. It got significantly modified with weapon bones, entire animation control code re-written (physics driven instead of root motion etc).

    Some of the work on that rig was done in 3DS Max by me. A friend who is also interested in animating does not have a Max licence, so he's learning to use Blender (to be honest, Blender has way superior animation workflow).

    When he exports an animation from Blender, it's impossible to use "Copy Existing Avatar" from Rig tab in import animation (I mean, you can use it, but it just goes Gmod Idiot Box on you). It's Created anew from import.

    Here's the kicker:
    You cannot put his (Blender) animation into an Animator built from previous Avatar (made in Max). It just shows up blank (idle animation). You cannot mix animations with different avatars in one Animator controller. Sound somewhat logical, yes?

    BUT, if you put his animation into a new Animator controller, and just switch the runtime animator controller via code, it auto-magically works! Animation looks correct, feels correct, skeleton and entire rig is correct. I dunno how, I dunno why.

    Why can't this "retargeting" logic be applied to "Copy Existing Avatar" workflow, I do not know.
     
    Thorlar likes this.
  10. Ironmax

    Ironmax

    Joined:
    May 12, 2015
    Posts:
    890
    When you import a new animation that has the same physics and structure as your old Avatar. you can copy that avatar to your new Humanoid skeleton it works just fine. You dont even need to import the mesh.

    I haven't tried with the new version yet, maybe i can't do that any more ether. I really wonder why i upgrade in the first place..
     
  11. Eudaimonium

    Eudaimonium

    Joined:
    Dec 22, 2013
    Posts:
    131
    Edited the opening post. Velocity from the rigid body also needs to be saved, otherwise it gets lost as well. That's a bit weirder now.
     
  12. Ironmax

    Ironmax

    Joined:
    May 12, 2015
    Posts:
    890
    Man i tell you, your fighting a war you can't win.. the bug war, featured by Unity. My bug report was moved to animations section so i guess this bug is part of the animation now. we suppose to warp to 0 now.. /sarcasm off

    This will always glitch nomatter how much you try to preserve data, you should see what one of my AI mob did when the controlller changed.. Monster was like.."wtf is this player doing".. warping..glitches..I am not even talking about multiplayer issue this also effects. Maybe i should go back to legacy animation..
     
    Last edited: Feb 7, 2017
  13. kdgalla

    kdgalla

    Joined:
    Mar 15, 2013
    Posts:
    4,638
    I just got this too. I submitted a bug report with a repro case. I doesn't happen when I switch the runtimeAnimatorController, but if I switch it and then switch it back, my character instantly pops back to its starting position.
     
  14. HonoraryBob

    HonoraryBob

    Joined:
    May 26, 2011
    Posts:
    1,214
    @Eudaimonium @Ironmax @kdgalla Also changing the avatar at runtime apparently doesn't work. So how do we allow players to switch characters in the middle of the game? There are workarounds I suppose, but in my case it would be a nasty workaround given the way I currently have things set up (since I didn't know about these bugs until now).
     
  15. Ironmax

    Ironmax

    Joined:
    May 12, 2015
    Posts:
    890
    I am pretty sure 5.3.1 did not have this new feature "bug" doesn't look like they even bother to fix it.
     
  16. HonoraryBob

    HonoraryBob

    Joined:
    May 26, 2011
    Posts:
    1,214
    Last edited: May 13, 2017
  17. Ironmax

    Ironmax

    Joined:
    May 12, 2015
    Posts:
    890
    Bump this animation controller issue is still broken in 5.6.1
     
  18. entropicjoey1

    entropicjoey1

    Joined:
    Jun 1, 2014
    Posts:
    26
    Well this is fixrd for unity 2017.1 but had to subscribe to be able to continue publishing to android :(
     
    Last edited: Aug 14, 2017
  19. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    2,517
    Is this still not fixed for 5.6x versions?
     
  20. Ironmax

    Ironmax

    Joined:
    May 12, 2015
    Posts:
    890
  21. skinwalker

    skinwalker

    Joined:
    Apr 10, 2015
    Posts:
    509
    I've been dealing with this for ~7 months (now using 5.6.3), but I only changed the animator controller when I changed the character's transform, so I could change the animator controller first and then the transform, but now I don't have access to that call order, so had to also store the position and rotation before the animator is changed and apply the same pos/rot after, it works nicely, but it's definitely an Unity bug and I will upgrade to Unity 2017 after a month.
     
  22. JotaRata

    JotaRata

    Joined:
    Dec 8, 2014
    Posts:
    61
    I have the same issue even with Root Motion enabled and no rigidbodies, disabling it doesn't work either, I will try your fix.
    Thanks for posting this
     
  23. skinwalker

    skinwalker

    Joined:
    Apr 10, 2015
    Posts:
    509
    It's fixed in Unity 2017.3.1 (can't speak for older versions of 2017).
     
  24. nqtwilford

    nqtwilford

    Joined:
    Jun 17, 2017
    Posts:
    4
    @entropicjoey1
    I'm using Unity 2017.2.0, It haven't fixed. Then I switch to Unity 2018.1.0. This bug still exists.:(
     
  25. skinwalker

    skinwalker

    Joined:
    Apr 10, 2015
    Posts:
    509
    Use the workaround above, it worked for me on Unity 5.
     
  26. nqtwilford

    nqtwilford

    Joined:
    Jun 17, 2017
    Posts:
    4
    I tried, not worked.
     
  27. skinwalker

    skinwalker

    Joined:
    Apr 10, 2015
    Posts:
    509
    So before changing the animator, saving the position/rotation of the game object and after you change the animator, setting that pos/rot doesn't work in unity 2018?
     
  28. nqtwilford

    nqtwilford

    Joined:
    Jun 17, 2017
    Posts:
    4
    Yes, it dosen't work. The position and rotation of game object and all bones didn't changed after applying overrides, but the pose of character goes weird on this frame, the body sinks into ground(height of bone Hips changed). This happens when a transition (A -> B) is interrupted by another transition (B -> C), and overrides applied at same time.