Unity添加二段跳后因while循环导致程序冻结问题求助
解决Unity二段跳代码的冻结问题
问题根源
你写的那段while (!groundedPlayer)循环是卡死的核心原因:
Unity的Update函数运行在主线程,这个循环一旦触发,会持续占用主线程CPU,导致游戏完全无法执行后续的逻辑(包括更新groundedPlayer的值、渲染画面、响应输入等)。而且groundedPlayer = controller.isGrounded这段代码在循环之后,根本没机会执行,groundedPlayer永远是false,循环永远不会结束,直接造成游戏冻结。
另外,用线程解决的思路也不对——Unity的组件API(比如CharacterController.isGrounded)只能在主线程调用,子线程无法正确获取地面检测状态,反而会引入线程安全问题。
正确的二段跳实现逻辑
Unity是帧驱动引擎,所有逻辑都应该在每一帧中逐步处理,不能用阻塞式循环。二段跳的正确逻辑应该是:
- 初始化允许玩家跳跃2次(二段跳)
- 每一帧先检测玩家是否落地,落地就重置跳跃次数为2
- 按下跳跃键时,只要还有剩余跳跃次数,就执行跳跃操作,同时减少一次跳跃次数
修改后的完整代码
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Example : MonoBehaviour { private CharacterController controller; private Vector3 playerVelocity; private bool groundedPlayer; private float playerSpeed = 2.0f; private float jumpHeight = 1.0f; private float gravityValue = -9.81f; // 初始允许2次跳跃(二段跳) int remainingJumps = 2; private void Start() { controller = gameObject.AddComponent<CharacterController>(); } void Update() { // 先检测是否落地,落地就重置跳跃次数 groundedPlayer = controller.isGrounded; if (groundedPlayer && playerVelocity.y < 0) { playerVelocity.y = 0f; remainingJumps = 2; // 落地后重置二段跳次数 } // 跳跃逻辑 if (Input.GetButtonDown("Jump")) { if (remainingJumps > 0) { // 执行跳跃 playerVelocity.y += Mathf.Sqrt(jumpHeight * -3.0f * gravityValue); remainingJumps--; // 消耗一次跳跃次数 } } // 移动逻辑 Vector3 move = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical")); controller.Move(move * Time.deltaTime * playerSpeed); if (move != Vector3.zero) { gameObject.transform.forward = move; } // 重力应用 playerVelocity.y += gravityValue * Time.deltaTime; controller.Move(playerVelocity * Time.deltaTime); } }
关键改动说明
- 把
jumpValue改成remainingJumps,初始值设为2,更直观表示剩余跳跃次数 - 移除了阻塞的while循环,改为在每一帧检测落地时重置跳跃次数
- 调整了
groundedPlayer的检测顺序,确保落地状态先被更新,再处理跳跃和移动逻辑 - 跳跃逻辑简化为:只要还有剩余次数,按下跳跃键就跳,同时减少次数
这样修改后,游戏不会再出现冻结,二段跳逻辑也能正常工作。
内容的提问来源于stack exchange,提问作者SCOS100Alt
相关产品推荐
相关产品推荐

