GetKeyDown输入仅播放动画的第一帧

时间:2015-12-30 17:33:24

标签: c# animation unity3d

我正在尝试控制一组角色动画,但我遇到了跳跃动画的问题。我的水平步行动画工作正常但是当我按下跳跃按钮时,我希望根据玩家是处于空闲还是行走状态来播放两个跳跃动画中的一个。然而,当我按下跳跃按钮时,它只播放相应跳跃动画的第一帧,然后再回到空闲或步行。如何在按下跳转按钮时播放整个跳跃动画?

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;
    float yDir;
    string currentAnimation = "";

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

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

        if (xDir > 0) // ------ Walk Right
        {
            goalRotation = Quaternion.Euler (0, 0, 0);
            SetAnimation ("Walk", true);
        } 
        else if (xDir < 0) // ------ 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;

            if (xDir > 0)
            {
                Jump ("Walk-Jump");
            }
            else if (xDir < 0)
            {
                Jump ("Walk-Jump");
            }
            else
            {
                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 animationName)
    {
        asherBlackRB.AddForce (jumpVector, ForceMode2D.Force);
        SetAnimation (animationName, true);
    }

    // Physics Updates
    void FixedUpdate ()
    {
        asherBlackRB.velocity = new Vector2 (xDir, asherBlackRB.velocity.y);
    }
}

2 个答案:

答案 0 :(得分:2)

您的跳跃动画无法正确显示,因为您总是在下一帧将其更改回另一个动画。例如,空转:

else
{
    SetAnimation ("Idle", true);

    if (Input.GetKeyDown("space"))
    {
        SetAnimation ("Idle-Jump", true);
    }
}

角色空闲的每一帧,无论角色是否跳跃,都会设置空闲动画。但是,只要按住空格键,它就会被换回到跳跃动画的第一帧。

你应该有一个布尔值来指示角色何时跳跃。只要将角色设置为跳跃动画,就可以将其设置为true。然后你可以调整你的if语句,这样它处理的第一件事就是处于跳跃状态的角色,这样你的跳跃逻辑就可以在没有任何干扰的情况下完成。当角色完成跳跃时,将布尔值设置为false。所以,像:

bool jumping = false;

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

    if (jumping)
    {
        // Process jumping here
        if (/* Check for jumping finished here */)
        {
            // Finished jumping
            jumping = false;
        }
    }
    else if (xDir > 0)
    {
        goalRotation = Quaternion.Euler (0, 0, 0);
        SetAnimation ("Walk", true);

        if (Input.GetKeyDown("space"))
        {
            SetAnimation ("Walk-Jump", true);
            jumping = true;
        }
    } 
    else if (xDir < 0)
    {
        goalRotation = Quaternion.Euler (0, 180, 0);
        SetAnimation ("Walk", true);

        if (Input.GetKeyDown("space"))
        {
            SetAnimation ("Walk-Jump", true);
            jumping = true;
        }
    }
    else
    {
        SetAnimation ("Idle", true);

        if (Input.GetKeyDown("space"))
        {
            SetAnimation ("Idle-Jump", true);
            jumping = true;
        }
    }

    graphics.localRotation = Quaternion.Lerp (graphics.localRotation, goalRotation, rotateSpeed * Time.deltaTime);
}

答案 1 :(得分:0)

将GetKeyDown更改为GetKey。

如Unity输入文档here中所述, GetKeyDown在按下键的帧期间触发一次。只要按下按钮,GetKey就会继续激活。