[超初心者向け]Unityチュートリアル「はじめてのUnity」のブロック崩しと同等をC#で::(3)動くボール

#この解説は
Unityのサイトに昔からあるチュートリアルに、以下があります。
[「はじめてのUnity」(旧）
http://tutorial.unity3d.jp/archive/my-first-unity/](http://tutorial.unity3d.jp/archive/my-first-unity/)
これを独自にC#化したものをベースとしています。以下を
この解説は以下の段階があります、前の内容を実行した上でのものとして参照して下さい。現時点(20151026)では、[新しい「はじめてのUnity」の玉転がしゲーム](https://github.com/unity3d-jp/FirstTutorial/wiki)が公開されています。本サイトのブロック崩しと併せて学習すると広がりがあり、初期の学習にはとても有効です。

* [[超初心者向け]Unityチュートリアル「はじめてのUnity」のブロック崩しと同等をC#で::(1)ステージ配置](http://qiita.com/JunShimura/items/cbb0db8087a5cc75735e)
* [[超初心者向け]Unityチュートリアル「はじめてのUnity」のブロック崩しと同等をC#で::(2)色を変える](http://qiita.com/JunShimura/items/1b2b4842e983022075de )
* [__[超初心者向け]Unityチュートリアル「はじめてのUnity」のブロック崩しと同等をC#で::(3)動くボール__](http://qiita.com/JunShimura/items/dfb2bdbbc328869f62ec )
* [[超初心者向け]Unityチュートリアル「はじめてのUnity」のブロック崩しと同等をC#で::(4)ラケットを動かす]
(http://qiita.com/JunShimura/items/5fac20966bba6b223427)
* [[超初心者向け]Unityチュートリアル「はじめてのUnity」のブロック崩しと同等をC#で::(5)消えるブロック](http://qiita.com/JunShimura/items/867179092a2a564bc88c)
* [[超初心者向け]Unityチュートリアル「はじめてのUnity」のブロック崩しと同等をC#で::(6)ブロックを手作業で並べる](http://qiita.com/JunShimura/items/1f39e52414171c67bc71)


# 動く物体を作る
ここでは、Sceneに物体（GameObject)を配置し、動きを与える、ということを進めます。前段階の配置をしている前提ですが、他のものでも同様になるので応用できます。

##ボールを配置
上に在るメニューの[GameObject]>[3D Object]>[Sphere]を選択して下さい。
[![Gyazo](http://i.gyazo.com/b36159ff76d4ac11080f2483fe541aaa.gif)](http://gyazo.com/b36159ff76d4ac11080f2483fe541aaa)
新規に`Sphere`という名前の`GameObject`が出来上がります。
そのままでも良いのですが、なじみにくいので名前を`Ball`に変えます。
[![Gyazo](http://i.gyazo.com/c095ba121fbccd3d0c3714102b61bbc6.png)](http://gyazo.com/c095ba121fbccd3d0c3714102b61bbc6)
動作が観察しやすいように、場所を原点付近に置いておきましょう。
[Inspector]タブの[Transform]のところにあるギアをクリックし、[Reset]を選択すると、値がリセットされて原点で大きさが1、回転なしの状態になります。
[![Gyazo](http://i.gyazo.com/9d4948cf063d3bf894923cd8d72a4624.gif)](http://gyazo.com/9d4948cf063d3bf894923cd8d72a4624)

##ボールに物理属性を与える
Unityでは簡単にゲームを作りやすくするために、物理演算を組み込んでいます、`Rigidbody`コンポーネントです。これを用いると、落下や衝突、摩擦や空気抵抗など、物理的な動作をUnityで作られた機能で実現できます。
###`Rigidbody`コンポーネントを`Ball`に追加
`Ball`を選択している状態で、[Compornent]>[Physics]>[Rigidbody]を選びます。
[![Gyazo](http://i.gyazo.com/2bbfc0c6558e21c0d12cfe7612239dfe.gif)]
(http://gyazo.com/2bbfc0c6558e21c0d12cfe7612239dfe)
[Inspector]タブに`Rigidbody`が追加されました。
[![Gyazo](http://i.gyazo.com/8cf40841f36eb44263f0ac6fea5417b4.png)](http://gyazo.com/8cf40841f36eb44263f0ac6fea5417b4)

###`Rigidbody`コンポーネントを調整
必要に応じて、設定をします。内容は、以下になっています。

|プロパティ|説明|
|:---------------|:----------------------------------------|
|Mass|オブジェクトの質量 (単位 : kg)。
|Drag|空気抵抗。0 の場合、空気抵抗が 0
|Angular Drag|回転する際の空気抵抗。0 の場合、空気抵抗なし。
|Use Gravity|有効にすると、オブジェクトは重力の影響を受けます。

くわしくは以下を参照してください。
[Unity-マニュアル：リジッドボディ
http://docs.unity3d.com/ja/current/Manual/class-Rigidbody.html]
(http://docs.unity3d.com/ja/current/Manual/class-Rigidbody.html)

###状況を確認
まず、現在の状況を確認します。'Rigidbody'があるので、この物体は物理的な動きをします。
エディタ画面中央の実行ボタンを押してみましょう。
[![Gyazo](http://i.gyazo.com/2e1690f2f8212d75346741927663158b.gif)](http://gyazo.com/2e1690f2f8212d75346741927663158b)
ゲーム画面に切り替わり、ボールが真下に落下していくのが判ります。

###重力を無効にする
今回のゲームはxz平面（左右と奥行き）上に作っています。y軸で重力の影響を受ける必要が無いので、重力設定を無効にします。コンポーネントのUse Gravityのチェックを外します。
[![Gyazo](http://i.gyazo.com/6c68b4585d8f4b97bd5b7252842db96f.png)](http://gyazo.com/6c68b4585d8f4b97bd5b7252842db96f)
これで玉は落下しなくなりました。

##`Ball`に力を加える
`Ball`にかかる力は重力も無効なので、現状だとなにも起きません。意図的に`Ball`に力を加えることで、`Ball`を動かします。意図的な力は、プログラミングの必要があります。Unityでの特殊な処理はScriptコンポーネントを作ってはめることで実現します。

###`Ball`にScriptコンポーネントを追加する
[Inspector]タブの一番下にある[Add compornent]をクリックして、Scriptアセットを作成、追加します。ファイル形式は`cs`を選びます。
[![Gyazo](http://i.gyazo.com/0b5ea99bc34d45fb94a98079996fc882.gif)](http://gyazo.com/0b5ea99bc34d45fb94a98079996fc882)

ファイル名を`Ball`とします。そうすると、Assetの中に`Ball.cs`が出来ています。
[![Gyazo](http://i.gyazo.com/a85f086a74de97b05d46d29ebcf0b625.png)](http://gyazo.com/a85f086a74de97b05d46d29ebcf0b625)

###`Ball.cs`を編集する
Asset内の'Ball'スクリプト(C#のアイコン）をダブルクリックすると、エディタが開きます。
優先的に開かれるエディタは、多くの場合はMonoDevelopというソフトが起動されます。自分で使いたいコードエディタがある場合は、それも可能です。調べてみましょう。

```csharp:Ball.cs
using UnityEngine;
using System.Collections;

public class Ball : MonoBehaviour {

	// Use this for initialization
	void Start () {
	
	}
	
	// Update is called once per frame
	void Update () {
	
	}
}
```

エディタで開かれた直後の状態です、それぞれに意味がありますが、知りたい人はこちらを参考にして下さい。

[[超初心者向け]やっと納得、Unityを初めて触ると出てくるC#の何だあれの答え
http://qiita.com/JunShimura/items/3c2e23bb77cc9085bfda]
(http://qiita.com/JunShimura/items/3c2e23bb77cc9085bfda)

今回は、初速を与えるのに、以下のコードを追加して力を加えます。

```csharp:Ball.cs
using UnityEngine;
using System.Collections;

public class Ball : MonoBehaviour {

    private float speed = 20.0f;    //これを追加

    // Use this for initialization
	void Start () {
        //以下を追加
        this.GetComponent<Rigidbody>().AddForce(
            (transform.forward + transform.right) * speed,
            ForceMode.VelocityChange);
	
	}
	
	// Update is called once per frame
	void Update () {
	
	}
}
```

部分的に解説します。

```csharp
    private float speed = 20.0f; 
```

変数名`speed`という小数が使える変数で、初期値を20にして宣言しています。これを速度とみなしています。

```csharp
        this.GetComponent<Rigidbody>().AddForce(
            (transform.forward + transform.right) * speed,
            ForceMode.VelocityChange);
```

ここでは、このスクリプトの結びついた`Rigidbody`の`this.GetConpornent<Rigidbody>()`から、備わっているメソッドの`AddForce`を使って、力を加えています。
`AddForce`には、どちらの向きに力を加えるのかを、3次元のベクトルで指定します。この例では、前方向きの単位ベクトル`transform.forward`と右向きの単位ベクトル`transform.right`を加算し、右前方方向のベクトルを求め、それに対してspeedを乗算しています。speedは変数なので、ベクトルの大きさを変える役割になります。

`AddForce`に関しては、以下を参考にして下さい。
[Unityスクリプトリファレンス Addforce
http://docs.unity3d.com/jp/current/ScriptReference/Rigidbody.AddForce.html]
(http://docs.unity3d.com/jp/current/ScriptReference/Rigidbody.AddForce.html)

これを保存して実行してみましょう。
[![Gyazo](http://i.gyazo.com/66bee052dc2e437a564ca7c9195a7b02.gif)](http://gyazo.com/66bee052dc2e437a564ca7c9195a7b02)

##カメラの位置を調整
現状だと動きが観察しにくいので、`Maincamera`を操作します。`Maincamera`オブジェクトは、ゲーム画面を撮影しているカメラのことです。どこから撮影するか、向いている角度などを設定して、見やすい形にしましょう。
`Maincamera`を選択して、適宜、見やすい位置に'Transform'を変えましょう。このとき、真上近くから見下ろすと全体が判りやすくなります。そのためには回転角度を加えるとよいです。x軸に対して回転したい場合は、`Rotation`の`x`を変えると見やすくなります。値を大きくするとしたにうつむいて、見下ろす方向になります。

[![Gyazo](http://i.gyazo.com/66e052311011dcd4880d49850cf09269.png)](http://gyazo.com/66e052311011dcd4880d49850cf09269)

[![Gyazo](http://i.gyazo.com/398124fce75f8c096359647ba3faf472.png)](http://gyazo.com/398124fce75f8c096359647ba3faf472)

##物理的な属性を変更する
現状だと壁に跳ね返らず、最後に失速して終わります。また、動作方向がxz平面だけでよく、回転に関する動作も要りません。エネルギー損失が全く無い状態が、今回のゲームでは向いていおり、まとめると以下になります。

* 空気抵抗が無い
* 摩擦が無い
* 回転に関する摩擦が無い
* 移動するのはxz平面上に限定する
* 回転しない
* 速度を維持して跳ね返る（エネルギー損失が無い）

###`Rigidbody`で抵抗や軸固定を設定する
空気抵抗などの影響を受けないように、設定を変えます。
[![Gyazo](http://i.gyazo.com/36b0048f53779ed9b836942d877e82d5.png)](http://gyazo.com/36b0048f53779ed9b836942d877e82d5)
`Drag`と`Anguar Drag`が0になると、空気抵抗が消えます。
xz平面だけの移動で、尚且つ回転しない設定にするには、`Rigidbody`コンポーネントの最下部にある`Constrain`で設定できます。これで固定したい値にチェックを入れます。今回は位置（Position）のY、回転角度（Rotation）のxyzにチェックを入れました。
[![Gyazo](http://i.gyazo.com/141862984bb114aa1af17c6a535883c6.png)](http://gyazo.com/141862984bb114aa1af17c6a535883c6)

これで動作を確かめると、、以下になります。
[![Gyazo](http://i.gyazo.com/3e4f07bbafe899246965d4110b2e041e.gif)](http://gyazo.com/3e4f07bbafe899246965d4110b2e041e)

###物理的な材質`Physic Material`を設定し、跳ね返り係数を設定する
ボールは壁に当たりますが、跳ね返りません。跳ね返る係数を設定するには、物理的な材質を設定する`Physic Material`が必要になります。
下のAssetタブの左上の[Create]>[Physic Material]を選択します。
[![Gyazo](http://i.gyazo.com/3e98c7805dc3a0f0019504d7151d9519.gif)](http://gyazo.com/3e98c7805dc3a0f0019504d7151d9519)

Asset内に`New Physic Material`が出来上がるので、名前を`Ball Physic Material`に変えます。
[![Gyazo](http://i.gyazo.com/fa4d6a3b217a6946ef2125f74f72b40c.png)](http://gyazo.com/fa4d6a3b217a6946ef2125f74f72b40c)


`Physic Material`に関しては、以下に解説があります。
[Unity-マニュアル：物理属性マテリアル
http://docs.unity3d.com/ja/current/Manual/class-PhysicMaterial.html]
(http://docs.unity3d.com/ja/current/Manual/class-PhysicMaterial.html)



これを選択状態し、[Inspector]タブで設定を変更します。

|プロパティー|説明|
|:---|:---|
|Dynamic Friction|動摩擦。通常は、0 （なし）から 1（重力なしで素早く停止） の間。
|Static Friction|静止摩擦。
|Bounciness|面の跳ね返し度合い。0 (なし）から1（損失なし）
|Friction Combine|衝突時の摩擦の結合方法
|Bounce Combine|跳ね返し度合の結合方法

今回は、以下を設定します。

* 摩擦は全く無い
* エネルギー損失の無い跳ね返り
* 衝突時の摩擦の計算は最小に
* 衝突時の跳ね返りは最大に

[![Gyazo](http://i.gyazo.com/14fdb00d2d21a73e79f79227d64fe9f4.png)](http://gyazo.com/14fdb00d2d21a73e79f79227d64fe9f4)

出来た`Ball Pysic Material`を`Ball`オブジェクトの`Sphere Collider`コンポーネントに与えます。
`Sphere Collider`コンポーネントのMaterialのところにある○をクリックし、`Ball Pysic Material`を設定します。

[![Gyazo](http://i.gyazo.com/371d318a50cfac5f7fd926f8f37e0703.gif)](http://gyazo.com/371d318a50cfac5f7fd926f8f37e0703)

設定が変わって、跳ね返るようになりました。
[![Gyazo](http://i.gyazo.com/53f0d5d6a61796c6188fb9c2872f7658.png)](http://gyazo.com/53f0d5d6a61796c6188fb9c2872f7658)

[![Gyazo](http://i.gyazo.com/f46ca32ce25141ec63494c4fe97078f3.gif)](http://gyazo.com/f46ca32ce25141ec63494c4fe97078f3)


#まとめ

* 力を加えるにはスクリプトを用いる
 * スクリプトはアセットで新規に作成する
 * 内容を変更するにはダブルクリックでエディタを開く
 * `Start`のところに処理を書く
 * 力を与えるメソッドは`Rigidbody`コンポーネントの`Addforce`
* 空気抵抗や摩擦、軸の固定は`Rigidbody`コンポーネントで設定する
* 跳ね返りなど衝突時の演算が必要な物理属性は'Physic Material'コンポーネントをアセットで用意し、用いる 

***

この解説は以下の段階があります、前の内容を実行した上でのものとして参照して下さい。

* [[超初心者向け]Unityチュートリアル「はじめてのUnity」のブロック崩しと同等をC#で::(1)ステージ配置](http://qiita.com/JunShimura/items/cbb0db8087a5cc75735e)
* [[超初心者向け]Unityチュートリアル「はじめてのUnity」のブロック崩しと同等をC#で::(2)色を変える](http://qiita.com/JunShimura/items/1b2b4842e983022075de )
* [__[超初心者向け]Unityチュートリアル「はじめてのUnity」のブロック崩しと同等をC#で::(3)動くボール__](http://qiita.com/JunShimura/items/dfb2bdbbc328869f62ec )
* [[超初心者向け]Unityチュートリアル「はじめてのUnity」のブロック崩しと同等をC#で::(4)ラケットを動かす]
(http://qiita.com/JunShimura/items/5fac20966bba6b223427)
* [[超初心者向け]Unityチュートリアル「はじめてのUnity」のブロック崩しと同等をC#で::(5)消えるブロック](http://qiita.com/JunShimura/items/867179092a2a564bc88c)
* [[超初心者向け]Unityチュートリアル「はじめてのUnity」のブロック崩しと同等をC#で::(6)ブロックを手作業で並べる](http://qiita.com/JunShimura/items/1f39e52414171c67bc71)