Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Animation parameters jumping around at idle

Discussion in 'Animation' started by uberalles, Jan 11, 2014.

  1. uberalles

    uberalles

    Joined:
    Jun 29, 2013
    Posts:
    46
    I went through the Stealth project and using that setup I created a small test where the user simply right-clicks a spot and the character walks over to that position. There are two problems though, one is that the character runs the last few steps (he walks at a slow pace the whole way there) and second is when he reaches the destination the two float parameters in the animator controller (Speed and AngularSpeed) start jumping in value (see image).

    $animator_Screen.jpg

    I've posted some code but if you've been through the Stealth project hopefully you've seen some of it before.
    This simply sends the character to the desired position:
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class UnitMovement : MonoBehaviour {
    6.  
    7.     RaycastHit hit;
    8.     private NavMeshAgent nav;
    9.     public float turnSmoothing = 15f;
    10.     public float spdDampTime = 0.1f;
    11.  
    12.     private Animator anim;
    13.     void Awake () {
    14.         anim = GetComponent<Animator>();
    15.         anim.SetLayerWeight(0,1f);
    16.         nav = GetComponent<NavMeshAgent>();
    17.     }
    18.     void Update () {
    19.         Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    20.         if(Physics.Raycast(ray, out hit,5000))
    21.         {
    22.             if(Input.GetMouseButtonUp(1))
    23.             {
    24.                 MovementManagement(hit.point);
    25.             }
    26.         }
    27.  
    28.     }
    29.  
    30.     void MovementManagement(Vector3 dest)
    31.     {
    32.         nav.speed = 2f;
    33.         nav.angularSpeed = 5f;
    34.         nav.destination = dest;
    35.  
    36.     }
    37. }
    38.  
    39.  
    This handles the animations:
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class MovementAnimation : MonoBehaviour
    6. {
    7.     public float deadZone = 5f;             // The number of degrees for which the rotation isn't controlled by Mecanim.
    8.    
    9.  
    10.     private NavMeshAgent nav;               // Reference to the nav mesh agent.
    11.     private Animator anim;                  // Reference to the Animator.
    12.  
    13.     private AnimStarter animSetup;        // An instance of the AnimatorSetup helper class.
    14.    
    15.    
    16.     void Awake ()
    17.     {
    18.         // Setting up the references.
    19.  
    20.         nav = GetComponent<NavMeshAgent>();
    21.         anim = GetComponent<Animator>();
    22.  
    23.        
    24.         // Making sure the rotation is controlled by Mecanim.
    25.         nav.updateRotation = false;
    26.        
    27.         // Creating an instance of the AnimatorSetup class and calling it's constructor.
    28.         animSetup = new AnimStarter(anim);
    29.        
    30.         // Set the weights for the shooting and gun layers to 1.
    31.         //anim.SetLayerWeight(1, 1f);
    32.         //anim.SetLayerWeight(2, 1f);
    33.        
    34.         // We need to convert the angle for the deadzone from degrees to radians.
    35.         deadZone *= Mathf.Deg2Rad;
    36.     }
    37.    
    38.    
    39.     void Update ()
    40.     {
    41.         // Calculate the parameters that need to be passed to the animator component.
    42.         NavAnimSetup();
    43.     }
    44.    
    45.    
    46.     void OnAnimatorMove ()
    47.     {
    48.         // Set the NavMeshAgent's velocity to the change in position since the last frame, by the time it took for the last frame.
    49.         nav.velocity = anim.deltaPosition / Time.deltaTime;
    50.        
    51.         // The gameobject's rotation is driven by the animation's rotation.
    52.         transform.rotation = anim.rootRotation;
    53.     }
    54.    
    55.    
    56.     void NavAnimSetup ()
    57.     {
    58.         // Create the parameters to pass to the helper function.
    59.         float speed;
    60.         float angle;
    61.  
    62.             // the speed is a projection of desired velocity on to the forward vector...
    63.             speed = Vector3.Project(nav.desiredVelocity, transform.forward).magnitude;
    64.            
    65.             // ... and the angle is the angle between forward and the desired velocity.
    66.             angle = FindAngle(transform.forward, nav.desiredVelocity, transform.up);
    67.            
    68.             // If the angle is within the deadZone...
    69.             if(Mathf.Abs(angle) < deadZone)
    70.             {
    71.                 // ... set the direction to be along the desired direction and set the angle to be zero.
    72.                 transform.LookAt(transform.position + nav.desiredVelocity);
    73.                 angle = 0f;
    74.             }
    75.  
    76.        
    77.         // Call the Setup function of the helper class with the given parameters.
    78.         animSetup.Setup(speed, angle);
    79.     }
    80.    
    81.    
    82.     float FindAngle (Vector3 fromVector, Vector3 toVector, Vector3 upVector)
    83.     {
    84.         // If the vector the angle is being calculated to is 0...
    85.         if(toVector == Vector3.zero)
    86.             // ... the angle between them is 0.
    87.             return 0f;
    88.        
    89.         // Create a float to store the angle between the facing of the enemy and the direction it's travelling.
    90.         float angle = Vector3.Angle(fromVector, toVector);
    91.        
    92.         // Find the cross product of the two vectors (this will point up if the velocity is to the right of forward).
    93.         Vector3 normal = Vector3.Cross(fromVector, toVector);
    94.        
    95.         // The dot product of the normal with the upVector will be positive if they point in the same direction.
    96.         angle *= Mathf.Sign(Vector3.Dot(normal, upVector));
    97.        
    98.         // We need to convert the angle we've found from degrees to radians.
    99.         angle *= Mathf.Deg2Rad;
    100.        
    101.         return angle;
    102.     }
    103. }
    104.  
    Any help would be greatly appreciated.
     
  2. uberalles

    uberalles

    Joined:
    Jun 29, 2013
    Posts:
    46
    Sorry to bump this one, but I'm really stuck.
     
  3. disorganized

    disorganized

    Joined:
    Jan 11, 2014
    Posts:
    29
    I have to admit I was being dumb 'cause I didn't check the speed through scripting (until recently) and both speed and angle drop to zero once it reaches its destination. However, in the animator window you see the values still jump. Is there still something going on 'behind the scenes' within Unity and could it be a slight performance drain?