1
votes

I'm trying to control a set of character animations but I'm having trouble with the jump animations. My horizontal walk animations are working fine but when I hit the jump button I want one of two jump animations to play depending on whether the player was in an idle or walking state.

I've set up a bool that updates based on whether my character collider is contacting the ground and I check against to determine when to play the jump animation. However when I press the jump button currently it only plays the first frame of the respective jump animation and then goes right back to either idle or walk. How do I get the entire jump animation to play when the jump button is pressed and the character is airborne?

using UnityEngine;
using System.Collections;

public class AsherBlackMover : MonoBehaviour {

    public float moveSpeed = 3;
    public float rotateSpeed = 10;
    public Transform graphics;
    public SkeletonAnimation skeletonAnimation;
    public Vector2 jumpVector;
    public bool isGrounded;

    // isGrounded Variables
    public Transform grounderPosition;
    public float grounderRadius;
    public LayerMask grounderLayerMask;

    private Rigidbody2D asherBlackRB;
    private Animator asherBlackAnim;

    Quaternion goalRotation = Quaternion.identity;
    float xDir;
    string currentAnimation = "";

    void Start ()
    {
        // Create a reference to Asher Black Rigidbody2D
        asherBlackRB = GetComponent<Rigidbody2D>();
    }

    void Update ()
    {
        xDir = Input.GetAxis ("Horizontal") * moveSpeed;

        if (xDir > 0 && isGrounded == true) // ------ Walk Right
        {
            goalRotation = Quaternion.Euler (0, 0, 0);
            SetAnimation ("Walk", true);
        } 
        else if (xDir < 0 && isGrounded == true) // ------ Walk Left
        {
            goalRotation = Quaternion.Euler (0, 180, 0);
            SetAnimation ("Walk", true);
        }
        else if (isGrounded == true) // ------ Idle
        {
            SetAnimation ("Idle", true);
        }

        // Jump Button
        if (Input.GetKeyDown("space") && isGrounded == true)
        {
            isGrounded = false;
            skeletonAnimation.state.SetAnimation (0, "Idle-Jump", true);

            if (xDir > 0 && isGrounded == false)
            {
                Jump ("Walk-Jump");
            }
            else if (xDir < 0 && isGrounded == false)
            {
                Jump ("Walk-Jump");
            }
            else if (isGrounded == false)
            {
                Jump ("Idle-Jump");
            }
        }

        // Circle on character that determines when grounded or not
        isGrounded = Physics2D.OverlapCircle (grounderPosition.transform.position, grounderRadius, grounderLayerMask);

        // Flip character smothly to emulate paper mario effect
        graphics.localRotation = Quaternion.Lerp (graphics.localRotation, goalRotation, rotateSpeed * Time.deltaTime);
    }

    void OnDrawGizmos ()
    {
        Gizmos.color = Color.yellow;
        Gizmos.DrawWireSphere (grounderPosition.transform.position, grounderRadius);
    }

    void SetAnimation (string name, bool loop)
    {
        if (name == currentAnimation)
        {
            return;
        }
        skeletonAnimation.state.SetAnimation (0, name, loop);
        currentAnimation = name;
    }

    void Jump (string animName)
    {
        asherBlackRB.AddForce (jumpVector, ForceMode2D.Force);
        SetAnimation (animName, true);

        print ("Doing a jump using the " + animName + " animation");
    }

    // Physics Updates
    void FixedUpdate ()
    {
        asherBlackRB.velocity = new Vector2 (xDir, asherBlackRB.velocity.y);
    }
}
1
are you missing a && isGrounded == true in else if (xDir < 0) // ------ Walk Left? - pseudoDust
Thanks for pointing that out @pseudoDust, I updated the code above, although that doesn't fix the specific animation issue I'm having. - greyBow

1 Answers

0
votes

From what I can tell, in the // Jump Button if block you set isGrounded to false, but right after that you set isGrounded based on collision detection:

isGrounded = Physics2D.OverlapCircle (grounderPosition.transform.position, grounderRadius, grounderLayerMask);

When you get to this statement you are still processing the same frame and the character still didn't have time to move isGrounded will be true by the time you get to the end of the update function. On the next update the animation will be reverted to the walk/idle one by the first set of if/else blocks. You might want to put the collision detection statement in an else block for the jump if. This might not be enough though as the time between frames might not be long enough for the character to move far enough away from the ground. In that case you might hold a counter and count, say, 5 frames until you go back to check the collision with the ground.