动画播放一帧,然后返回混合树运动。仅在一个对象上
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;
【讨论】:
以上是关于动画播放一帧,然后返回混合树运动。仅在一个对象上的主要内容,如果未能解决你的问题,请参考以下文章
带有 allowUserInteraction 的 UIView.animate 仅在动画的最后一帧中启用 UIButton