You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在C#中实现Unity 2D平台游戏可重复的跳跃机制?

修复2D平台游戏重复跳跃及自然下落问题

嘿,我仔细扒了你的代码,发现几个核心逻辑问题导致跳跃只能触发一次、还没法自然下落,咱们一步步把它掰正:

主要问题拆解

  1. MovePosition绕过了物理引擎:你用rb2D.MovePosition来控制跳跃和移动,这会直接硬设角色位置,完全忽略Rigidbody2D的重力属性——这就是角色不会自然下落的根源,相当于你把物理引擎的作用给屏蔽了。
  2. 碰撞状态逻辑混乱OnCollisionExit2D里乱设jump = true完全没必要,反而会在空中错误触发跳跃状态;grounded的切换也不够严谨,容易出现状态紊乱。
  3. 跳跃触发与时长控制不匹配:你用jumptime来控制跳跃时长,但没有和输入正确绑定,导致没法重复触发跳跃动作。

修正后的完整代码

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

public class PlayerController2D : MonoBehaviour {
    private Rigidbody2D rb2D;
    public float moveSpeed = 10f; // 替换原xvelocity,变量名更直观
    public float jumpForce = 15f; // 控制跳跃初始高度
    public float jumpHoldMaxDuration = 1.2f; // 按住跳跃键的最长持续时间(对应你要的1-1.5秒)
    private bool isGrounded = true;
    private bool isHoldingJump = false;
    private float currentJumpHoldTimer = 0f;

    void Start() {
        rb2D = GetComponent<Rigidbody2D>();
        // 确保Rigidbody2D的重力开启(Inspector面板里也可以调重力值,比如设为3f更贴合平台游戏手感)
        rb2D.gravityScale = 3f;
    }

    void Update() {
        // 跳跃触发:按下跳跃键且在地面时,启动跳跃
        if (Input.GetButtonDown("Jump") && isGrounded) {
            isHoldingJump = true;
            currentJumpHoldTimer = jumpHoldMaxDuration;
            // 给初始跳跃力
            rb2D.velocity = new Vector2(rb2D.velocity.x, jumpForce);
        }
        // 跳跃延长:按住跳跃键且还在计时内,持续给向上力实现"跳更高"效果
        else if (Input.GetButton("Jump") && isHoldingJump && currentJumpHoldTimer > 0) {
            currentJumpHoldTimer -= Time.deltaTime;
            rb2D.velocity = new Vector2(rb2D.velocity.x, jumpForce * 0.7f);
        }
        // 停止跳跃:松开按键或计时结束,终止跳跃状态
        else if (Input.GetButtonUp("Jump") || currentJumpHoldTimer <= 0) {
            isHoldingJump = false;
        }
    }

    private void FixedUpdate() {
        // 左右移动:用velocity控制,保留物理引擎的效果
        float horizontalInput = Input.GetAxisRaw("Horizontal");
        rb2D.velocity = new Vector2(horizontalInput * moveSpeed, rb2D.velocity.y);
    }

    // 更准确的地面检测:用Stay判断是否持续接触地面,避免短暂碰撞边缘就误判为空中
    private void OnCollisionStay2D(Collision2D collision) {
        if (collision.gameObject.CompareTag("Terrain")) {
            isGrounded = true;
            Debug.Log("落地啦");
        }
    }

    private void OnCollisionExit2D(Collision2D collision) {
        if (collision.gameObject.CompareTag("Terrain")) {
            isGrounded = false;
            Debug.Log("离开地面");
        }
    }
}

关键改动说明

  • 改用rb2D.velocity控制运动:让物理引擎的重力正常生效,角色会自然下落,不用手动写下落逻辑。
  • 优化跳跃输入逻辑:用GetButtonDown触发初始跳跃、GetButton延长跳跃时长、GetButtonUp立即终止,完全贴合常见平台游戏的跳跃手感。
  • 严谨的地面状态判断:用OnCollisionStay2D代替Enter,避免因为碰撞边缘短暂离开就误判为空中状态。
  • 变量命名更直观:把原有的xvelocityyvelocity改成moveSpeedjumpForce,后续维护更方便。

现在测试的话,按住跳跃键会持续跳跃1.2秒左右达到目标高度,松开后立刻下落,落地后可以再次触发跳跃,完全符合你的预期效果。

内容的提问来源于stack exchange,提问作者R_ Flintstone

火山引擎 最新活动