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

Unity角色跳跃问题:如何实现按键时100%触发无延迟跳跃?

跳跃触发不稳定与延迟问题的修复方案

核心问题拆解

  • 输入检测时机错误:跳跃逻辑放在FixedUpdate中使用Input.GetKeyUp,FixedUpdate是固定间隔的物理帧(默认0.02秒),很容易错过按键抬起的瞬间,导致触发不稳定;且GetKeyUp不符合常规跳跃操作逻辑——玩家通常按下按键就希望触发跳跃,而非抬起时。
  • 移动方式冲突物理系统:直接修改transform.position移动角色,绕过了Rigidbody2D的物理模拟,会干扰碰撞检测的准确性,进而导致onCloud状态判断出错。
  • 碰撞状态判断不严谨:仅通过OnCollisionEnter2D设置onCloud=true,未处理角色主动离开云朵的情况,且未验证碰撞方向,可能出现侧面碰撞误触发的问题。

修复后的完整代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MonsterScript : MonoBehaviour
{
    [SerializeField] private float walkSpeed = 10f;
    [SerializeField] private float jumpStrength = 11f;

    private float movementX;
    private bool onCloud = true;
    private readonly string CLOUD_TAG = "Cloud";
    private readonly string WALK_ANIMATION = "walk";

    private Rigidbody2D mybody;
    private SpriteRenderer sr;
    private Animator anim;

    private void Awake()
    {
        mybody = GetComponent<Rigidbody2D>();
        anim = GetComponent<Animator>();
        sr = GetComponent<SpriteRenderer>();
        // 开启连续碰撞检测,避免快速移动时跳过碰撞检测
        mybody.collisionDetectionMode = CollisionDetectionMode2D.Continuous;
    }

    void Update()
    {
        monsterWalkInput();
        monsterJumpInput();
    }

    private void FixedUpdate()
    {
        ApplyMovement();
    }

    // 输入逻辑统一放在Update,保证按键响应及时
    void monsterWalkInput()
    {
        movementX = Input.GetAxisRaw("Horizontal");
        // 更新行走动画状态
        anim.SetBool(WALK_ANIMATION, movementX != 0);
        // 根据移动方向翻转 sprite
        if (movementX != 0)
        {
            sr.flipX = movementX < 0;
        }
    }

    void monsterJumpInput()
    {
        // 改用GetKeyDown,按下瞬间触发,符合操作习惯
        if (Input.GetKeyDown(KeyCode.Space) && onCloud)
        {
            mybody.AddForce(Vector2.up * jumpStrength, ForceMode2D.Impulse);
            onCloud = false;
        }
    }

    // 物理移动放在FixedUpdate,与物理系统同步
    void ApplyMovement()
    {
        Vector2 currentVelocity = mybody.velocity;
        currentVelocity.x = movementX * walkSpeed;
        mybody.velocity = currentVelocity;
    }

    private void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.gameObject.CompareTag(CLOUD_TAG))
        {
            // 检查碰撞法线,确保是角色从上方落到云朵上
            foreach (ContactPoint2D contact in collision.contacts)
            {
                if (contact.normal.y > 0.7f)
                {
                    onCloud = true;
                    Debug.Log("Landed!");
                    break;
                }
            }
        }
    }

    // 处理离开云朵的情况,修正状态
    private void OnCollisionExit2D(Collision2D collision)
    {
        if (collision.gameObject.CompareTag(CLOUD_TAG))
        {
            onCloud = false;
        }
    }
}

额外优化提示

  • 检查云朵的Rigidbody2D设置:建议设为Kinematic或标记为Static,避免云朵自身物理移动干扰碰撞检测。
  • 调整角色物理参数:如果仍有延迟,可适当降低角色Rigidbody2D的质量,或提高jumpStrength数值。
  • 碰撞体适配:确保角色和云朵的碰撞体大小、位置合理,避免出现接触检测盲区。

内容的提问来源于stack exchange,提问作者Abiskar Sapkota

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 10:50:22