You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:55:57