マリオカートの緑こうらっぽいのを作ろう【Unity3D】

Googleで「Unity 緑こうら」と調べてもUnityについての記事が見つからなかったので
今更ですがメモとして書きたいと思います。
(そもそも検索エンジンで出てこないということは調べてる人が少なすぎるということでこの記事の必要性低い?w)

3Dで進めていきます。2Dでも少し変えればできます。

---
#オブジェクトの作成

###キャラの作成
では早速始めていきましょう。

あるシーンに下の様にオブジェクトを作ってください。

- Player (キューブ)
- MidoriKoura (キューブ)

![PlayerとMidoriKoura](https://qiita-image-store.s3.amazonaws.com/0/307779/4fb97f45-6737-b5cc-44e2-387d0bcf5f31.png)
**MidoriKoura**に緑色のマテリアルを付けました。

次に**MidoriKoura**にRigidbodyを追加してy座標を固定してください。
**Angular Drag**を0にし、**Use Gravity**のチェックを外します。
**Angular Drag**は空気抵抗です。0にした場合それが無くなります。
**Use Gravity**は重力の有無です。
![MidoriKoura.Rigidbody](https://qiita-image-store.s3.amazonaws.com/0/307779/840d3fc0-351d-6e33-2bf7-5129c0c51ce3.png)

**Player**にもRigidbodyを追加します。値はそのままでいいです。
![Player.Rigidbody](https://qiita-image-store.s3.amazonaws.com/0/307779/f7406e71-ba2f-1ca1-0aa4-e365c93d8729.png)

####Physic Materialの作成

**[Physic Material](https://docs.unity3d.com/ja/2018.1/Manual/class-PhysicMaterial.html)**で摩擦や弾性などを設定できます。
Collider関連のコンポーネントに**Material**という項目がありますよね？
そこにアタッチするものです。

Projectウィンドウで*Create -> Physic Material* で作成してください。
名前は何でもいいです。
![New Physic Material](https://qiita-image-store.s3.amazonaws.com/0/307779/9d3157cd-d58c-8d0a-bf3a-313c6fda0248.png)

New Physic Materialを選択してインスペクターから値を変えていきます。
画像のように設定してください。
**Friction Combine**はMinimum、**Bounce Combine**はMaximumであることに注意してください。
![New Physic Material(Inspecter)](https://qiita-image-store.s3.amazonaws.com/0/307779/ad3b0710-cc18-8777-ffa7-cb2a8622f7d4.png)


これを**MidoriKoura**の**Box Collider**にある**Material**にアタッチしてください
![MidoriKoura.BoxCollider.Material](https://qiita-image-store.s3.amazonaws.com/0/307779/6ebc6e08-31d7-d7ca-efbd-22fc48d9a1fe.png)



###ステージを作成

キューブオブジェクトでステージを作ってみました。
![Stage](https://qiita-image-store.s3.amazonaws.com/0/307779/f8dc2038-ab8f-7f8f-8f11-e9c7012152ae.png)

床となるStage、壁となるWallでステージを作っています。

これらのオブジェクトにはその他のコンポーネントを追加しなくても大丈夫です。

#スクリプト

今回は、**緑こうらの動きをするスクリプト**と**Playerを動かすスクリプト**の２つを書きます。

####Midorikouraの動きをするスクリプト

```C#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MidoriKouraMovement : MonoBehaviour
{
    float speed = 1000;
    void Start()
    {
        this.GetComponent<Rigidbody>().AddForce(transform.right * speed + transform.forward * speed);
    }

    private void OnCollisionEnter(Collision collision)
    {
        if (collision.gameObject.name == "Player")
        {
            Destroy(this.gameObject);
        }
    }
}
```
ゲーム起動時に右上にオブジェクトが押されるようにして、Playerに当たったときに消すだけです。
Playerのオブジェクトの名前が Player じゃない方は、
コード内の"Player"の部分をそのオブジェクトの名前に設定してください。

保存したら**MidoriKoura**にアタッチしてください。

そしてプレイしてみてください。

壁に跳ね返って動き回ると思います。
Playerに当たると消えると思います。

スピードが遅いと感じる方はspeedの値を上げてください。

####Playerの動きをするスクリプト

``` c#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerMovement : MonoBehaviour
{
    private void OnCollisionEnter(Collision collision)
    {
        if(collision.gameObject.name == "MidoriKoura")
        {
            Destroy(collision.gameObject);
        }
    }
}
```

保存したらPlayerにアタッチしてください。
**MidoriKoura**が当たったら**Player**も消えるようにしただけです。

---

##MidoriKouraが壁に10回当たったら消えるようにする

ここまでのスクリプトでは**MidoriKoura**はPlayerに当たるまで永遠に動き回ります。

10回壁にあたったら消えるようにしましょう。

###壁にタグを追加

今のステージでは、コンピュータからしてみれば床や壁の区別がついていません。
同じ扱いを受けています。
このままでは**壁だけ**反応させることはできません。
他に区別の仕方はあると思いますが、今回はタグを使って区別していこうと思います。

壁になっているオブジェクトを選択(CTRLキーで複数選択)して、Tag [Untagged] をクリックして**Add tag...**でタグを追加します。
![Wall.tag](https://qiita-image-store.s3.amazonaws.com/0/307779/7a0bbd7d-4d60-ad8d-89d1-35c1355cc38d.png)

 [+] をクリックして_Wall_というタグを作ってください。
![Wallタグ作成](https://qiita-image-store.s3.amazonaws.com/0/307779/ff1276ec-754e-601d-b5ff-6dee6faf1b58.png)

再びWallゲームオブジェクトを選択して_Wall_を決定してください。
![Wallタグ追加](https://qiita-image-store.s3.amazonaws.com/0/307779/aa364927-6317-c121-6455-83e9008677a8.png)

これでWallを認識できました。

###スクリプトの編集

**MidoriKouraMovement**をもう一度編集します。

```c#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MidoriKouraMovement : MonoBehaviour
{
    float speed = 1000;
    void Start()
    {
        this.GetComponent<Rigidbody>().AddForce(transform.right * speed + transform.forward * speed);
    }

    int count = 0;
    private void OnCollisionEnter(Collision collision)
    {
        if (collision.gameObject.name == "Player")
        {
            Destroy(this.gameObject);
        }

        if(collision.gameObject.tag == "Wall")
        {
            count += 1;
            if(count >= 10)
            {
                Destroy(this.gameObject);
            }
        }
    }
}
```

**MidoriKoura**が壁にぶつかるたびにcountを1増やし、
countが10以上になったとき消すようにしています。

##スタートの方向をランダムにする

この状態では**MidoriKoura**の力の方向は右奥になります。
これをランダムにします。

```c#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MidoriKouraMovement : MonoBehaviour
{
    float speed = 1000;
    void Start()
    {
        this.GetComponent<Rigidbody>().AddForce(new Vector3(Random.Range(0, 361), 0, Random.Range(0, 361)) * speed);
    }

    int count = 0;
    private void OnCollisionEnter(Collision collision)
    {
        if (collision.gameObject.name == "Player")
        {
            Destroy(this.gameObject);
        }

        if(collision.gameObject.tag == "Wall")
        {
            count += 1;
            if(count >= 10)
            {
                Destroy(this.gameObject);
            }
        }
    }
}
```

変えたのは**Start()**の中だけ変えました。360度の中から乱数で取得します。
その数字に**speed**をかけて移動させています。

ここの**speed**は異常に速いので最初の**speed**を200で割ったくらいの数字がちょうどいいです。

#終わりに

Qiitaどころか記事を書くのをあまりしたこと無いので分かりづらくてすみません。

誤字脱字・情報の誤りがあったらコメントしていただいたら幸いです。