【テトリス作成⑦】ブロックの操作機能作成について深掘る

こちらを元に解説しています。
https://qiita.com/hanatan079/items/3675855784e14acda119

★★★★★随時更新★★★★★
2022.11.22追記
20022.12.2追記
★★★★★★★★★★★★★★★
```
（見本）GameManeger.cs

//入力受付タイマー(3種類)
    float nextKeyDownTimer, nextKeyLeftRightTimer, nextKeyRotateTimer;

//インターバル（3種類）
    [SerializeField]
    private float nextKeyDownInterval, nextKeyLeftRightInterval, nextKeyRotateInterval;

        //タイマーの初期設定(スタート)
        nextKeyDownTimer = Time.time + nextKeyDownInterval;
        nextKeyLeftRightTimer = Time.time + nextKeyLeftRightInterval;
        nextKeyRotateTimer = Time.time + nextKeyRotateInterval;

    //キーの入力を検知してブロックを動かす関数
    void PlayerInput()
    {
        if (Input.GetKey(KeyCode.D) && (Time.time > nextKeyLeftRightTimer) || Input.GetKeyDown(KeyCode.D))
        {
            //右に動かす
            activeBlock.MoveRight();

            nextKeyLeftRightTimer = Time.time + nextKeyLeftRightInterval;

            if (!board.CheckPosition(activeBlock))
            {
                activeBlock.MoveLeft();
            }

        }
            //左に動かす
        else if (Input.GetKey(KeyCode.A) && (Time.time > nextKeyLeftRightTimer) || Input.GetKeyDown(KeyCode.A))
        {
            activeBlock.MoveLeft();

            nextKeyLeftRightTimer = Time.time + nextKeyLeftRightInterval;

            if (!board.CheckPosition(activeBlock))
            {
                activeBlock.MoveRight();
            }
        }
        else if (Input.GetKey(KeyCode.E) && (Time.time > nextKeyRotateTimer))
        {
            activeBlock.RotateRight();
            nextKeyRotateTimer = Time.time + nextKeyRotateInterval;

            if (!board.CheckPosition(activeBlock))
            {
                activeBlock.RotateLeft();
            }

        }
        //下に動かす
        else if (Input.GetKey(KeyCode.S) && (Time.time > nextKeyDownTimer) || (Time.time > nextdropTimer))
        {
            activeBlock.MoveDown();

            nextKeyLeftRightTimer = Time.time + nextKeyDownInterval;
            nextdropTimer = Time.time + dropInterval;

            if (!board.CheckPosition(activeBlock))
            {
                BottomBoard();
            }
        }
    } 


    //ボードの底についた時に次のブロックを生成する関数
    void BottomBoard()
    {
        activeBlock.MoveUp();
        board.SaveBlockInGrid(activeBlock);

        activeBlock = spawner.SpawnBlock();

        nextKeyDownTimer = Time.time;
        nextKeyLeftRightTimer = Time.time;
        nextKeyRotateTimer = Time.time;
    }
```

解説

【入力受付タイマ(3種類)】
```
    float nextKeyDownTimer, nextKeyLeftRightTimer, nextKeyRotateTimer;
```
変数3つ(下にいく、左右、回転)

float型について
https://qiita.com/hanatan079/items/36386ae4335bb0b06c88


【インターバル（3種類）】
```
    ①[SerializeField]
    private float nextKeyDownInterval, nextKeyLeftRightInterval, nextKeyRotateInterval;
```
①インスペクタから呼び出し可能
インターバル３つ(下にいく、左右、回転)


【タイマーの初期設定(スタート)】
```
        nextKeyDownTimer = Time.time + nextKeyDownInterval;
        nextKeyLeftRightTimer = Time.time + nextKeyLeftRightInterval;
        nextKeyRotateTimer = Time.time + nextKeyRotateInterval;
```
タイマーは経過時間とインターバルを合わせた時間


【キーの入力を検知してブロックを動かす関数】
```
    void PlayerInput()
    {
        ①if (Input.GetKey(KeyCode.D) && ②(Time.time > nextKeyLeftRightTimer) || ③Input.GetKeyDown(KeyCode.D))
        {
　　　　　　　　　　　　　　　　　　　　　　　　//右へ
            ④activeBlock.MoveRight();
            ⑤nextKeyLeftRightTimer = Time.time + nextKeyLeftRightInterval;
            ⑥if (!board.CheckPosition(activeBlock))
            {
                ⑦activeBlock.MoveLeft();
            }
        }
            //左に動かす
       ①else if (Input.GetKey(KeyCode.A) && ②(Time.time > nextKeyLeftRightTimer) || ③Input.GetKeyDown(KeyCode.A))
        {
            ④activeBlock.MoveLeft();
            ⑤nextKeyLeftRightTimer = Time.time + nextKeyLeftRightInterval;
            ⑥if (!board.CheckPosition(activeBlock))
            {
                ⑦activeBlock.MoveRight();
            }
        }
　　　　　　　　　　　　　　　　//回転
        ①else if (Input.GetKey(KeyCode.E) && ②(Time.time > nextKeyRotateTimer))
        {
                ④activeBlock.RotateRight();
            　　　　　　　　⑤nextKeyRotateTimer = Time.time + nextKeyRotateInterval;
            ⑥if (!board.CheckPosition(activeBlock))
            {
                ⑦activeBlock.RotateLeft();
            }
        }
        //下に動かす
        ①else if (Input.GetKey(KeyCode.S) && ②(Time.time > nextKeyDownTimer) || ⑧(Time.time > nextdropTimer))
        {
            ④activeBlock.MoveDown();
            ⑤nextKeyDownTimer = Time.time + nextKeyDownInterval;
            ⑤nextdropTimer = Time.time + dropInterval;
            ⑥if (!board.CheckPosition(activeBlock))
            {
               ⑨BottomBoard();
            }
        }
    } 

```
①ボタンが押されているかの判定(DAESキー)
②ボタンが押され続けている間でも一定時間が経過しないと条件が当てはまらない
③GetKeyDown押された瞬間(連打された時は初めだけ)を感知する
　　　①〜③⑧　①②のどっちもがtrueの時、又は①②のどっちもか③,⑧がtrueの時
④MoveRight（右）へ、MoveLeft(左)へ、RotateRight（右回転）、MoveDown(下)へ
⑤タイマーの更新
⑥再度、枠からはみ出ていないかの確認
　　　　！=false / はみ出た時はtrue
⑦はみ出た時は反対にずらして戻す
⑧時間経過で自動に落ちる
⑨関数呼び出し(ボードの底についた時に次のブロックを生成する関数)

voidについて
https://qiita.com/hanatan079/items/36386ae4335bb0b06c88
演算子について
https://qiita.com/hanatan079/items/01530bc45bab85f3d19f


【ボードの底についた時に次のブロックを生成する関数】
```
    void BottomBoard()
    {
        ①activeBlock.MoveUp();
        ②board.SaveBlockInGrid(activeBlock);

        ③activeBlock = spawner.SpawnBlock();
　　　　　　　　　　　　　　　④
        nextKeyDownTimer = Time.time;
        nextKeyLeftRightTimer = Time.time;
        nextKeyRotateTimer = Time.time;
    }
```
①枠からでたブロックを上にあげて枠内におさめる
②２次元配列に今の位置を記録させる。SaveBlockInGrid関数、activeBlock引数
③新しいブロックを生成してactiveBlockへ格納する
④タイマーを初期化する