Unityでゲーム開発


<img width="550" alt="スクリーンショット 2021-03-23 16.18.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064503/58f9c88a-e45e-2e22-3f8a-7941ca893924.png">
今回は「 Carrom 」というボードゲームを題材に Unity と Blender を利用して開発しました。

#Carrom とは
<img width="350" alt="スクリーンショット 2021-03-23 16.05.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064503/52477ea7-45c7-b56a-ae74-be96d1846307.png">
**・ボードゲーム
・ビリヤードによく似ている
・自分のコイン（ストライカー）を指で弾いて中心のコインにぶつけて
　四隅の穴（ポケット）に入れる**


#ルールの設定
<img width="350" alt="スクリーンショット 2021-03-23 17.09.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064503/396362a3-ed26-5561-181d-8b5efd6173f7.png">
**・２人で行う
・交代制
・青チームは白いコインを、緑チームは茶色のコインを全て落とし
　最後に赤いコインを落とすと勝利
・真ん中の赤いコインは得点が3点 他のコインは1点**

その他にも細々としたルールを設定していますが
大きな流れは上記のようになっています。

#Background と Object を配置
<img width="350" alt="スクリーンショット 2021-04-15 16.16.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064503/5a37d67f-8bc0-951e-d177-4dc99d78ffaa.png">
初めに Background （背景）や Object （コイン、ストライカー）を配置しました。
配置しただけなので動きはない状態です。


#スコア機能の作成
<img width="420" alt="スクリーンショット 2021-04-15 16.23.31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064503/c85f6ff7-b687-fd58-e83c-e8a4b452f452.png">
スコアTextをゲーム画面に表示させ、
**四隅の黒い穴にコインが当たったらスコアText に点数を追加**するスクリプトを作成しました。
中央の赤いコインは得点が3点なので Tag（ red ）で判別させます。
不具合が発生しないか確認し無事実装完了！
...ですが、
**開発途中にスコア機能が勝敗に関係ない事に気付きました。**
設計書を作成している途中で気づくべきミスだったと反省しています。
せっかく作ったのでスコアは表示させたままにしました。

#ストライカーの動作処理
今回はクリックした場所にストライカーを飛ばすよう設定しました。

```ruby:Striker.cs 
if (Input.GetMouseButtonDown(0)) 
{

   Vector3 mouseWorldPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
   Vector3 shotForward = mouseWorldPos - transform.position;
   shotForward = Vector3.Scale(shotForward, new Vector3(1, 0, 1))              
   shotForward = shotForward.normalized;
   rigidbody.AddForce(shotForward * strikerSpeed);

}

```

実装後Unity 内 Main Cameraの Projection を Orthographic に切り替えます。

Perspective ... 遠近法を使った描写
Orthographic ... 平行投射を使った描写

Perspectiveを利用するとゲーム画面に奥行きができます。今回の開発したゲームは遠近法を利用しないものだったので Orthographic を利用しました。

#ターン制の実装

対戦相手用のObject（ストライカー）を配置後、ターン制を実装させるための
スクリプトを作成しました。
ターン制は真偽値を利用しました。
下記はターン制を簡単に再現したコードです。

```ruby:GameManager.cs 

public classGameManager : MonoBehaviour
{
    public GameObject Sphere;
    public static bool PlayerTurn;

  void Start()
  {
    Sphere.SetActive (true);
    PlayerTurn = true;
  }

  void Update()
  {

     if (PlayerTurn == true) 
     {
        Sphere.SetActive (false);
        PlayerTurn = false;         
    }   
  }
}

```

#相手のスコア機能実装
<img width="420" alt="スクリーンショット 2021-04-15 16.28.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064503/f02ffd9d-2df9-e2d7-af2b-edb73136dc7f.png">
対戦相手のスコアText を作成し、コインにTagを付けます。
コインの色を Tag で区別し（白は white 、茶色は brown ）
**穴に入ったコインの Tag が
whiteだった場合は青に1点  brownだった場合は緑に1点**
としました。

#勝利TextとRETRYボタンの実装
<img width="420" alt="スクリーンショット 2021-04-15 16.55.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064503/05f9e984-7df3-557a-4009-ce050cfe441b.png">
**if 自分のコインが全て落ちた && 赤コインが落ちた  場合 勝利Textを表示**
としました。
緑用のTextも用意し、全て落ちたコインのTagによって表示させるTextを分岐させています。
**上手く機能しますがかっこいいフォントが見つからず一番修正したい部分です。**
RETRYボタンを勝利Textと同じタイミングで表示させます。
ボタン押下後、スコアを0にし、コインとストライカーをスタート時と同じ位置に配置させました。

#Blenderでコイン作成 配置
<img width="420" alt="スクリーンショット 2021-04-15 16.55.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064503/efd347ce-50f1-f2ad-37db-4c72976e27bd.png">
Blenderでコインを作成しUnityにエクスポートしました。
<img width="700" alt="スクリーンショット 2021-04-15 16.55.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064503/1e0b8f0a-3c9c-e460-379a-8d26f3304fe5.png">
配置前（左）と配置後（右）です。コインが変わるだけでゲームの印象がガラリと変わります。



#まとめ
個人でのゲーム開発は初めてでしたがとても面白かったです。
色々な気付きや発見、失敗がありました。
技術不足はもちろんですが、設計書に関しても反省がありました。
開発途中に設計書のミスに気付き修正した部分が多く、設計書の荒が課題だと感じました。
今回の学びをこれからのものづくりに活かしていきます。