Search Unity

Changing speed of animation states through code

Discussion in 'Animation' started by Karkazaz, Apr 29, 2015.

  1. Karkazaz

    Karkazaz

    Joined:
    Mar 11, 2014
    Posts:
    32
    Hello.
    I need to be able to change the speed of individual animation states through code. For example, I have a movement speed stat which I want to sync to the walk animation speed. The same for attack speed. I have solved this by making this script.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4.  
    5. public class PlayerAnimationController : MonoBehaviour
    6. {
    7.     Animator anim;
    8.     List<UnityEditor.Animations.AnimatorControllerLayer> layers = new List<UnityEditor.Animations.AnimatorControllerLayer>();
    9.     List<UnityEditor.Animations.AnimatorState> animationsStates_Base = new List<UnityEditor.Animations.AnimatorState>();
    10.     List<UnityEditor.Animations.AnimatorState> animationsStates_Attack = new List<UnityEditor.Animations.AnimatorState>();
    11.     PlayerStats playerstats;
    12.  
    13.     void Start ()
    14.     {
    15.         anim = GetComponent<Animator>();
    16.  
    17.         if (anim != null)
    18.         {
    19.             UnityEditor.Animations.AnimatorController ac = (UnityEditor.Animations.AnimatorController)anim.runtimeAnimatorController;
    20.             foreach(UnityEditor.Animations.AnimatorControllerLayer acl in ac.layers)
    21.             {
    22.                 layers.Add(acl);
    23.             }
    24.  
    25.             // Base layer states
    26.             foreach(UnityEditor.Animations.ChildAnimatorState s in layers[0].stateMachine.states)
    27.             {
    28.                 animationsStates_Base.Add(s.state);
    29.             }
    30.  
    31.             // Attack layer states
    32.             foreach(UnityEditor.Animations.ChildAnimatorState s in layers[1].stateMachine.states)
    33.             {
    34.                 animationsStates_Attack.Add(s.state);
    35.             }
    36.         }
    37.  
    38.         playerstats = Player.player.GetComponent<PlayerStats>();
    39.     }
    40.  
    41.     void Update ()
    42.     {
    43.         foreach(UnityEditor.Animations.AnimatorState state in animationsStates_Base)
    44.         {
    45.             if(state.name == "Walk")
    46.             {
    47.                 state.speed = playerstats.m_stat["movement_speed"];
    48.             }
    49.         }
    50.  
    51.         foreach(UnityEditor.Animations.AnimatorState state in animationsStates_Attack)
    52.         {
    53.             if(state.name == "Attack 1")
    54.             {
    55.                 state.speed = playerstats.m_stat["attack_speed"];
    56.             }
    57.         }
    58.     }
    59. }
    This works great. But when I am trying to build this, I fail because there is no UnityEditor outside the Unity editor. So I need to change almost everything, but I really can not find a way to change animation states speed. Is there a solution for this?
     
    Last edited: Apr 29, 2015
  2. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    This is a new feature in 5.1, in previous version you coudn't change state speed at runtime.
     
  3. Karkazaz

    Karkazaz

    Joined:
    Mar 11, 2014
    Posts:
    32
    But there is no way to change the speed of an animation state during runtime without using things from the UnityEditor namespace. Is this true? EDIT: I am using the most current version of Unity, which is 5.0.1f1. EDIT 2: Oh I think you mean the Beta? Because I cant find any versions with 5.1.x. I am going to download that and I will reply if I encounter the same problem.
     
    Last edited: Apr 29, 2015
  4. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    You can't use UnityEditor namespace at runtime, that why we did a new feature to support this in 5.1

    see this thread for more information
    http://forum.unity3d.com/threads/ru...ties-speed-mirror-cycleoffset-for-5-1.307521/

    5.1 is in beta right now so you have to be on the beta list to get access to it.
     
  5. Karkazaz

    Karkazaz

    Joined:
    Mar 11, 2014
    Posts:
    32
    Aha, that is really unfortunately because I need it for one little thing. How long do you think it takes for the 5.1 to become public?
     
  6. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    The goal is to ship 5.1 in the beginning of summer if everything goes well.
     
  7. Karkazaz

    Karkazaz

    Joined:
    Mar 11, 2014
    Posts:
    32
    Ok. I know asset that will make this work. How are they achieving this? Would you want to tell me how I should tweak Unity so I will be able to change the speed parameter
     
  8. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    I'm not sure I understand what you mean, you are asking for some documentation on this new feature to prepare your self for 5.1?
    the only doc we have so far is this one
    http://forum.unity3d.com/threads/ru...ties-speed-mirror-cycleoffset-for-5-1.307521/
     
  9. ExOblivione

    ExOblivione

    Joined:
    Jul 7, 2014
    Posts:
    8
  10. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    You can control your state speed with controller's parameter.

    First create a new float parameter 'mySpeed' in your controller.
    Select your state and set speed Multiplier to your new float parameter 'mySpeed'
    At runtime you need to write into your controller parameter 'mySpeed' to modify your state speed.
    speed.png
     
    hybrid_dragon, LohQ, wertunit and 2 others like this.
  11. ExOblivione

    ExOblivione

    Joined:
    Jul 7, 2014
    Posts:
    8
    Thank you very much for the reply. So now it sounds like what I want to do is possible. The main issue I'm having is getting a reference to the parameter.

    I have a spawner script that gets enemies from an object pool. I set variables upon making the enemies active. I want to be able to set the anim speed to control the speed increase over the course of waves of enemies. How would I access each controllers parameter 'mySpeed' to modify the state speed?

    Here is a snippet showing how I am spawning and changing a few items now.

    Code (JavaScript):
    1. function SpawnWaves2 () {
    2.  
    3.          
    4.         var fastZombie = poolManager.GetComponent(PoolManager).GetPooledFastZombies(GameObject);
    5.                                        
    6.         var spawnPositions : Array = [Vector3(-spawnValuesL.x, spawnValuesL.y, Random.Range (-spawnValuesL.z, spawnValuesL.z)),
    7.                                 Vector3(Random.Range (-spawnValuesT.x, spawnValuesT.x), spawnValuesT.y, spawnValuesT.z),
    8.                                 Vector3(spawnValuesR.x, spawnValuesR.y, Random.Range (-spawnValuesR.z, spawnValuesR.z)),
    9.                                 Vector3(Random.Range (-spawnValuesB.x, spawnValuesB.x), spawnValuesB.y, -spawnValuesB.z)];
    10.                                            
    11.                fastZombie.transform.position = spawnPositions[Random.Range(0,4)];
    12.                fastZombie.transform.rotation = Quaternion.identity;
    13.                fastZombie.transform.LookAt(target);
    14.                //fastZombie.GetComponent(NavMeshAgent).speed = chaseSpeed;
    15.                fastZombie.SetActive(true);
     
  12. ExOblivione

    ExOblivione

    Joined:
    Jul 7, 2014
    Posts:
    8
    I got it! Little more research after your answer:

    Code (JavaScript):
    1. var zombieAnim = zombie.GetComponent(Animator);
    2.  
    3. zombieAnim.SetFloat("zSpeed", chaseSpeed);
    Thanks!
     
    asagigeechs likes this.