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

2D俯视角史莱姆跳跃效果实现问题求助

解决史莱姆2D俯视角跳跃问题

原代码的核心问题

  • 用X位置进度驱动正弦波,会导致跳跃节奏随目标距离乱掉:近目标时跳跃没完成就落地,远目标时可能反复上下波动,不符合真实跳跃“一次起跳-落地”的逻辑
  • 正弦波是对称运动,没模拟真实跳跃的重力加速度(上升减速、下落加速),动作显得生硬假
  • 直接硬写Y值,没和移动进度绑定,跳跃与移动的同步性差

方案1:协程+抛物线公式(无物理交互)

用协程控制完整跳跃流程,基于时间进度计算抛物线位置,保证跳跃节奏统一,同时模拟重力感。

示例代码:

private bool isJumping = false;
public float jumpHeight = 1f; // 跳跃峰值高度
public float jumpDuration = 0.5f; // 单次跳跃总时长

public void JumpToTarget(Vector3 targetPos)
{
    if (isJumping) return;
    StartCoroutine(JumpCoroutine(targetPos));
}

private IEnumerator JumpCoroutine(Vector3 targetPos)
{
    isJumping = true;
    Vector3 startPos = transform.position;
    float elapsedTime = 0f;

    while (elapsedTime < jumpDuration)
    {
        elapsedTime += Time.deltaTime;
        float progress = Mathf.Clamp01(elapsedTime / jumpDuration);
        
        // 匀速计算X轴位置
        float currentX = Mathf.Lerp(startPos.x, targetPos.x, progress);
        // 抛物线Y轴高度:顶点在进度0.5处,符合重力下落逻辑
        float currentY = startPos.y + 4 * jumpHeight * progress * (1 - progress);
        
        transform.position = new Vector3(currentX, currentY, transform.position.z);
        yield return null;
    }

    // 强制修正最终位置,避免误差
    transform.position = targetPos;
    isJumping = false;
}

点击触发逻辑:

void Update()
{
    if (Input.GetMouseButtonDown(0))
    {
        Vector3 targetPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        targetPos.z = transform.position.z; // 保持俯视角Z轴一致
        JumpToTarget(targetPos);
    }
}

方案2:使用Rigidbody2D(带物理交互)

如果需要史莱姆和场景碰撞体交互(比如碰障碍停下、掉坑),直接用物理系统更真实。

步骤:给史莱姆添加Rigidbody2D组件,设置合适的Gravity Scale,取消Fixed Angle(需要史莱姆形变/旋转的话)。

示例代码:

private Rigidbody2D rb;
public float gravityScale = 2f;

void Awake()
{
    rb = GetComponent<Rigidbody2D>();
    rb.gravityScale = gravityScale;
}

void Update()
{
    // 只有在地面(Y轴速度为0)时允许跳跃
    if (Input.GetMouseButtonDown(0) && Mathf.Abs(rb.velocity.y) < 0.01f)
    {
        Vector3 targetPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        targetPos.z = transform.position.z;
        JumpToTarget(targetPos);
    }
}

private void JumpToTarget(Vector3 targetPos)
{
    Vector2 direction = targetPos - transform.position;
    float distance = direction.magnitude;

    // 物理公式计算跳跃初速度,确保刚好落到目标点(取45度起跳角度)
    float gravity = Physics2D.gravity.y * rb.gravityScale;
    float initialVelocity = Mathf.Sqrt(Mathf.Abs(gravity) * distance);
    
    rb.velocity = direction.normalized * initialVelocity;
}

额外优化建议

  • 绑定跳跃动画:根据Y轴速度切换上升/下落动画,或按进度播放弹性形变动画
  • 缓动移动:把Mathf.Lerp换成Mathf.SmoothStep或自定义AnimationCurve,让史莱姆移动更有弹性
  • 动态调高度:根据目标距离调整跳跃高度,远目标跳得更高,增强真实感

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 23:51:15