【问题标题】:How to delay movement in unity while animation plays如何在动画播放时统一延迟移动
【发布时间】:2019-07-31 23:10:28
【问题描述】:

我在 Unity 2018.4 中延迟我的角色移动时遇到了困难,我怀疑这更像是我的代码与 unity 相对的问题。

编辑: 我希望能够按住右箭头键,让角色415ms不动,然后能够移动580ms,之后他不能移动350ms(让动画播放完毕)

我尝试在 IE 分子中使用倒计时等待然后调用我的移动函数,但这会导致我的角色在动画播放后不移动。

//What makes the character move, works fine if executed on its own in update
private void ExecuteMovement(float dir)
    {
        currentPosition = transform.position;
        currentPosition.x += dir * Time.deltaTime * speed;
        transform.position = currentPosition;
    }

//Trying to use waitforseconds to delay the execution while the animation plays
private IEnumerator Movement(float dir)
    {
        yield return new WaitForSeconds(0.5f);

        ExecuteMovement(dir);
    }

void Update()
    {
        if (0 > Input.GetAxis("Horizontal"))
        {
            //This is to flip image
            transform.eulerAngles = new Vector3(0, 180, 0);

            //starts animation
            animator.SetBool("isSkipping", true);

            //calls the movement function with the direction to move in
            Movement(Input.GetAxis("Horizontal"));

        }

        else if (0 < Input.GetAxis("Horizontal"))
        {
            //This is to flip image
            transform.eulerAngles = new Vector3(0, 0, 0);

            //starts animation
            animator.SetBool("isSkipping", true);

            //calls the movement function with the direction to move in
            Movement(Input.GetAxis("Horizontal"));

        }
    }

我很乐意尝试任何其他方法来延迟角色的移动。动画显示角色充电跳跃然后跳跃。我只想在动画大约半秒后在空中移动。

【问题讨论】:

    标签: c# unity3d wait


    【解决方案1】:

    您正试图像调用方法一样调用您的IEnumerator


    相反,您必须使用StartCoroutine 将其作为Coroutine 启动

    StartCoroutine(Movement(Input.GetAxis("Horizontal")));
    

    看到你的编辑

    我希望能够按住右箭头键,让角色在 415 毫秒内不动,然后在 580 毫秒内可以移动,然后在 350 毫秒内不能移动(让动画播放完毕)

    直到现在,既然你想要一个持续的运动但仍然完全控制速度,我会将它保留在Update 中,并且只使用协程来控制一个标志。协程在读/写和维护方面仍然更好。 (现在它还允许在空中切换方向..不确定你是否想要这个):

    // control the ability to move with a simple flag
    // instead of various states
    public bool canMove;
    
    // check if a jumping is already being animated/executed 
    // -> disallow a new jumping animation until it is finished
    private bool canJump = true;
    
    private void Update()
    {
        // avoid repeated API calls
        var input = Input.GetAxis("Horizontal");
    
        if (input < 0)
        {
            //This is to flip image
            transform.eulerAngles = new Vector3(0, 180, 0);
    
            if(canJump)
            {
                //starts the movement
                StartCoroutine(Jump());
            }
        }
        else if (input > 0)
        {
            //This is to flip image
            transform.eulerAngles = new Vector3(0, 0, 0);
    
            if(canJump)
            {
                //starts the movement
                StartCoroutine(Jump());
            }
        }
    
        // if can not move do nothing else
        if(!canMove) return;
    
        // execute the movement
        transform.position += Vector3.right * input * speed * Time.deltaTime;
    }
    
    private IEnumerator Jump()
    {
        // disable jumping
        canJump = false;
    
        // disable move during animation
        canMove = false;
    
        //starts animation
        animator.SetBool("isSkipping", true);
    
        // not move for 415ms
        yield return new WaitForSeconds(0.415f);
    
        // enable move
        canMove = true;
    
        // be able to move for 580ms
        yield return new WaitForSeconds(0.580f);
    
        // disable move
        canMove = false;
    
        // cannot move for 350ms during end of animation
        yield return new WaitForSeconds(0.350f);
    
        // enable move again
        canMove = true;
    
        // re-enable jumping
        canJump = true;
    }
    

    【讨论】:

    • 我用新的编辑更新了我的代码,但现在我的角色只翻转图像。动画不播放,角色无法移动……
    • 是的,我很傻 ;) 使用 private bool canJump = true; 应该这样做。我上次更新后总是false
    【解决方案2】:

    在更新中使用计时器怎么样?

    float timer = 0f;
    void Update()
    {
        var dir = Input.GetAxis("Horizontal");
        if (0 > dir)
        {
            //This is to flip image
            transform.eulerAngles = new Vector3(0, 180, 0);
    
            //starts animation
            animator.SetBool("isSkipping", true);
    
            //calls the movement function with the direction to move in
            timer +=Time.deltaTime;
            if(timer >= 0.5){
               ExecuteMovement(dir);
               timer -=0.5f;
            }
            //Movement(Input.GetAxis("Horizontal"));
    
        }
    
        else if (0 < dir)
        {
            //This is to flip image
            transform.eulerAngles = new Vector3(0, 0, 0);
    
            //starts animation
            animator.SetBool("isSkipping", true);
    
            //calls the movement function with the direction to move in
            timer +=Time.deltaTime;
            if(timer >= 0.5){
               ExecuteMovement(dir);
               timer -=0.5f;
            }
            //Movement(Input.GetAxis("Horizontal"));
    
        }
    }
    

    【讨论】:

    • 这似乎使动作变得紧张而随意。 unity 角色在空中移动并不顺畅,它只是瞬间移动精灵。也许我的措辞不正确?我希望能够按住右箭头键,让角色在 415 毫秒内不动,然后在 580 毫秒内能够移动,然后在 350 毫秒内不能移动(让动画播放完毕)
    【解决方案3】:

    在大量修改 Gray_Rhino 对这个问题的回答后,我发现了一种相当粗糙的方法来完成这项工作。我设置了跳跃动画的 3 个阶段,当不断向一个方向移动时,计时器将检查动画的距离并决定是否允许移动输入。动画结束或角色被告知向另一个方向移动后,计时器会重置。

    bool facingRight;
        int jumpPhase = 1;
        float timer = 0f;
        float dir;
        void Update()
        {
            if (jumpPhase != 3)
            {
                dir = Input.GetAxis("Horizontal");
            }
    
            if (0 > dir || (jumpPhase == 3 && facingRight == true))
            {
                timer += Time.deltaTime;
    
                if (facingRight != true)
                {
                    transform.eulerAngles = new Vector3(0, 180, 0);
                    jumpPhase = 1;
                    timer = 0f;
                    facingRight = true;
                }
    
                else if (jumpPhase == 1)
                {
                    //starts animation
                    animator.SetBool("isSkipping", true);
    
                    if (timer >= 0.415f)
                    {
                        jumpPhase = 2;
                    }
                }
    
                else if (jumpPhase == 2)
                {
                    ExecuteMovement(dir);
    
                    if (timer >= 0.995f)
                    {
                        jumpPhase = 3;
                    }
                }
    
                if (jumpPhase == 3)
                {
                    if (timer >= 1.5f)
                    {
                        jumpPhase = 1;
                        timer = 0f;
                    }
                }
    
            }
    
            else if (0 < dir || (jumpPhase == 3 && facingRight != true))
            {
                timer += Time.deltaTime;            
    
                if (facingRight == true)
                {                
                    transform.eulerAngles = new Vector3(0, 0, 0);
                    jumpPhase = 1;
                    timer = 0f;
                    facingRight = false;
                }
    
                else if (jumpPhase == 1)
                {
                    //starts animation
                    animator.SetBool("isSkipping", true);
    
                    if (timer >= 0.415f)
                    {
                        jumpPhase = 2;
                    }
                }
    
                else if (jumpPhase == 2)
                {
                    ExecuteMovement(dir);
    
                    if (timer >= 0.995f)
                    {
                        jumpPhase = 3;
                    }
                }
    
                if (jumpPhase == 3)
                {
                    if (timer >= 1.5f)
                    {
                        jumpPhase = 1;
                        timer = 0f;
                    }
                }
    
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-08-03
      • 2013-04-07
      • 2015-08-31
      • 2014-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多