动画播放一帧,然后返回混合树运动。仅在一个对象上

Posted

技术标签:

【中文标题】动画播放一帧,然后返回混合树运动。仅在一个对象上【英文标题】:Animation plays for one frame, then back to blend tree locomotion. ONLY ON AN OBJECT 【发布时间】:2021-02-11 19:54:05 【问题描述】:

我正在尝试制作像《黑暗之魂》这样的游戏,其中有一个可以滚动和冲刺的角色。使用光线投射实现跌倒机制后(如果没有地面检测跌倒;如果已经跌倒则播放动画)Here

这是为了阻止玩家在空中四处走动......假设他离开了边缘并且重力正在慢慢地将他向下漂移。

虽然他正在漂流并且仍然可以四处移动,但他可以很好地滚动和后退(他应该是摔倒了)。虽然当他落在任何物体上时,他将无法滚动或后退。随便走走冲刺(运动混合树)与下一段相同的问题

当移动 isInAir 变量=true 时,在 if 语句之外,但仍然* 在 else 块内,该块确保玩家是否正在坠落。然后下降动画将起作用。 坠落动画作品,赞!但现在我在一个无法完成动画的对象上。 Here

顺便说一句——crossFade 设置为零(在 animationHandler.PlayTargetAnimation 函数内)以达到这一点,否则我的动画帧将在运动混合树上冻结,同时仍然能够四处移动而不是滚动(不是甚至覆盖一个人的距离)

STUCK ON THIS FRAME IF I TRY TO ROLL WHILE ON THE GROUND. I CAN WALK AROUND BUT ROLLING FREEZES ME IN LOCOMOTION

控制台记录目标动画以及玩家是否跌倒。两者都是准确的......

TLDR -- 玩家在任何物体上都无法完成动画

动画 ANIMATIONS

脚本 SCRIPTS

这实际上来自一个视频教程系列,此代码是逐字记录但无法正常工作...除了一些日志和分配 isInAir 位置的更改之外,它的代码相同。 参考:https://www.youtube.com/playlist?list=PLD_vBJjpCwJtrHIW1SS5_BNRk6KZJZ7_d

我完全注释掉了这个功能,现在我在没有动画的情况下以缓慢的速度摔倒,但至少我可以在地面上滚动!

    public void HandleFalling(float delta , Vector3 moveDirection)
    
        
        playerManager.isGrounded = false;
        RaycastHit hit;
        Vector3 origin = myTransform.position;
        origin.y += groundDetectionRayStartPoint;



        //IF SOMETHING IS DIRECTLY IN FRONT OF YOU, YOURE NOT MOVING
        if (Physics.Raycast(origin , myTransform.forward , out hit ,0.6f))
        
            moveDirection = Vector3.zero;
        



        if(playerManager.isInAir)
        
            rigidbody.AddForce(-Vector3.up * fallSpeed);
            rigidbody.AddForce(moveDirection * fallSpeed / 10f );
        

        Vector3 dir = moveDirection;
        dir.Normalize();
        origin =  origin + dir * groundDirectionRayDistance;
        targetPosition = myTransform.position;

        //DEBUGGER
        Debug.DrawRay(origin , -Vector3.up * minimumDistanceToBeginFall, Color.red , 0.1f , false);

        //grounded
        if (Physics.Raycast(origin , -Vector3.up , out hit , minimumDistanceToBeginFall , ignoreForGroundCheck)) 
        
            

            normalVector = hit.normal;
            Vector3 tp = hit.point;
            playerManager.isGrounded = true;
            targetPosition.y = tp.y;

            if (inAirTimer > 0.5f)
            
                Debug.Log("you were in the air for " + inAirTimer);
                animatorHandler.PlayTargetAnimation("Unarmed-Land" , false);
                inAirTimer = 0;
            
            else
            
                animatorHandler.PlayTargetAnimation("Locomotion" , false);
                inAirTimer = 0;
            

            playerManager.isInAir = false;


        
        else //falling
        
            Debug.Log("falling");
            
            playerManager.isInAir = true; //added to fix fall animation bug   *******************


            if (playerManager.isGrounded)
            
                playerManager.isGrounded = false;
            
            
            
            if (playerManager.isInAir == true)
            
               if (playerManager.isInteracting == false)
               
                   animatorHandler.PlayTargetAnimation("Falling" , true);
               
               
               Vector3 vel = rigidbody.velocity;
               vel.Normalize();
               rigidbody.velocity = vel * (movementSpeed/2);


                // if commented from the top and uncommented here, then rolls work but fall doesnt *******************
                //    playerManager.isInAir = true; 

                //When player is touching ground no matter what is commented out from above, PLAYER CANNOT ROLL WHILE TOUCHING GROUND

            
        

        if (playerManager.isGrounded)
        
            if (playerManager.isInteracting || inputHandler.moveAmount > 0  )
            
                myTransform.position = Vector3.Lerp(myTransform.position , targetPosition , Time.deltaTime);
            
            else
            
                myTransform.position = targetPosition;
            
        

    

【问题讨论】:

也许如果您使用 CrossFade 它有很长的退出时间?没有小数点的错字浮点数? @akaBase 嘿,非常感谢您的评论,我已经评论了 crossFade,现在我可以四处走动,但我不能滚动/后退。 Crossfade 有什么替代品,或者我用错了吗? anim.CrossFade(targetAnim , 0.2f); @akaBase 所以我将交叉淡入淡出中的 .02 更改为 .005,现在滚动动画会运行一瞬间。抱歉,我真的不知道如何统一编码,但我正在学习。 IDK 除了神奇地转换我的动画之外,CrossFade 还能做什么 你把它们设为循环了吗? @akaBase 所以现在交叉淡入淡出在一个函数中设置为零,该函数将在更新到“播放目标动画”时被调用,但是在一些巧妙的控制台日志之后,我注意到动画会自动播放将计时器设置回零,这将使动画切换回步行/跑步/冲刺(运动混合树) 【参考方案1】:

事实证明,在我的手柄下降功能中,地面检测就像一个魅力,但如果我立即接地,运动就会发挥作用。检查滚动计时器的 if 语句有效。

这是导致问题的函数

public void HandleFalling(float delta , Vector3 moveDirection) //bugged function, commented out in PlayerManager.Update()
    
        
        playerManager.isGrounded = false;
        RaycastHit hit;
        Vector3 origin = myTransform.position;
        origin.y += groundDetectionRayStartPoint;



        //IF SOMETHING IS DIRECTLY IN FRONT OF YOU, YOURE NOT MOVING
        if (Physics.Raycast(origin , myTransform.forward , out hit ,0.6f))
        
            moveDirection = Vector3.zero;
        



        if(playerManager.isInAir)
        
            rigidbody.AddForce(-Vector3.up * fallSpeed);
            rigidbody.AddForce(moveDirection * fallSpeed / 4.5f );
        

        Vector3 dir = moveDirection;
        dir.Normalize();
        origin =  origin + dir * groundDirectionRayDistance;
        targetPosition = myTransform.position;

        //DEBUGGER
        Debug.DrawRay(origin , -Vector3.up * minimumDistanceToBeginFall, Color.red , 0.1f , false);

        //grounded
        if (Physics.Raycast(origin , -Vector3.up , out hit , minimumDistanceToBeginFall , ignoreForGroundCheck)) 
        

            normalVector = hit.normal;
            Vector3 tp = hit.point;
            playerManager.isGrounded = true;
            targetPosition.y = tp.y;

            if (inAirTimer > 0.5f)
            
                Debug.Log("you were in the air for " + inAirTimer);
                animatorHandler.PlayTargetAnimation("Unarmed-Land" , false);
                inAirTimer = 0;
            
            else
             //SOLUTION TO THE ISSUE!!!!
                // Debug.Log(inputHandler.RollInputTimer);
                if(inputHandler.RollInputTimer > 0.19)
                    animatorHandler.PlayTargetAnimation("Locomotion" , false);
                    inAirTimer = 0;
                

                
                // animatorHandler.PlayTargetAnimation("Locomotion" , false);
                // inAirTimer = 0;
            

            playerManager.isInAir = false;


        
        else //falling
        
            Debug.Log("falling");
            
            playerManager.isInAir = true; //added to fix fall animation bug   *******************


            if (playerManager.isGrounded)
            
                playerManager.isGrounded = false;
            
            
            
            if (playerManager.isInAir == true)
            
               if (playerManager.isInteracting == false)
               
                   animatorHandler.PlayTargetAnimation("Falling" , true);
               
               Vector3 vel = rigidbody.velocity;
               vel.Normalize();
               rigidbody.velocity = vel * (movementSpeed/2);


                // if commented from the top and uncommented here, then rolls work but fall doesnt *******************
                //    playerManager.isInAir = true; 

                //When player is touching ground no matter what is commented out from above, PLAYER CANNOT ROLL WHILE TOUCHING GROUND

            
        

        if (playerManager.isGrounded)
        
            if (playerManager.isInteracting || inputHandler.moveAmount > 0  )
            
                myTransform.position = Vector3.Lerp(myTransform.position , targetPosition , Time.deltaTime);
            
            else
            
                myTransform.position = targetPosition;
            
        

    

【讨论】:

以上是关于动画播放一帧,然后返回混合树运动。仅在一个对象上的主要内容,如果未能解决你的问题,请参考以下文章

具有指向和单击运动的动画 [Unity2D]

带有 allowUserInteraction 的 UIView.animate 仅在动画的最后一帧中启用 UIButton

按钮单击时的 Unity 动画返回空闲动画

能够播放gif动画的ImageView

一帧等于多少秒?

点击移动动画不起作用