Search Unity

  1. Check out the Unite LA keynote for updates on the Visual Effect Editor, the FPS Sample, ECS, Unity for Film and more! Watch it now!
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. Improved Prefab workflow (includes Nested Prefabs!), 2D isometric Tilemap and more! Get the 2018.3 Beta now.
    Dismiss Notice
  4. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice
  5. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice

Override animation frames

Discussion in 'Animation' started by nanocba83, Nov 8, 2018.

  1. nanocba83


    Feb 20, 2018
    I'm developing a tennis game and now I'm trying to sync my player's swing when impacting the ball. I have only one animation for now, but it's enough for what I'm trying to achieve at the moment.

    Basically, I would like to change the default animation at runtime so I can reduce the gap between the racket and the ball at the time of impact. Right now I'm setting a threshold that if the ball is at certain distance of it, then it's considered a hit. That threshold it's too big to make it look realistic.

    I've tried IK with no good results. I wonder at this point if IK is really the way to go as it would seem that it would require far more calculations and complexity if it is possible at all. I wonder if there's a simpler approach I could try.

    Also I'm not sure if I'm not obtaining good results with IK because of the animation itself that wasn't really prepared for this. If that could be the case, may I also wonder what are best practices to have animations that work seamlessly with an IK pass?

    Code (CSharp):
    1. //a callback for calculating IK
    2.     void OnAnimatorIK() {
    3.         if (animator) {
    5.             //if the IK is active, set the position and rotation directly to the goal.
    6.             if (ikActive) {
    8.                 // Set the right hand target position and rotation, if one has been assigned
    9.                 if (ball != null) {
    11.                     Vector3 currentPosition = animator.GetIKPosition(AvatarIKGoal.RightHand);
    13.                     //The avatar the IK is running on
    14.                     GameObject avatar = this.gameObject;
    16.                     //Distance from avatar to ball
    17.                     float distanceToBall = Vector3.Distance(racket.transform.position, ball.position);
    19.                     //Weight will be close to 1 as ball gets closer to the avatar
    20.                     float weight = 1 - Mathf.Max(Mathf.Min(distanceToBall / 50, 1), 0);
    22.                     //Set IK target weight
    23.                     animator.SetIKPositionWeight(AvatarIKGoal.RightHand, weight);
    25.                     //Set IK target
    26.                     animator.SetIKPosition(AvatarIKGoal.RightHand, new Vector3(currentPosition.x + 10, currentPosition.y, currentPosition.z));
    27.                 }
    29.             }
    31.             //if the IK is not active, set the position and rotation of the hand and head back to the original position
    32.             else {
    33.                 animator.SetIKPositionWeight(AvatarIKGoal.RightHand, 0);
    34.             }
    35.         }
    36.     }