見出し画像

【Unity 初心者向け】オブジェクトの移動② | キー入力で自由にオブジェクトを動かす方法

前回は、transform.position の値を変更するとオブジェクトが移動することを確認しました。

たとえば、次のように書くと、オブジェクトは右方向へ動き続けます。

transform.position += Vector3.right * speed * Time.deltaTime;

ただし、このままではゲームを開始した瞬間から勝手に動いてしまいます。
ゲームでは、

  • 右キーを押したら右へ移動する

  • 左キーを押したら左へ移動する

  • 上キーを押したら上へ移動する

  • 下キーを押したら下へ移動する

というように、プレイヤーの入力に応じて移動する方向を変えることがよくあります。

今回は、キー入力を使ってオブジェクトを上下左右に動かしてみましょう。
後半では、4方向の処理をまとめて、より扱いやすい移動方法に発展させます。


1.今回作るもの

今回は、キーボードの矢印キーを使ってオブジェクトを上下左右に移動させます。

最初は、

Input.GetKey()

を使って、キーが押されているかを1つずつ確認します。
さらに

Input.GetAxisRaw()

を使って「どの方向へ移動したいのか」を数値として取得する方法を確認します。

最終的には、次のようなコードになります。

float x = Input.GetAxisRaw("Horizontal");
float y = Input.GetAxisRaw("Vertical");

Vector3 direction = new Vector3(x, y, 0).normalized;

transform.position += direction * speed * Time.deltaTime;

少し難しそうに見えますが、順番に確認すれば、それぞれが何をしているのか分かるようになります。


2.キー入力移動のプログラム

2-1.右キーを押したときだけ移動する

まずは簡単なところから始めましょう。

前回作成したスクリプトを使って、右矢印キーを押している間だけ右へ移動するようにします。

using UnityEngine;

public class ObjectMove : MonoBehaviour
{
    public float speed = 3f;

    void Update()
    {
        if (Input.GetKey(KeyCode.RightArrow))
        {
            transform.position += Vector3.right * speed * Time.deltaTime;
        }
    }
}

ゲームを実行して、キーボードの右矢印キーを押してみましょう。
キーを押している間だけ、オブジェクトが右へ移動します。


2-2.Input.GetKeyとは

今回登場したのが、以下のコード

Input.GetKey()

Input.GetKey()は、指定したキーが現在押されているか、を調べる命令です。
今回は、

Input.GetKey(KeyCode.RightArrow)

としています。

KeyCode.RightArrowは、キーボードの右矢印キーを表しています。
右矢印キーが押されていれば true、押されていなければ false になります。
そのため、

if (Input.GetKey(KeyCode.RightArrow))

では、右矢印キーが押されているときだけ if の中の処理を実行する、という意味になります。

Input.GetKey()で重要なのは、キーを押している間、何度もtrueになる、という点です。
Update()はゲーム中、繰り返し実行されています。
そのため、

if (Input.GetKey(KeyCode.RightArrow))
{
    transform.position += Vector3.right * speed * Time.deltaTime;
}

とすると、右キーを押している間、

少し右へ移動
↓
少し右へ移動
↓
少し右へ移動
↓
少し右へ移動

という処理が繰り返されます。
結果として、オブジェクトが滑らかに右へ動きます。


2-3.Vector3.rightとは

前回は、

new Vector3(1, 0, 0)

のように、X・Y・Zを指定して移動方向を作りました。

Unityには、よく使う方向が最初から用意されています。

今回登場した

Vector3.right

は右方向を表すコードで、

new Vector3(1, 0, 0)

と同じ方向を表します。
X成分がプラスの値なので、右方向になります。


2-4.その他の方向も用意されている

Unityには、右方向だけでなく、ほかの方向も用意されています。

右方向は上で確認した通り

Vector3.right

new Vector3(1, 0, 0)

左方向は

Vector3.left

new Vector3(-1, 0, 0)

UnityEditorのバージョンによっては、Vector3.left が使えない場合があります。
その時は以下のように指定します。

-Vector3.right


上方向は

Vector3.up

new Vector3(0, 1, 0)

下方向は

Vector3.down

new Vector3(0, 1, 0)

前方向は

Vector3.forward

new Vector3(0, 0, 1)

後方向は

Vector3.back

new Vector3(0, 0, -1)

このように、よく使う方向はVector3にあらかじめ用意されています。


2-5.左右に動かしてみる

それでは、左矢印キーも追加してみましょう。

void Update()
{
    if (Input.GetKey(KeyCode.RightArrow))
    {
        transform.position += Vector3.right * speed * Time.deltaTime;
    }

    if (Input.GetKey(KeyCode.LeftArrow))
    {
        transform.position += Vector3.left * speed * Time.deltaTime;
    }
}

これで、

  • 右矢印キー → 右へ移動

  • 左矢印キー → 左へ移動

となります。


2-6.上下の移動も追加する

さらに、上と下も追加します。

void Update()
{
    if (Input.GetKey(KeyCode.RightArrow))
    {
        transform.position += Vector3.right * speed * Time.deltaTime;
    }

    if (Input.GetKey(KeyCode.LeftArrow))
    {
        transform.position += Vector3.left * speed * Time.deltaTime;
    }

    if (Input.GetKey(KeyCode.UpArrow))
    {
        transform.position += Vector3.up * speed * Time.deltaTime;
    }

    if (Input.GetKey(KeyCode.DownArrow))
    {
        transform.position += Vector3.down * speed * Time.deltaTime;
    }
}

これで矢印キーを使って、オブジェクトを上下左右へ自由に動かせるようになりました。

現在の処理を日本語で考えると、次のようになります。

右キーが押されていたら
    右へ移動

左キーが押されていたら
    左へ移動

上キーが押されていたら
    上へ移動

下キーが押されていたら
    下へ移動

非常に分かりやすい書き方です。
キー入力の仕組みを勉強するときは、まずこの方法で動きを確認すると理解しやすいでしょう。

ただし、少し気になるところもあります。
方向が増えるたびに、

if (...)
{
    transform.position += ...
}

という処理を追加しなければなりません。
そこで次は、入力された方向を最初にまとめて作る方法 を考えてみましょう。


3.移動方向の数値化

3-1.「どちらへ動きたいか」を数値で取得

左右の入力を、数値で表してみます。
右へ移動したい場合は、

X = 1

左へ移動したい場合は、

X = -1

どちらも押していない場合は、

X = 0

と考えることができます。

同じように上下も、

上 → Y = 1
下 → Y = -1
入力なし → Y = 0

と考えられます。

つまり、プレイヤーの入力から、

X方向の値
Y方向の値

を取得できれば、

new Vector3(x, y, 0)

として移動方向を作ることができます。

ここで使えるのが、

Input.GetAxisRaw()

です。
ゲット・アクシス・ロウ と読みます。


3-2.Input.GetAxisRaw("Horizontal")

まず、次のコードを書いてみましょう。

float x = Input.GetAxisRaw("Horizontal");

Horizontalは、横方向の入力を取得するために使います。
基本的には、

右 →  1
左 → -1
入力なし → 0

という値を取得できます。
そのため、

float x = Input.GetAxisRaw("Horizontal");

とすると、横方向への入力を x という変数に保存できます。


3-3.Input.GetAxisRaw("Vertical")

上下方向は、

float y = Input.GetAxisRaw("Vertical");

で取得できます。

基本的には、

上 →  1
下 → -1
入力なし → 0

となります。

これで、

float x = Input.GetAxisRaw("Horizontal");
float y = Input.GetAxisRaw("Vertical");

とすることで、横方向と縦方向の入力をそれぞれ取得できます。

補足
Input.GetAxis()という似た命令もあります。
GetAxisRaw()は入力値がすぐに-1・0・1へ切り替わりますが、GetAxis()は値が徐々に変化します。
今回は移動方向を分かりやすく確認するため、GetAxisRaw()を使用します。


3-4.入力からVector3を作る

取得した x と y を使って、移動方向を作ります。

Vector3 direction = new Vector3(x, y, 0);

たとえば右キーを押している場合、

x = 1
y = 0

なので、

new Vector3(1, 0, 0)

になります。
これは右方向です。

上キーを押していれば、

x = 0
y = 1

なので、

new Vector3(0, 1, 0)

になります。
これは上方向です。


この方法の便利なところは、2つのキーを同時に押した場合です。

たとえば、右キーと上キーを同時に押すと、

x = 1
y = 1

となります。
そのため、

new Vector3(1, 1, 0)

という方向ができます。
これは右上方向です。

同じように、2つのキーを同時に押したときは次のようになります。

左 + 上 → (-1, 1, 0)

右 + 下 → (1, -1, 0)

左 + 下 → (-1, -1, 0)

つまり、入力値からVector3を作るだけで、斜め方向も自然に扱うことができます。


4.数値化した値を使った移動

4-1.作った方向へ移動する

数値化した方向を、前回と同じようにtransform.positionへ追加します。

float x = Input.GetAxisRaw("Horizontal");
float y = Input.GetAxisRaw("Vertical");

Vector3 direction = new Vector3(x, y, 0);

transform.position += direction * speed * Time.deltaTime;

これだけで、上下左右と斜め方向へ移動できます。
かなりコードがすっきりしました。


4-2.斜め移動の問題

ここで実際に動かしてみると、1つ問題があります。
右だけを押した場合は、

new Vector3(1, 0, 0)

ところが、右と上を同時に押すと、以下のようになります。

new Vector3(1, 1, 0)

この2つは、方向だけでなく ベクトルの長さ も違います。
(1, 1, 0) のほうが長いため、そのまま移動に使うと、斜めに移動したときのほうが速くなってしまいます。


4-3.normalizedで方向の長さをそろえる

そこで使うのが、.normalized です。

次のようにします。

Vector3 direction = new Vector3(x, y, 0).normalized;

normalizedを使うと、方向はそのままでVector3の長さを1にそろえる ことができます。

たとえば、

new Vector3(1, 0, 0)

は長さ1です。
一方、

new Vector3(1, 1, 0)

は、そのままでは長さが1より大きくなります。
.normalized を使うことで、斜め方向も 長さ 1 にそろえることができます。

その結果、上下左右でも斜めでも、ほぼ同じ速度で移動できるようになります。


5.完成コード

今回の最終的なコードはこちらです。

using UnityEngine;

public class ObjectMove : MonoBehaviour
{
    public float speed = 3f;

    void Update()
    {
        float x = Input.GetAxisRaw("Horizontal");
        float y = Input.GetAxisRaw("Vertical");

        Vector3 direction = new Vector3(x, y, 0).normalized;

        transform.position += direction * speed * Time.deltaTime;
    }
}

最初に作った4つの if と比べると、かなり短くなりました。


5-1.コードを順番に読んでみる

今回のコードで特に重要なのは、処理を3段階に分けて考えることです。
まず、

float x = Input.GetAxisRaw("Horizontal");
float y = Input.GetAxisRaw("Vertical");

で、プレイヤーがどのキーを押しているかを数値として取得します。

次に、

Vector3 direction = new Vector3(x, y, 0).normalized;

で、取得した入力から移動する方向を作ります。

最後に、

transform.position += direction * speed * Time.deltaTime; 

で、作った方向へ実際にオブジェクトを移動します。

つまり、

キー入力
↓
移動方向を作る
↓
その方向へ移動する

という流れになっています。

この考え方は、これからプレイヤーを操作するスクリプトを作るときにとても重要になります。


5-2.GetKeyを使う方法との違い

最初に作ったコードでは、

if (Input.GetKey(KeyCode.RightArrow))
{
    transform.position += Vector3.right * speed * Time.deltaTime;
}

のように、キーごとに移動処理を書いていました。

一方、GetAxisRawを使った方法では、

float x = Input.GetAxisRaw("Horizontal");
float y = Input.GetAxisRaw("Vertical");

Vector3 direction = new Vector3(x, y, 0).normalized;

として、最初に移動方向を1つ作っています。

そして最後に、

transform.position += direction * speed * Time.deltaTime;

と、移動処理を1回だけ行っています。

Unityにまだ慣れないうちは、まずGetKeyを使って「キーが押されていたら、その方向へ動かす」という仕組みを理解することが大切です。

そこから「入力から移動方向を作る」という考え方へ発展させると、コードの意味を理解しやすくなります。


21.今回のまとめ

今回は、キーボードの入力を使ってオブジェクトを自由に動かす方法を確認しました。

次回は、transform.positionへ直接座標を追加する方法とは少し違う、Transform.Translate を使った別の移動方法について確認していきます。


こちらはUnity初心者向けの記事をテーマ別にまとめています。
▼ Unity初心者向け記事まとめはこちら


こちらのマガジン「ミニゲーム作成講座 全8回セット」でもシーンの切り替えなどを活用して、初心者でも知識ゼロから作れるミニゲーム作成講座を紹介しています。

さらにステップアップの「スマホで遊ぶジャンプゲーム 8回セット」のマガジンもぜひご活用ください。


ファイブボックスでは、スクラッチやUnityの個別指導のオンラインレッスンを行っています。
ご興味のある方は当サイト、オンラインレッスンから、無料体験授業へお問い合わせ下さい。

いいなと思ったら応援しよう!

ファイブボックス よろしければ応援お願いします! いただいたチップはクリエイターとしての活動費に使わせていただきます!