简体   繁体   中英

Playing a 2d animation before flipping a sprite in Unity c#

I was actually able to do this with an enemy but for some reason I can't get it to work if it's the player.

See, the player is in a default, idle animation. When I press the arrow key from the opposite direction its facing at (default is the right when game starts -->), I want it to play a turning animation before the sprite flips over its x scale.

However what it's doing right now when I press the arrow key to turn him, is that firstly, it quickly flips the sprite over, then performs the animation as if it hadn't been flipped yet, then flips over to the other direction again.

In my animator, the idle has no exit time to the flip node and the flip node does have an exit time back to idle, just in case you would inquire. I've tried invoking a timer here and there as well but so far no luck. Can anyone help please?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class tulMoveMount : MonoBehaviour {

    private Animator anim;
    private Rigidbody2D rb;
    public Image manaBar;

    public LayerMask whatIsGround;
    private bool grounded = false;
    public Transform groundCheck;
    public float groundCheckRadius;

    private bool goRight = true;
    private bool jump;
    private bool turn = false;
    private bool idle = true;
    private bool mountOff;
    private bool turnComplete = false;  

    public float runSpeed;
    public float walkSpeed; 
    private float move; 
    public float turnDelay = 2.25f;     
    public float timer3 = 2.26f;

    void Start ()
    {
        anim = GetComponent<Animator>();
        rb = GetComponent<Rigidbody2D>();
    }

    void Update () 
    {
        grounded = Physics2D.OverlapCircle (groundCheck.position, groundCheckRadius, whatIsGround);
        timer -= Time.deltaTime;
        turnDelay -= Time.deltaTime;
        HandleMovement ();

    }

    void HandleMovement()
    {

        float move = Input.GetAxis ("Horizontal");
        float moveV = Input.GetAxis ("Vertical");

        {
            rb.velocity = new Vector2 (move * walkSpeed, rb.velocity.y);

            anim.SetFloat ("walkSpeed", Mathf.Abs (move));

        }

        if (!goRight && move > 0) {
            FlipConditions ();
            Invoke ("ResetValues",timer3 );
            Flip ();
            turnComplete = false;
        }
        if (goRight && move < 0) {
            FlipConditions ();
            Invoke ("ResetValues",timer3 );
            Flip ();
        }
    }

    void FlipConditions()//
    {
        idle = false;
        turn = true;
        anim.SetTrigger ("turn");
        idle = true;
        anim.SetTrigger ("idle");
    }

    void Flip()
    {
        goRight = !goRight;
        Vector3 theScale = transform.localScale;
        theScale.x *= -1;
        transform.localScale = theScale;
        turnComplete = false;
    }
    void ResetValues()
    {
        idle = true;
        anim.SetTrigger ("idle");
    }
}

You can try to flip the sprite in LateUpdate() after you perform perform any animation in Update() . Try something like that, placing the animation in Update:

// store references to components on the gameObject
Transform _transform;
Rigidbody2D _rigidbody;

// hold player motion in this timestep
float vx;
float vy;

float MoveSpeed;

void Awake () {

    // get a reference to the components we are going to be changing and store a reference for efficiency purposes
    transform = GetComponent<Transform> ();

    rigidbody = GetComponent<Rigidbody2D> ();

}

// this is where most of the player controller magic happens each game event loop
void Update()
{
    // determine horizontal velocity change based on the horizontal input
    vx = Input.GetAxisRaw ("Horizontal");

    // get the current vertical velocity from the rigidbody component
    vy = rigidbody.velocity.y;

    // Change the actual velocity on the rigidbody
    rigidbody.velocity = new Vector2(vx * MoveSpeed, vy);
}

// Checking to see if the sprite should be flipped
// this is done in LateUpdate since the Animator may override the localScale
// this code will flip the player even if the animator is controlling scale
void LateUpdate()
{
    // get the current scale
    Vector3 localScale = transform.localScale;

    if (vx > 0) // moving right so face right
    {
        facingRight = true;
    } else if (vx < 0) { // moving left so face left
        facingRight = false;
    }

    // check to see if scale x is right for the player
    // if not, multiple by -1 which is an easy way to flip a sprite
    if (((facingRight) && (localScale.x<0)) || ((!facingRight) && (localScale.x>0))) {
        localScale.x *= -1;
    }

    // update the scale
    transform.localScale = localScale;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM