# Unity 跳跃学习笔记

在 Unity 中实现跳跃的方式有多种，我整理了三种可行的方式，在这里分享一下。

# Transform

关键代码为：

```csharp
public float jumpHeight = 2f;
transform.position = new Vector3(transform.position.x, transform.position.y + jumpHeight, 0);
```

也就是直接修改物体的位置，说实话，单这一行根本算不上是跳跃，应该是瞬移。

所以要实现 y 坐标的渐进变化，应该用缓动函数来计算位置，线性变化可以用 `Vector3.Lerp` 来实现：

```csharp
private Vector3 startPosition;
private Vector3 endPosition;
private float jumpStartTime;
public float jumpTime = 0.5f;
private bool isJumping = false;
public float jumpHeight = 2f;

void Update()
{
    if (!isJumping && Input.GetButtonDown("Jump"))
    {
        isJumping = true;
        startPosition = transform.position;
        endPosition = transform.position + new Vector3(0, jumpHeight, 0);
        jumpStartTime = Time.time;
        StartCoroutine(Jump());
    }
}

IEnumerator Jump()
{
    while (Time.time < jumpStartTime + jumpTime)
    {
        float t = (Time.time - jumpStartTime) / jumpTime;
        transform.position = Vector3.Lerp(startPosition, endPosition, t);
        yield return null;
    }
    
    isJumping = false;
}
```

代码中能控制的地方有 `jumpHeight`、`jumpTime`。

# velocity

关键代码为：

```csharp
rb = GetComponent<Rigidbody2D>();
rb.velocity = new Vector2(rb.velocity.x, jumpHeight);
```

原理是给 rigidbody 一个 y 轴正向的速度，会让 rigidbody 自行处理向上的移动，然后受到重力影响，自行下落。

# AddForce

关键代码为：

```csharp
rb = GetComponent<Rigidbody2D>();
rb.AddForce(new Vector2(0, jumpHeight), ForceMode2D.Impulse);
```

原理是给 rigidbody 一个向上的力，Impulse 表示冲量，让力只存在一瞬间，然后 rigidbody 会获得加速度向上冲。

# velocity 和 AddForce 的区别

在一段跳时，两者没有明显区别，在二段跳时，两者的移动路径是不同的。

`AddForce` 的跳跃高度会受按键间隔影响，间隔越小，跳得越高。因为 `AddForce` 是施加力到物体上，短期内施加多个力，会让他们叠加，从而带来更大的加速度。

同理，间隔越长，二段跳的效果越不明显，因为此时只受重力影响，加速度向下，新的力带来的加速度会被抵消掉。
