タップしたところに弾を飛ばす方法

シューティングゲームで使えそうな、タップしたところにオブジェクトを飛ばす実装について

:::note info
使用PC： MacBook Pro (13-inch, M1, 2020)
OSバージョン: 11.5.2
Unityバージョン：2020.3.20f1
:::

# 実際にゲームをプレイすると
![シューティング動画_AdobeCreativeCloudExpress.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890419/f4bd1d02-f03a-7e08-0866-44b167323918.gif)
こんな感じになったら完成です！

# 目次
[1.オブジェクトの準備](#1-オブジェクトの準備)
[2.弾が飛ぶスクリプトの作成](#2-弾が飛ぶスクリプトの作成)
[3.弾の出現位置を作る](#3-弾の出現位置を作る)
[4.弾を生成するスクリプトの作成](#4-弾を生成するスクリプトの作成)
[5.オブジェクトの代入](#5-オブジェクトの代入)

# オブジェクトの準備
①`【Hierarchy】→【Create】→【3D Object】→【Sphere】`で弾オブジェクトを作成する
②名前をBallに変更しておく
③Projectビューにドラッグ&ドロップしてPrefab化しておく
④HierarchyビューのBallは不要なので消しておく
⑤PrefabにしたBallにRigidbodyをAdd Componentする

# 弾が飛ぶスクリプトの作成
`【Project】→【Create】→【C# Script】`でScriptを作成し、名前をBallControllerに変更する


```C#:BallController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BallController : MonoBehaviour
{
    public void Shoot(Vector3 dir)
    {
        GetComponent<Rigidbody>().AddForce(dir);
    }
}
```

これだけ！BallController.csをBallオブジェクトにアタッチする

## コードの解説
まずは弾を飛ばす用の関数 `public void Shoot`を作ります。
その中にRigidbodyのAddForce関数で、Ballオブジェクトに物理的な力を加え移動させるコードを書いてます。
これによって勢いよくボールが飛んでいくように実装しました！

# 弾の出現位置を作る
`【Hierarchy】→【Create】→【Create Empty】`で名前をBallGeneratorに変更

_この`BallGenerator`からBallオブジェクトが出てくるようにしていきます！_

# 弾を生成するスクリプトの作成
`【Project】→【Create】→【C# Script】`でScriptを作成し、名前をBallGeneに変更する

```C#:BallGene.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BallGene: MonoBehaviour
{
    public GameObject BallPrefab;
    GameObject Ball;

    // Update is called once per frame
    void Update()
    {
        if (Input.GetMouseButton(0))
        {
            Ball=Instantiate(BallPrefab) as GameObject;

            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            Vector3 worldDir = ray.direction;
            Ball.GetComponent<BallController>().Shoot(
                worldDir.normalized * 3000);
        }
        Destroy(Ball, 10.0f);
    }
}
```

BallGene.csをBallGeneratorオブジェクトにアタッチする

## コードの解説

**①変数宣言**

```C#:BallGene.cs
public GameObject BallPrefab;
GameObject Ball;
```
大元になる弾のPrefabと、Instantiateする用の弾をGameObject型で宣言します。
PrefabはUnity側で代入するのでpublicをつけておいてください。


**②void Update関数の中に処理を書いていく。**

```C#:BallGene.cs
if (Input.GetMouseButton(0)){
 Ball=Instantiate(BallPrefab) as GameObject;
```

マウスをクリックしたときに処理をif文で書いていきます。
次に変数宣言したGameObject型のBallの中身をBallPrefabとして生成します。

>ちなみに()の中に入れる数字によってクリックの処理が変わります☺️


|メソッド|処理　　　　| 
|:-----------|------------:|
|GetMouseButtonDown(1)     |右クリック時      |
| GetMouseButtonDown(0)   | 左クリック時  |
| GetMouseButtonDown(2)         | 中クリック時  | 


```C#:BallGene.cs
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
Vector3 worldDir = ray.direction;
```

カメラからRayを打ち、画面をクリックしたところの位置と方向をrayに格納します。
ray.directionでカメラからタップした座標に向かうベクトルを規定します。


```C#:BallGene.cs
Ball.GetComponent<BallController>().Shoot(worldDir.normalized * 3000);
```
Ballオブジェクトについて`BallController.cs`の**Shoot関数**を呼び出します。
normalized変数でベクトルの正規化（長さが1のベクトルを生成）して、そこに3000の力を加えていきます。
ここの3000とかは、ご自身のゲームに合わせて数値を変えてみてください。

```C#:BallGene.cs
Destroy(Ball, 10.0f);
```
生成した弾を10秒後に消去します。

# オブジェクトの代入
HierarchyのBallGeneratorオブジェクトを選択し、Inspectorでアタッチしたスクリプト内にあるBall PrefabにBallのPrefabをドラッグ&ドロップする

### 以上！


>参考記事
・[ボールをタップした場所に飛ばす方法と座標系の違い【Unity】](https://goodlucknetlife.com/unity-ball-tap-shoot/)