【Unity】2Dシューティングを作ってみる話 #6

記事をご覧いただき、誠にありがとうございます。
投稿主の無能です。

前回は公式のチュートリアルを少し発展させて、流れる背景の仕組みを作りました。

今回はAndroidで操作できるように、バーチャルスティックを追加したいと思います。

バーチャルスティックを導入する

バーチャルスティックを導入するにあたり、自前で用意するのもアリなんですが、スクリプトを書いたりなんだりと実装するまでがとても面倒なので、偉大なるアセットの力を借りて実装します。

今回導入するアセットはこちらです。

Joystick Pack - Unity Asset Store

このJoystick Packですが、シンプルだけどとても良く考えられた、開発者側の負担を軽減させてくれるアセットだと思います。

素晴らしい!の一言ですね。
このアセット、マジでこのまま公式になったりしないかなぁ、と個人的には思います。

ではアセットストアで自分のアセットに追加して、Unityにインポートします。

アセットストアのアセットを作成中のプロジェクトへインポート

Unityにインポートするには、Package ManagerからPackagesでMy Assetsを選択し、アセットストアで追加したJoystick Packをダウンロード、インポートします。

Package ManagerはWindow > Package Managerで開きます。

Window > Package Managerで開く

Package ManagerのPackagesでMy Assetsを選択

一覧からJoystick Packを探す

初回はDownloadになっている
2回目以降は再ダウンロードかインポートになる

右下のImportボタンを押下する

インポートが完了すると、Package Managerに戻ります。
Package Managerのウィンドウはインポートが完了したので閉じます。

これでJoystick Packのインポートが出来ました。

次は、このJoystick Packを実装していきます。

Joystick Packを実装する

Joystick Packを実装するには、まずJoystick Packを表示させるための土台となるCanvasが必要になります。

GameObject > UI > Canvas でCanvasを追加します。

GameObject > UI > Canvas でCanvasを追加

追加したら、名前を「forAndroidControl」にします。

名前を「forAndroidControl」にする

このままだと、サイズが固定されているので、画面に応じて伸縮するようにします。

Canvas ScalerのUI Scale ModeをScale with Screen Sizeにします。

Canvas ScalerのUI Scale ModeをScale with Screen Sizeにする

すると解像度を設定するReference Resolutionの項目が出てくるので、ご自身のAndroidデバイスの解像度にあわせてください。

今回はQHD(2560×1440)にします。

勿論サイズが違っていたら、修正も可能です。

QHD(2560×1440)にする

Gameビューの画面サイズもあわせて変更します。

Gameビューの画面サイズを変更

次にMatchをHeight(1)にします。

MatchをHeight(1)にする

これでCanvasの設定が終わったので、次はJoystick Packからバーチャルスティックを実際にCanvasに配置します。


インポートしたJoystick PackのファイルがAssetsフォルダ内に出来ているので、Prefabsフォルダ内のVariable Joystickを、HierarchyビューのCanvas、つまり先程作成したforAndroidControlにドラッグします。

Assetsフォルダ内にJoystick Packのファイルが出来ている

Prefabsフォルダ内のVariable Joystickをドラッグする

forAndroidControlの子オブジェクトにする

これでCanvasでバーチャルスティックが表示されるようになります。

バーチャルスティックが表示されるようになった

次に、バーチャルスティックの動作範囲を設定します。

Androidデバイスの画面上で、どのくらいの範囲でバーチャルスティックが反応するか、という範囲を動作範囲と無能が勝手に言ってる造語なのであまり気にしないでください。

Canvas全体がSceneビューに映るようにして、Variable Joystickをフォーカス(ダブルクリック)します。

すると範囲が設定できるので、範囲をCanvas全体の左半分にします。

Canvas全体がSceneビューに映るようにして、Variable Joystickをフォーカス(ダブルクリック)する

表示された範囲をドラッグしてforAndroidControlの左半分になるように調整する

これで動作範囲の設定が出来ました。

次はバーチャルスティックの挙動を設定します。

Variable JoystickのInspectorビューにあるJoystick TypeをFloatingにします。

Joystick TypeをFloatingにする

これでバーチャルスティックの準備が出来ました。

Joystick Packの詳細な説明については他の紹介記事の方が詳しく説明しているので、ここでは割愛します。
詳細が必要な方は調べてみてください。

あとはスクリプトで、バーチャルスティックが動いたらPlayerを動かせるようにします。

スクリプトを追記する

ではスクリプト追記します。

追記するのはPlayerControllerスクリプトになります。

このようになります。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(Rigidbody2D))]
public class PlayerController : MonoBehaviour
{
    [Header("Playerの動く速さ")]   [SerializeField] float moveSpeed = 1f;
    [Header("移動制限の余白")]     [SerializeField] float marginX = 1f, marginY = 1f;
    [Header("弾のオブジェクト")]   [SerializeField] GameObject playerBullet;
    [Header("弾の速さ")]          [SerializeField] float bulletSpeed = 10f;
    [Header("発射ポイント")]       [SerializeField] Transform playerFirePos;
    [Header("弾の発射の閾値")]     [SerializeField] float bulletDelay = 1f;
    [Header("バーチャルスティック")][SerializeField] VariableJoystick joyStick;

    Rigidbody2D playerRB;                   // プレイヤーのRigidbody
    Vector2 moveDirection, min, max;        // プレイヤーのベクトル,画面サイズの最小ベクトル/最大ベクトル
    Vector2 playerPos;                      // プレイヤーの移動制限用
    float bulletInterval;                   // 弾の発射間隔管理用

    void Start()
    {
        // プレイヤーのRigidbodyを取得
        playerRB = GetComponent<Rigidbody2D>();
    }

    void Update()
    {
        // 入力受付
        InputProcess();

        // バーチャルスティック処理 ---
        // バーチャルスティックに何らかの入力が合った場合
        // (joyStickが0では無い場合)
        if (joyStick.Direction != Vector2.zero)
        {
            // moveDirectionをバーチャルスティックの入力にする
            moveDirection = joyStick.Direction;
        }
        // --- ここまで

        // 弾の発射 ---
        // deltaTimeを加算
        bulletInterval += Time.deltaTime;
        // 発射間隔が閾値未満の場合
        if (bulletInterval < bulletDelay)
        {
            // 処理を中断
            return;
        }
        // スペースキーが押された場合
        if (Input.GetKey(KeyCode.Space))
        {
            // 弾の発射関数を呼ぶ
            PlayerShot(playerFirePos);
        }
        // 発射間隔をリセット
        bulletInterval = 0;
        // --- ここまで

    }

    void FixedUpdate()
    {
        // プレイヤーを動かす
        PlayerMove();
    }

    // 入力受付
    void InputProcess()
    {
        // 入力を正規化して受け取る
        float x = Input.GetAxisRaw("Horizontal");
        float y = Input.GetAxisRaw("Vertical");
        // 入力を正規化する
        moveDirection = new Vector2(x, y).normalized;
    }

    // プレイヤーを動かす
    void PlayerMove()
    {
        // 移動制限
        MoveClamp();
        // プレイヤーを動かす
        playerRB.velocity = moveDirection * moveSpeed;
    }

    // プレイヤーの移動制限
    void MoveClamp()
    {
        // 最後の移動地点を取得
        playerPos = transform.position;
        // ビューポート座標からワールド座標を取得
        min = Camera.main.ViewportToWorldPoint(Vector2.zero);
        max = Camera.main.ViewportToWorldPoint(Vector2.one);
        // 移動を制限する
        playerPos.x = Mathf.Clamp(playerPos.x, min.x + marginX, max.x - marginX);
        playerPos.y = Mathf.Clamp(playerPos.y, min.y + marginY, max.y - marginY);
        // プレイヤーの位置を取得した最後の地点にする
        transform.position = playerPos;
    }

    // 弾の発射
    void PlayerShot(Transform firePos)
    {
        // 弾を生成
        GameObject bulletClone = Instantiate(playerBullet, firePos.position, Quaternion.identity);
        // 弾のRigidbodyに速度ベクトルをつける
        bulletClone.GetComponent<Rigidbody2D>().velocity = new Vector2(bulletSpeed, 0);
    }
}

追記したのはほんの僅かですが、これで動くようになります。

それでは説明していきます。

まずはVariable JoystickをjoyStickとして、Inspectorビューで設定出来るようにしてあります。

joyStickはUpdate関数内で、入力がされた場合にmoveDirectionにjoyStickの動きを代入しています。

バーチャルスティックの入力判定は、バーチャルスティックの動きが0以外(Vector2.zero)の場合としました。
これで何らかの入力がされた、とみなしています。

スクリプトの追記がたったこれだけになるなんて…
やっぱりJoystick Packは凄いし超便利…!

という事で、Unityに戻ってPlayerのInspectorビューに設定しましょう。

Playerを選択して、forAndroidControlの中にあるVariable Joystickをドラッグします。

forAndroidControlの中にあるVariable Joystickをドラッグする

ではゲームを実行して確認してみましょう。

バーチャルスティックでPlayerが動かせるようになった

勿論、従来通りキーボードでも動かせます。

ゲームを実行したままキーボードの方向キーでも操作可能です。

キーボードの方向キーでも操作可能

そして動作範囲を設定したので、Gameビューの右半分ではバーチャルスティックが表示されていません。
(画像は割愛します)

これがアセットのパワー!(某タレントの笑顔)

まとめ

今回は
  • Canvasを追加してバーチャルスティックが表示できる土台を作った
  • Joystick Packというアセットをインポートして、Canvasで表示するように設定した
  • スクリプトを追記してバーチャルスティックでの移動が可能になった
という事をやりました。

次回は、ここまでの設定がAndroidで反映されるかを確認したいので、.exeファイルとAndroidデバイス向けのビルドをしたいと思います。

では、また次回!

コメント