Unity PlayerMovement脚本蹲伏失效 滑铲冲刺功能正常
问题根因
蹲伏移速不生效是三个核心逻辑错误导致的:
StateHandler()状态判断的分支写法和顺序有问题:蹲伏判断用了独立if而非互斥的else if,后面的滑铲判断也没加sliding状态的前置校验。只要之前开过冲刺、sprinting标记没重置,按住蹲伏时就会直接命中滑铲分支,把刚设置的crouchSpeed覆盖成slideSpeed。- 蹲伏、滑铲的触发逻辑重复写了三处:
MyInput()里一套、Update()里一套、StateHandler()里又改了一遍状态,逻辑互相覆盖,状态标记乱跳。 - 松开蹲伏键时不管当前是蹲伏还是滑铲,直接把
sliding设为false,也没重置sprinting标记,下次按蹲伏很容易误判成滑铲。
修复方案
- 调整
StateHandler()的判断逻辑,按状态优先级从高到低用if-else if做互斥判断,顺序为:滑铲 > 蹲伏 > 冲刺 > 行走 > 空中,滑铲分支必须校验sliding为true才进入。 - 删除分散在各处的重复蹲伏/滑铲触发逻辑,把按键响应、角色缩放、状态切换统一放到
MyInput()里处理,避免逻辑冲突。 - 补全状态重置逻辑:进入蹲伏时强制取消冲刺标记,松开蹲伏键时区分当前是滑铲还是普通蹲伏,执行对应恢复逻辑。
核心修改代码
首先替换原有的StateHandler()方法:
private void StateHandler() { // 最高优先级:滑铲状态 if (sliding) { state = MovementState.sliding; moveSpeed = slideSpeed; } // 普通蹲伏:不在滑铲状态时按蹲伏键进入 else if (Input.GetKey(crouchKey)) { state = MovementState.crouching; moveSpeed = crouchSpeed; sprinting = false; // 蹲伏时强制清除冲刺标记,避免误判滑铲 } // 冲刺状态:地面、按冲刺键、按W前进时进入 else if (grounded && Input.GetKey(sprintKey) && Input.GetKey(KeyCode.W)) { state = MovementState.sprinting; moveSpeed = sprintSpeed; sprinting = true; } // 地面普通行走 else if (grounded) { state = MovementState.walking; moveSpeed = walkSpeed; sprinting = false; } // 空中状态 else { state = MovementState.air; } }
然后替换原有的MyInput()方法里的蹲伏相关逻辑,删掉重复的滑铲判断:
private void MyInput() { horizontalInput = Input.GetAxisRaw("Horizontal"); verticalInput = Input.GetAxisRaw("Vertical"); // 跳跃逻辑保持原有逻辑不变 if (Input.GetKey(jumpKey) && readyToJump && grounded) { readyToJump = false; Jump(); Invoke(nameof(ResetJump), jumpCooldown); } // 按下蹲伏键统一处理 if (Input.GetKeyDown(crouchKey)) { // 冲刺状态下按蹲伏=触发滑铲 if (sprinting && grounded) { StartSlide(); } // 非冲刺状态按蹲伏=进入普通蹲伏 else { sliding = false; transform.localScale = new Vector3(transform.localScale.x, crouchYScale, transform.localScale.z); rb.AddForce(Vector3.down * 5f, ForceMode.Impulse); } } // 松开蹲伏键统一处理 if (Input.GetKeyUp(crouchKey)) { // 处于滑铲状态就停止滑铲 if (sliding) { StopSlide(); } // 普通蹲伏状态就恢复默认身高 else { transform.localScale = new Vector3(transform.localScale.x, startYScale, transform.localScale.z); } } }
最后打开Update()方法,删掉里面重复写的这两段滑铲/蹲伏触发代码,避免重复执行冲突:
// 删除以下两行重复逻辑 // if (Input.GetKeyDown(crouchKey) && sprinting) // StartSlide(); // if (Input.GetKeyUp(crouchKey) && sliding) // StopSlide();
改完之后测试即可:静止/走路状态按左Ctrl会进入普通蹲伏,移速为预设的crouchSpeed;冲刺状态按左Ctrl正常触发滑铲,不会再出现蹲伏移速被覆盖的问题。
内容的提问来源于stack exchange,提问作者Levi
相关产品推荐
相关产品推荐

