Search Unity

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.     }