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

如何在Vector3.MoveTowards中修改Y轴实现角色跳跃弧线?

Precise Jump Arc with Custom Peak Position (No Physics)

Perfect, let's solve this precise jump movement problem without relying on Unity's physics system—since you need exact control over the landing spot and want to customize where the jump reaches its peak, here's a straightforward, reliable approach using a coroutine and parabolic curve fitting.

Core Idea

Instead of using Vector3.MoveTowards alone, we'll split the movement into two coordinated parts:

  • Horizontal (X/Z): Linear interpolation between start and end points to guarantee precise positioning over time.
  • Vertical (Y): A custom parabolic curve that passes through the start, your desired peak, and end points. This ensures the jump follows a natural arc and lands exactly on target.

Complete Coroutine Code

private IEnumerator JumpToTarget(Vector3 startPos, Vector3 targetPos, float jumpRelativeHeight, float peakPositionRatio, float jumpDuration)
{
    float startTime = Time.time;
    float endTime = startTime + jumpDuration;

    float startY = startPos.y;
    float endY = targetPos.y;
    // Calculate peak Y position (adjust this if you want an absolute height instead of relative)
    float peakY = startY + jumpRelativeHeight;
    float peakRatio = Mathf.Clamp01(peakPositionRatio); // Ensure ratio stays between 0 and 1

    // Calculate coefficients for the parabolic equation: y = a*t² + b*t + c (c = startY)
    float numeratorA = (peakY - startY) - peakRatio * (endY - startY);
    float denominatorA = peakRatio * (peakRatio - 1f);
    float a = numeratorA / denominatorA;
    float b = (endY - startY) - a;

    while (Time.time < endTime)
    {
        // Get normalized time progress (0 = start, 1 = end)
        float t = (Time.time - startTime) / jumpDuration;
        t = Mathf.Clamp01(t);

        // Compute horizontal position (linear interpolation for X/Z)
        Vector3 horizontalPos = Vector3.Lerp(startPos, targetPos, t);
        // Compute vertical position using our parabolic formula
        float currentY = a * t * t + b * t + startY;

        // Update the character's position
        transform.position = new Vector3(horizontalPos.x, currentY, horizontalPos.z);

        yield return null;
    }

    // Force final position to target to eliminate any frame-based inaccuracies
    transform.position = targetPos;
}

Code Breakdown

Let's walk through the key parts so you can tweak it to your needs:

  • Parameters:
    • startPos/targetPos: The exact start and end points of the jump (supports different Y heights for both points).
    • jumpRelativeHeight: How high the jump goes relative to the starting Y position (e.g., 2f means peak is 2 meters above start). If you want an absolute peak height, replace peakY = startY + jumpRelativeHeight with a fixed value like peakY = 5f.
    • peakPositionRatio: A value between 0 and 1 that defines when the jump reaches its peak. 0.5 = mid-jump, 0.2 = 20% of the way to the target, 0.8 = 80% of the way.
    • jumpDuration: Total time (in seconds) for the jump to complete—controls how fast/slow the movement is.
  • Parabolic Curve: We fit a quadratic equation to three points (start, peak, end) to ensure the Y movement follows a natural arc that hits your desired peak and lands exactly on target.
  • Precision: The final transform.position = targetPos line ensures no frame-rate-related drift, so your character always lands perfectly.

Example Usage

Call the coroutine from your movement code like this:

// Jump 5 meters forward from current position, peak at 40% of the journey, 2m high, takes 1 second
Vector3 jumpTarget = transform.position + Vector3.forward * 5f;
StartCoroutine(JumpToTarget(transform.position, jumpTarget, 2f, 0.4f, 1f));

Quick Optimizations

  • Smoother Movement: Add an easing function to the t value for more natural acceleration/deceleration. Replace t = Mathf.Clamp01(t) with t = Mathf.SmoothStep(t, 0f, 1f).
  • Speed-Based Control: If you prefer to control movement speed instead of duration, calculate jumpDuration as Vector3.Distance(startPos, targetPos) / moveSpeed (where moveSpeed is your desired horizontal speed in units per second).
  • Variable Peak Height: Adjust peakY to account for the target's Y position, e.g., peakY = Mathf.Max(startY, endY) + jumpRelativeHeight to ensure the jump clears any elevation changes.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:17:39