Unity平台跳跃游戏:同一按键双跳跃功能的计数异常问题
这个问题我太熟悉了——本质是同一帧内状态更新导致的逻辑冲突!咱们来拆解一下问题出在哪,再给你修复方案。
首先,你遇到的核心问题:当你在地面按空格时,代码先执行了普通跳跃的逻辑,把inAir设为true;紧接着同一帧里,空中跳跃的逻辑检测到inAir == true,而且pressingJumpButton还是true(因为Input.GetKeyDown在按键按下的那一帧全程有效),所以直接触发了空中跳跃,把地面跳跃也算进了3次空中跳跃的次数里。
另外你的代码还有个小漏洞:地面跳跃后没有把canJump设为false,导致玩家在空中时canJump依然是true,这可能会引发其他奇怪的问题。
接下来是修复方案,我推荐第二种更简洁的思路:
方案一:用帧标志位避免同帧触发
添加一个临时标志位,标记当前帧是否是地面跳跃的触发帧,让空中跳跃逻辑跳过这一帧:
bool pressingJumpButton = Input.GetKeyDown("space"); bool justJumpedFromGround = false; // 普通地面跳跃逻辑 if (pressingJumpButton && canJump) { Debug.Log("jump"); GetComponent<Rigidbody>().velocity = new Vector3( GetComponent<Rigidbody>().velocity.x, jumpingSpeed, GetComponent<Rigidbody>().velocity.z); inAir = true; canJump = false; // 离开地面后禁用地面跳跃 justJumpedFromGround = true; // 标记这是地面跳跃帧 } // 空中跳跃逻辑:跳过地面跳跃的那一帧 if (pressingJumpButton && inAir && !canJump && maxAir > 0 && !justJumpedFromGround) { Debug.Log("airJump"); maxAir -= 1; GetComponent<Rigidbody>().velocity = new Vector3( GetComponent<Rigidbody>().velocity.x, jumpingSpeed, GetComponent<Rigidbody>().velocity.z); } // 每一帧结束时重置标志位 void LateUpdate() { justJumpedFromGround = false; } // 回到地面时重置状态 void OnTriggerStay (Collider otherCollider) { if (otherCollider.tag == "JumpingArea") { canJump = true; inAir = false; maxAir = 3; } }
方案二:重构跳跃计数逻辑(更推荐)
把空中跳跃次数和地面跳跃彻底分开,地面跳跃不消耗空中跳跃次数,只有在空中的按键才会消耗:
bool pressingJumpButton = Input.GetKeyDown("space"); // 地面跳跃:只有在地面时触发,不消耗空中跳跃次数 if (pressingJumpButton && canJump) { Debug.Log("jump"); GetComponent<Rigidbody>().velocity = new Vector3( GetComponent<Rigidbody>().velocity.x, jumpingSpeed, GetComponent<Rigidbody>().velocity.z); inAir = true; canJump = false; } // 空中跳跃:只有在空中且还有次数时触发 else if (pressingJumpButton && inAir && maxAir > 0) { Debug.Log("airJump"); maxAir -= 1; GetComponent<Rigidbody>().velocity = new Vector3( GetComponent<Rigidbody>().velocity.x, jumpingSpeed, GetComponent<Rigidbody>().velocity.z); } // 地面检测重置状态 void OnTriggerStay (Collider otherCollider) { if (otherCollider.tag == "JumpingArea") { canJump = true; inAir = false; maxAir = 3; } }
这个方案用else if把两个跳跃逻辑互斥开,地面跳跃触发时,空中跳跃的逻辑就不会执行,从根源上解决了同帧冲突的问题,代码也更简洁。
你可以试试第二种方案,应该能完美解决你的问题!
内容的提问来源于stack exchange,提问作者ganesflea
相关产品推荐
相关产品推荐

