unity

プレイヤーを矢印キーで上下に移動と移動範囲の制限を実装【Unityで2Dシューティングゲームを作ろう②】

こんにちは、シロウです。

前回の記事では『背景をスクロールさせる方法』を解説しました。

今回はプレイヤーの移動と移動範囲の設定を実装していきます。

かなり簡単なので、ぜひご覧ください。

プレイヤーを配置

とりあえず適当にプレイヤーを配置します。

前回の記事で紹介した『Robot Shooting Game Sprite (Free)』をインポートしてくれている人はRobot > robot_idle1を配置して、scaleを(3,3,0)ぐらいにしてください。

プレイヤーの移動スクリプト

まずはprojectウィンドウで新しいスクリプトを作ります。(今回は『PlayerController』という名前にしました。)

そして、PlayerControllerに下記のコードを記述してください。

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

public class PlayerController : MonoBehaviour
{
    [SerializeField] private float speed;//プレイヤーの移動速度

    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        MovePlayer(); //プレイヤーを動かすメソッドを呼び出す
    }

    void MovePlayer()
    {
        //もし上矢印キーが押されたら
        if (Input.GetAxisRaw("Vertical") > 0)
        {
            Vector3 playerPos = transform.position; //Vector3型のplayerPosに現在の位置情報を格納
            playerPos.y += speed * Time.deltaTime; //y座標にspeedを加算
            transform.position = playerPos; //現在の位置情報に反映させる

        } else if(Input.GetAxisRaw("Vertical") < 0) //もし下矢印キーが押されたら
        {
            Vector3 playerPos = transform.position;
            playerPos.y -= speed * Time.deltaTime;
            transform.position = playerPos;
        }
    }
}

 

簡単に解説していきます。

if (Input.GetAxisRaw("Vertical") > 0)

まずGetAxisRawは引数の矢印キーを押した時に1か-1に引数を返してくれます。

引数がVerticalなら上下キー、Horizontalなら左右キーを表します。

今回の場合はVerticalを引数に指定しているので、上(↑)キーを押した時に「1」、下(-1)を押した時に「-1」を返してくれます。

ということで、この文表しているのは「もし上(↑)キーを押したらif文内の処理を開始する」ということです。

Vector3 playerPos = transform.position; //Vector3型のplayerPosに現在の位置情報を格納
playerPos.y += speed * Time.deltaTime; //y座標にspeedを加算
transform.position = playerPos; //現在の位置情報に反映させる

こちらのコードが少しややこしいですね。

下記のように書くことが出来そうですが、これは出来ません。

transform.position += speed * Time.deltaTime;

C#ではtranform.position.x(or y , or z)の値をそのまま変更することはできません。

*詳しく説明すると『プロパティが構造体の時はそのメンバーの値は変更できない』という仕組みなわけですが、とりあえず transform.position.x は変更できないと覚えておけばOKです。

変更するためには一度他のVector3型の変数(今回はplayerPos)に transform.position を格納して、その値を変更、そしてまた元の transform.position に格納するという手順を行わなければなりません。

そのため、面倒ですが先ほど記述したように一度 playerPos に格納してから、y座標を変更しています。

else ifの処理は下(↓)キーを押している時に実行されるようにするため逆にしているだけです。

Time.deltaTime というのは1フレームにかかった時間を表しているのですが、簡単に解説すると『実際にこのゲームをするパソコンの性能によって、移動スピードが変わらないようにするためのおまじない』みたいな感じです。

なので、移動系の処理を書く時はとりあえず speed に Time.deltaTime を掛けてあげるようにしましょう。

 

今作った「PlayerControllerスクリプト」をPlayerにアタッチして、再生してみましょう。

上下キーを押した時にそれぞれに対応した方向へ動くはずです。

移動範囲の制限

先ほどのコードだけだと、移動範囲の制限処理を書いていないのでどこまでも上か下にいってしまいますね。

そこでまずは下記の変数を追加します。

[SerializeField] private float maxY, minY; //移動範囲の制限

[SerializeField] private を public にしても大丈夫ですし、

[SerializeField] private float maxY; 
[SerializeField] private float minY,

と別々に分けても大丈夫です。

    void MovePlayer()
    {
        //もし上矢印キーが押されたら
        if (Input.GetAxisRaw("Vertical") > 0)
        {
            Vector3 playerPos = transform.position; //Vector3型のplayerPosに現在の位置情報を格納
            playerPos.y += speed * Time.deltaTime; //y座標にspeedを加算

            //追加
            //もしplayerPosのY座標がmaxY(最大Y座標)より大きくなったら
            if(maxY < playerPos.y)
            {
                playerPos.y = maxY; //PlayerPosのY座標にmaxYを代入
            }
            transform.position = playerPos; //現在の位置情報に反映させる

        } else if(Input.GetAxisRaw("Vertical") < 0) //もし下矢印キーが押されたら
        {
            Vector3 playerPos = transform.position;
            playerPos.y -= speed * Time.deltaTime;

            //追加
            if (minY > playerPos.y)
            {
                playerPos.y = minY;
            }
            transform.position = playerPos;
        }
    }

あとは上記のように MovePlayer() の中に新たにif文を追加してください。

if(maxY < playerPos.y)

このif文のもう一つ上の処理で playerPos.y にspeedを掛けているので、その値が maxY よりも大きい時はif文内の処理 playerPos.y = maxY;  が実行されます。

そして、その後の transform.position = playerPos が実行されることで、maxY 以上にキャラクターが移動することを防ぎます。

同じメソッド内の処理は上から順番に実行されるため処理の順番を入れ替えてしまうと処理の結果が変わってしまう可能性があります。

あとは今のスクリプトをキャラクターにアタッチして、インスペクター上から変数の値を自分好みに変えてあげてください。下記のようにすればちょうどいいと思います。

あとは再生してあげればきちんと範囲内で動くようになっているはずです。

さて、次回は弾を発射できるようにしていきますので、お楽しみに(*・ω・)ノ