Unity骷髅战士脚本追击中断问题求助
Unity骷髅战士追击卡死问题分析与修复
问题根源
- 状态重置缺失:当玩家跳过后拉开距离,敌人从攻击/突进状态切换到追击状态时,没有主动重置
ATTACK_ANIMATION、CLOSE_IN_ANIMATION的布尔参数,也没恢复CanMove,导致动画状态判断异常,AttackEnded事件无法触发。 - 逻辑分支漏洞:
ActIfPlayerIsDetected中,当敌人处于攻击状态时玩家拉开距离,代码进入MoveMinorEnemy分支,但此时CanMove为false,且没有任何逻辑在这种场景下重置状态,直接导致敌人卡死在非移动状态。 - 攻击状态判断僵化:
SkeletonWarriorAttack只检查当前是否在攻击动画,没有处理玩家已经离开攻击范围的情况——如果攻击动画没触发(比如玩家刚好跳走),AttackEnded永远不会被调用,CanMove永久为false。
修复方案
1. 修复状态切换逻辑
修改ActIfPlayerIsDetected方法,在玩家拉开距离时主动重置动画状态和CanMove:
private void ActIfPlayerIsDetected() { if (AbsolutePositionOfEnemyFromPlayer > MinimumDistanceToCloseIn) { // 从攻击/突进状态切换到追击时,强制重置状态 if (!CanMove) { CanMove = true; SkeletonWarriorAnim.SetBool(ATTACK_ANIMATION, false); SkeletonWarriorAnim.SetBool(CLOSE_IN_ANIMATION, false); } MoveMinorEnemy(); } else if ((AbsolutePositionOfEnemyFromPlayer <= MinimumDistanceToCloseIn) && (AbsolutePositionOfEnemyFromPlayer > MinimumReachDistanceToInitiateAttack)) { CanMove = false; SkeletonWarriorCloseIn(); } else { CanMove = false; SkeletonWarriorAttack(); } }
2. 优化攻击状态判断
修改SkeletonWarriorAttack方法,增加玩家离开攻击范围时的状态重置逻辑:
void SkeletonWarriorAttack() { // 先关闭突进动画,避免动画状态冲突 SkeletonWarriorAnim.SetBool(CLOSE_IN_ANIMATION, false); // 仅当玩家在攻击范围内且未处于攻击动画时,触发攻击 if (!SkeletonWarriorAnim.GetCurrentAnimatorStateInfo(0).IsName(ATTACK_ANIMATION) && AbsolutePositionOfEnemyFromPlayer <= MinimumReachDistanceToInitiateAttack) { SkeletonWarriorAnim.SetBool(ATTACK_ANIMATION, true); } // 玩家离开攻击范围时,直接重置攻击状态和移动权限 else if (AbsolutePositionOfEnemyFromPlayer > MinimumReachDistanceToInitiateAttack) { SkeletonWarriorAnim.SetBool(ATTACK_ANIMATION, false); CanMove = true; } }
3. 完善移动状态的动画控制
修改MoveMinorEnemy方法,确保非移动状态下关闭行走动画:
private void MoveMinorEnemy() { if (CanMove) { SkeletonWarriorAnim.SetBool(WALK_ANIMATION, true); if (RelativePositionOfEnemyFromPlayer > 0) { SkeletonWarriorRenderer.flipX = true; SkeletonWarriorBody.velocity = new Vector2(-speed, SkeletonWarriorBody.velocity.y); } else if (RelativePositionOfEnemyFromPlayer < 0) { SkeletonWarriorRenderer.flipX = false; SkeletonWarriorBody.velocity = new Vector2(speed, SkeletonWarriorBody.velocity.y); } } else { SkeletonWarriorAnim.SetBool(WALK_ANIMATION, false); SkeletonWarriorBody.velocity = new Vector2(0, SkeletonWarriorBody.velocity.y); } }
4. 验证动画事件配置
确保Animator中:
Attack1动画的末尾帧添加了AttackEnded事件(无参数)CloseInToAttack动画的末尾帧添加了CloseInEnded事件(无参数)
内容的提问来源于stack exchange,提问作者Zirgud
相关产品推荐
相关产品推荐

