# 単純な物理

ゲームでよく使われそうな物理を練習しましょう。以下の処理は、Unity の Rigidbody を対応してくれる処理である。

## 移動、速度、加速度

### 移動と速度の関係性

 次の状況を考えてみてください：あるキャラクターは2D空間の位置「***p = (p<sub>x</sub>, p<sub>y</sub>)***」にいる。このキャラクターは定めた時間「***Δt***」をかけて、ある目的地「***q = (q<sub>x</sub>, q<sub>y</sub>)***」に到着させたい。

![image.png](https://class.illogic.games/uploads/images/gallery/2026-06/scaled-1680-/GDhimage.png)

 この場合は、移動に必要な速度「***v = (v<sub>x</sub>, v<sub>y</sub>)***」を求めることができる：

<table border="1" id="bkmrk--1" style="border-collapse: collapse; width: 100%; border-width: 1px; background-color: rgb(255, 255, 255);"><colgroup><col style="width: 99.881%;"></col></colgroup><tbody><tr><td>![image.png](https://class.illogic.games/uploads/images/gallery/2026-06/scaled-1680-/aFOimage.png)

</td></tr></tbody></table>

始点「***p***」から終点「***q***」までの距離（と向き）を到着までの必要な時間で割ると、速度「***v***」を求める。それでは、始点「***p***」と速度「***v***」があれば、定めた時間「***t***」の後に、どこにいるか知りたいなら：

<table border="1" id="bkmrk--2" style="border-collapse: collapse; width: 100%; border-width: 1px; background-color: rgb(255, 255, 255);"><colgroup><col style="width: 99.881%;"></col></colgroup><tbody><tr><td>![image.png](https://class.illogic.games/uploads/images/gallery/2026-06/scaled-1680-/pZMimage.png)

</td></tr></tbody></table>

Unityでは、フレーム間の時間を「`Time.deltaTime`」で取得できるので、移動を計算したいなら：

```c#
// 始点（現在の位置）
Vector3 p = transform.position;

// vは「Vector3」型の速度（量と向き）
Vector3 q = p + v * Time.deltaTime;

// 位置を更新
transform.position = q;
```

#### 練習

シーンに何かの3Dオブジェクトを追加。スペースキーを押したら、一定速度で移動する。キーを放したら、速度を0にする。速度を Inspectorで設定できるようにしてください。

<details id="bkmrk-testvelocity%E3%81%AE%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88-%2F"><summary>TestVelocityのスクリプト</summary>

```c#
// 物理の練習：一定速度で移動
public class TestVelocity : MonoBehaviour
{
    // 速度ベクトル（量＋向き）
    [SerializeField]
    private Vector3 velocity; 

    void Update()
    {
        // まず、速度はゼロにする
        Vector3 v = Vector3.zero;

        // 何かのキーを押したら
        if (Input.GetKey(KeyCode.Space))
            v = velocity; // 速度を書き換える

        // 物理演算を使って、移動する
        Vector3 p = transform.position;

        // 移動の式
        Vector3 q = p + v * Time.deltaTime; 

        // 位置更新
        transform.position = q;
    }
}
```

</details>### 加速度

 速度は「時間単位当たりの物体の**位置**の変化量」であるとしたら、加速度は「時間単位当たりの物体の**速度**の変化量」である（速度の速度）。つまり：

<table border="1" id="bkmrk--3" style="border-collapse: collapse; width: 100%; border-width: 1px; background-color: rgb(255, 255, 255);"><colgroup><col style="width: 99.881%;"></col></colgroup><tbody><tr><td>![image.png](https://class.illogic.games/uploads/images/gallery/2026-06/scaled-1680-/e5zimage.png)

</td></tr></tbody></table>

速度「***v***」は、初期速度「***v<sub>0</sub>***」に加速度「***a***」と加速した時間「***Δt***」の乗算を足す。Unityで実装するなら：

```c#
// 内部の速度ベクトル
private Vector3 velocity;

private void Update()
{
	// 初期速度
	Vector3 v0 = velocity;

	// 新しい速度を計算
	Vector3 v = v0 + a * Time.deltaTime

	// 次のフレームの初期速度を更新
	velocity = v;
}
```

練習

加速度を試せる TestAccel のスクリプトを作成してください。「A」キーを押したら一定加速度で移動する。「S」キーを押すと一定速度で減速する。速度が0以下にならないようにする。なお、加速度を Inspectorで設定できるようにしてください。

<details id="bkmrk-testaccel%E3%81%AE%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88-%2F%2F-%E7%89%A9"><summary>TestAccelのスクリプト</summary>

```c#
// 物理の練習：加速度
public class TestAccel : MonoBehaviour
{
	[SerializeField]
	Vector3 acceleration; // 加速度ベクトル（量＋向き）

	Vector3 velocity; // 速度（内部）

	void Update()
	{
		// まずは、速度を更新
		Vector3 a = Vector3.zero; // 加速なし
		
		// 「a」を押したら、加速
		if (Input.GetKey(KeyCode.A))
			a = acceleration;
		
		// 「s」を押したら、減速
		else if (Input.GetKey(KeyCode.S))
			a = -acceleration;

		// 現在の速度
		velocity = velocity + a * Time.deltaTime;

		// 位置を更新（移動）
		Vector3 p = transform.position;
		Vector3 q = p + velocity * Time.deltaTime;
		transform.position = q;
	}
}
```

</details>## 重力

重力は下に向かう加速度ベクトルである。地球の場合は、おおよそ 9.81 m/s<sup>2</sup> である。

```c#
// 重力ベクトル
Vector3 gravity = new Vector3(0, -9.81f, 0);
```

#### 練習

ボールを投げるスクリプト「ThrowBall」を作成する。Inspectorでボールに初期速度を設定し、斜め上に投げ、重力で落とす。無限に落ちないように、Y軸の位置は０以下にならないようにする。

<table border="1" id="bkmrk-v0-%E3%81%AE%E5%88%9D%E6%9C%9F%E9%80%9F%E5%BA%A6%E3%81%AB%E3%81%A6%E3%83%9C%E3%83%BC%E3%83%AB%E3%82%92%E6%8A%95%E3%81%92%E3%82%8B%E3%80%82-g" style="border-collapse: collapse; width: 100%; border-width: 0px;"><colgroup><col style="width: 58.4969%;"></col><col style="width: 41.5805%;"></col></colgroup><tbody><tr><td style="border-width: 0px;">[![image.png](https://class.illogic.games/uploads/images/gallery/2026-06/scaled-1680-/2TNimage.png)](https://class.illogic.games/uploads/images/gallery/2026-06/2TNimage.png)</td><td style="border-width: 0px;">***v<sub>0</sub>*** の初期速度にてボールを投げる。

***g*** 重力の加速度であり、時間により落下してくる。

</td></tr></tbody></table>

<details id="bkmrk-throwball-%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88-%2F%2F-%E3%83%9C"><summary>ThrowBall スクリプト</summary>

```c#
// ボールを投げ、重力で落とす
public class ThrowBall : MonoBehaviour
{
    // ボールの初期速度
    [SerializeField] 
    private Vector3 velocity;

    private void Update()
    {
        // 重力による加速度を使い、速度を更新
        Vector3 gravity = new Vector3(0, -9.81f, 0);
        velocity += gravity * Time.deltaTime;
        
        // 位置を更新
        var position = transform.position;
        position += velocity * Time.deltaTime;
        
        // 高さが0以下にならないようにする
        position.y = Mathf.Max(0, position.y);
        transform.position = position;
    }
}
```

</details>## 質量、力と加速度の関係性

すべての物体は「質量」があり、重ければ重いほど動かすのは力が必要。従って、物体の加速度は、物体の重さ（質量）と力に依存する。その関係性以下の通りである：

<table border="1" id="bkmrk--4" style="border-collapse: collapse; width: 100%; border-width: 1px; background-color: rgb(255, 255, 255);"><colgroup><col style="width: 99.881%;"></col></colgroup><tbody><tr><td>![image.png](https://class.illogic.games/uploads/images/gallery/2026-06/scaled-1680-/C3Timage.png)

</td></tr></tbody></table>

ここで、「***a***」は加速度であり、「***f***」は力、「***m***」は質量である。これは「`Rigidbody.AddForce`」の処理である。

#### 練習

ThrowBall を更新し、ボールに質量を与え、キーを押したら力を与える。力のベクトルと質量をInspectorで変えられるようにする。

<table border="1" id="bkmrk-m-%E3%81%AF%E3%83%9C%E3%83%BC%E3%83%AB%E3%81%AE%E8%B3%AA%E9%87%8F%E3%81%A7%E3%81%82%E3%82%8B%E3%80%82-f-%E3%81%AF%E6%8A%95%E3%81%92%E3%82%8B" style="border-collapse: collapse; width: 100%; border-width: 0px;"><colgroup><col style="width: 54.3326%;"></col><col style="width: 45.6277%;"></col></colgroup><tbody><tr><td style="border-width: 0px;">![image.png](https://class.illogic.games/uploads/images/gallery/2026-06/scaled-1680-/MZSimage.png)</td><td style="border-width: 0px;">***m*** はボールの質量である。

***f*** は投げる力である。

***g*** 重力の加速度であり、時間により落下してくる。

</td></tr></tbody></table>

<details id="bkmrk-throwball-%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88-%2F%2F-%E3%83%9C-1"><summary>ThrowBall スクリプト</summary>

```c#
// ボールを投げ、重力で落とす
public class ThrowBall : MonoBehaviour
{
    // ボールの質量
    [SerializeField] 
    private float mass;

    // 投げる力
    [SerializeField] 
    private Vector3 force;
    
    // 速度（内部）
    private Vector3 velocity;

    private void Start()
    {
        // 力と質量から加速度を計算
        Vector3 a = force / mass;
        
        // 加速度は時間をかけて速度を変える
        // 投げる時間を 0.5秒にしましょう
        velocity = a * 0.5f;
    }

    private void Update()
    {
        // 重力による加速度を使い、速度を更新
        Vector3 gravity = new Vector3(0, -9.81f, 0);
        velocity += gravity * Time.deltaTime;
        
        // 位置を更新
        var position = transform.position;
        position += velocity * Time.deltaTime;
        
        // 高さが0以下にならないようにする
        position.y = Mathf.Max(0, position.y);
        transform.position = position;
    }
}
```

</details>