3DのTPSシューティングゲームを作りたい人の日記

#はじめに
この記事は私がUnityで3DのTPSシューティングゲームを作る過程を残しておくために書いています(随時更新予定)。

プログラムを組む過程で詰まったところで参考にしたもの等を書いていくので、同じようなことで詰まっている方の助けになればと思います。

#作りたいもの
![Sooting game image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688227/e11b740f-a469-c274-e100-9dbf07330e69.png)
上の画像のようなイメージの物を作りたい！・・・と言ってもこの絵ではちょっと絵心なくて伝わらないと思うので、簡単に説明します。

**生き物がほとんど滅んだ世界で、そこかしこに現れる敵を倒しながら大事なものを持って旅をするゲーム**を作りたい！

とは言ったものの、ふわっとしてるし、簡単に広い世界を移動するようなゲームを作れるとは思えないので、第一の目標として

**スタート地点からゴール地点まで大事なものを敵を倒しながら運ぶゲーム**を作ろうと思っています。

#進歩
オブジェクトは仮置きですが，次の動作が出来る状態です。
操作はPS4のコントローラーで行うことを想定して作っています。
-プレイヤーの移動
-プレイヤーに追従し、プレイヤー(正確には少し上)を中心に回転するカメラ
-銃からマズルフラッシュと、照準の先に物体があった場合は当たった場所にエフェクトが出るようにする
![コメント 2020-08-07 224920.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688227/0e25434e-5e5d-ee83-a3b1-0a48b52badc5.png)

#PS4のコントローラーに関する設定
PS4のコントローラーを使うためには、まずコントローラーの操作割り当てを行わなければなりません。
そこで、参考にさせていただいた記事は以下の二つになります。
[UnityでPS4コントローラ(DuelShock4)を使う](https://qiita.com/o_s_t/items/c18edeeee869d42c6eb9)
[周回遅れのゲーム工房 UnityでPS4のコントローラーを使う方法](https://ikubo.jp/game/unity-bonfire-dualshock4/)

#プレイヤーとカメラ
ここでは、プレイヤーとカメラに関する処理のプログラムについて書きます。ここではこちらの記事を参考にさせていただきました。
[Unityでカメラの向きを基準に移動する方法と、追従して回転できるカメラの実装](https://tech.pjin.jp/blog/2016/11/04/unity_skill_5/)
-プレイヤーの移動
ここで、移動はコントローラーの左スティックで行えるようになっています。

```

    float inputHorizontal;
    float inputVertical;
    Rigidbody rb;
    
    float moveSpeed = 3f;
    
    void Start() {
        rb = GetComponent<Rigidbody>();
    }
    
    void Update() {
        inputHorizontal = Input.GetAxisRaw("Horizontal Stick-L");
        inputVertical = Input.GetAxisRaw("Vertical Stick-L") * -1;
    }
    
    void FixedUpdate() {
        // カメラの方向から、X-Z平面の単位ベクトルを取得
        Vector3 cameraForward = Vector3.Scale(Camera.main.transform.forward, new Vector3(1, 0, 1)).normalized;
    
        // 方向キーの入力値とカメラの向きから、移動方向を決定
        Vector3 moveForward = cameraForward * inputVertical + Camera.main.transform.right * inputHorizontal;
    
        // 移動方向にスピードを掛ける。ジャンプや落下がある場合は、別途Y軸方向の速度ベクトルを足す。
        rb.velocity = moveForward * moveSpeed + new Vector3(0, rb.velocity.y, 0);
    
        // キャラクターの向きを進行方向に
        if (moveForward != Vector3.zero) {
            transform.rotation = Quaternion.LookRotation(moveForward);
        }
    }
```

-カメラの操作
ここで，カメラ移動はコントローラーの右スティックで行えるようになっています。

```

    public new GameObject targetObj;
    Vector3 targetPos;
    float speedX = 200.0f;
    float speedY = 200.0f;
    float angleLimitUp;
    float angleLimitDown;
    float stickInputX = 0f;
    float stickInputY = 0f;
    bool stickFlag_h = false;
    bool stickFlag_v = false;
    float r = 0f;
    float myPositionY;

    void Start () {
        targetPos = targetObj.transform.position;
        r = Mathf.Abs(targetPos.z - this.transform.position.z);
        angleLimitUp = targetPos.y + r*Mathf.Sin(80.0f * Mathf.Deg2Rad);
        angleLimitDown = targetPos.y +  r*Mathf.Sin(-45.0f * Mathf.Deg2Rad);
    }
    
    void Update() {
        Transform myTransform = this.transform;
        // targetの移動量分、自分（カメラ）も移動する
        transform.position += targetObj.transform.position - targetPos;
        targetPos = targetObj.transform.position;
    
        //Rスティックが左に倒されたら右回転
        if(Input.GetAxis("Horizontal Stick-R") < 0){
            stickFlag_h = true;
            stickInputX = Input.GetAxis("Horizontal Stick-R");
            // targetの位置のY軸を中心に、回転（公転）する
            transform.RotateAround(targetPos, Vector3.up, stickInputX * Time.deltaTime * speedX);
        }
        //Rスティックが右に倒されたら左回転
        if(Input.GetAxis("Horizontal Stick-R") > 0){
            stickFlag_h = true;
            stickInputX = Input.GetAxis("Horizontal Stick-R");
            // targetの位置のY軸を中心に、回転（公転）する
            transform.RotateAround(targetPos, Vector3.up, stickInputX * Time.deltaTime * speedX);
		}
        //Rスティックが上に倒されたら下回転
        if(Input.GetAxis("Vertical Stick-R") < 0){
            stickFlag_v = true;
            stickInputY = Input.GetAxis("Vertical Stick-R");
            myPositionY = myTransform.position.y;
            if(myPositionY > angleLimitDown){
                // カメラの垂直移動
                transform.RotateAround(targetPos, transform.right, stickInputY * Time.deltaTime * speedY);
            }
        }
        //Rスティックが下に倒されたら上回転
        if(Input.GetAxis("Vertical Stick-R") > 0){
            stickFlag_v = true;
            stickInputY = Input.GetAxis("Vertical Stick-R");
            myPositionY = myTransform.position.y;
            if(myPositionY < angleLimitUp){
                // カメラの垂直移動
                transform.RotateAround(targetPos, transform.right, stickInputY * Time.deltaTime * speedY);
            }
        }
        stickFlag_h = false;
        stickFlag_v = false;
    }
```

#武器の動作
今回は実際に銃から弾丸を発射するのではなく、エフェクトで表現することを考えてプログラムしています。
銃からマズルフラッシュと、照準の先に物体があった場合は当たった場所にエフェクトが出るようにすることで表現しています。
ここではこちらの記事を参考にさせていただきました。
[弾の発射処理の作り方＆エフェクトの追加方法]
(https://unity.moon-bear.com/zombie-slayer/shoot-and-effect/)
武器の動作に関するプログラムは参考記事そのままなので、ここには記載しません。今後エフェクトは変更する予定です。

#今後
とりあえず
**プレイヤーの3Dモデルを作って歩くアニメーションを作る！**

今はカメラに対して横に移動しながら正面に銃を撃つ場合でもプレイヤーは横を向いてしまっていて、違和感しかないので、解消するためにモデルを作ってアニメーションを作ってみようと思います。