- Home /
 
stop animation on a single joint?
Is there a way to tell one joint in an animated character to stop? For example, a shoulder (elbow, wrist...) of an arm holding something should stop swinging with the run cycle and just stay out in front of the character. Thanks!
Answer by MaDDoX · Nov 30, 2010 at 08:30 PM
Your best bet there is simply overriding the animation (ie. in LateUpdate) with something to re-aim your arm to a desired target. I've done a half-baked script that allows me to do just that. Of course you'll have to set a way to toggle and untoggle the script for the animations where you don't want the arm re-aiming forward, you can for instance use triggers in animation clips - ctrl+D them if they're imported to make them editable in the animation window. I've tried the script provided in the FPS example (from the Unity3D site) but I found it too tied to their specific setup, so it wouldn't suit me.
Here goes my script, to set it up what I do is simply drag'ndrop an empty gameobject there and move it around interactively in the editor window (while the game's running) plus tweak the "twist" settings until I find the right resulting orientation for the joint (right forearm in my case). Then i write the coordinates down and set it again out of playtime. Kinda of a lame "designer code" solution I know, but it works heh :) If someone can code a more elegant way to do this, please return the favor - even if this was useful just as inspiration - and share k? Good luck!
 using UnityEngine;
 using System.Collections;
 public class AimFix : MonoBehaviour
 {
 
 public Transform target;
 public Transform joint;
 public bool smooth = true;
 public float effect = 1; //6
 public Vector3 twist = Vector3.zero;
 
 private Vector3 targetPos;
 private Quaternion _finalrotation; 
 
 void LateUpdate ()
 {    
     if (effect <= 0) return;
     if (target)
     {
         if (smooth)
         {   // Look at and dampen the rotation
             Vector3 lerpedRotation_e = Vector3.zero;
             Quaternion aimRotation_q;
 
             targetPos = target.position;
             targetPos.y = joint.position.y;
             targetPos.z = -targetPos.z;
             aimRotation_q = Quaternion.LookRotation(joint.position - targetPos);
 
             lerpedRotation_e.x = Mathf.Lerp(lerpedRotation_e.x, aimRotation_q.eulerAngles.x, effect * Time.deltaTime);
             lerpedRotation_e.y = Mathf.Lerp(lerpedRotation_e.y, aimRotation_q.eulerAngles.y, effect * Time.deltaTime); 
             lerpedRotation_e.z = Mathf.Lerp(lerpedRotation_e.z, aimRotation_q.eulerAngles.z, effect * Time.deltaTime);
 
 
             _finalrotation = Quaternion.Euler(lerpedRotation_e.x + twist.x, lerpedRotation_e.y + twist.y, lerpedRotation_e.z + twist.z);
             joint.rotation = _finalrotation;
         }
         else
         {   // Just lookat
             joint.LookAt(target);
         }
     }
 }
 }
 
              Your answer