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

Unity 2D无尽跑酷角色跳远距离随世界速度变化的解决求助

解决方案:动态调整重力与跳跃力固定跳跃轨迹

核心逻辑是让跳跃总时间和世界速度成反比,同时通过物理公式推导,实时计算对应的重力和跳跃初速度,保证:

  • 跳跃高度固定
  • 落地时世界滚动的距离(视觉上的跳远距离)固定
  • 角色全程保持X轴静止

关键参数定义

先确定两个固定的关卡设计参数:

  • fixedJumpHeight:你想要的固定跳跃高度(比如2米)
  • fixedJumpDistance:你想要的固定跳远距离(即落地时世界滚动的长度,比如5米)

公式推导

假设跳跃过程对称(上升和下落时间相同,无空气阻力):

  1. 跳跃总时间 T = 落地时世界滚动距离 / 当前世界速度 → T = fixedJumpDistance / worldSpeed
  2. 上升时间 t = T / 2(因为上升下落对称)
  3. 由物理公式,上升高度 fixedJumpHeight = 0.5 * gravity * t²,代入t = T/2和T = fixedJumpDistance/worldSpeed,最终推导得:
    • 所需重力:gravity = (8 * fixedJumpHeight * worldSpeed²) / fixedJumpDistance²
    • 跳跃初速度:jumpVelocityY = (4 * fixedJumpHeight * worldSpeed) / fixedJumpDistance

代码实现

关闭Unity自带重力,用自定义逻辑动态计算并应用重力和跳跃力:

using UnityEngine;

public class PlayerController : MonoBehaviour
{
    [SerializeField] private Rigidbody2D _rb;
    [SerializeField] private WorldMover _worldMover;
    [Header("固定跳跃参数")]
    [SerializeField] private float _fixedJumpHeight = 2f;
    [SerializeField] private float _fixedJumpDistance = 5f;

    private void Awake()
    {
        _rb = GetComponent<Rigidbody2D>();
        // 禁用Unity自带重力,用自定义逻辑控制
        _rb.gravityScale = 0;
    }

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space) && IsGrounded())
        {
            ApplyJump();
        }
    }

    private void FixedUpdate()
    {
        // 实时应用自定义重力
        float currentWorldSpeed = _worldMover.currentSpeed;
        if (currentWorldSpeed <= 0) return;

        float gravity = (8 * _fixedJumpHeight * currentWorldSpeed * currentWorldSpeed) 
                        / (_fixedJumpDistance * _fixedJumpDistance);
        // 重力方向向下,所以施加负Y方向的力
        _rb.AddForce(new Vector2(0, -gravity * _rb.mass), ForceMode2D.Force);
    }

    private void ApplyJump()
    {
        float currentWorldSpeed = _worldMover.currentSpeed;
        if (currentWorldSpeed <= 0) return;

        float jumpVelocityY = (4 * _fixedJumpHeight * currentWorldSpeed) / _fixedJumpDistance;
        // 重置X轴速度为0,确保角色不移动
        _rb.velocity = new Vector2(0, jumpVelocityY);
    }

    // 替换为你的落地检测逻辑(射线/碰撞器检测)
    private bool IsGrounded()
    {
        // 示例:从角色脚下发射短射线检测地面
        RaycastHit2D hit = Physics2D.Raycast(transform.position, Vector2.down, 0.1f, LayerMask.GetMask("Ground"));
        return hit.collider != null;
    }
}

注意事项

  • 确保WorldMover的currentSpeed变量在速度变化时实时更新(比如触发减速地砖/加速道具时)。
  • 测试时先固定currentSpeed为某个值(比如5),调整_fixedJumpHeight和_fixedJumpDistance到你想要的效果,再测试速度变化的场景。
  • 排除其他影响角色X轴的力或脚本,保证角色X轴始终为0。
  • 如果跳跃轨迹有微小偏差,检查是否有碰撞检测的误差,或者调整射线检测的长度/层级。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 04:45:28