Unityでゲームを作ろう:第3回「オブジェクトを動かすスクリプトを書こう」

Unity

こんにちは、トナカイです。

ゲームを作ろうシリーズ第3回です。

前回はフィールドに当たり判定を付ける所まで進めました。

第3回では、キャラクターを操作できるようにUnityでスクリプトを書いていきます。

この記事を読むと、以下のことが分かるようになります。

  • キーボードでキャラクターを動かすスクリプトの書き方
  • プレイヤーへの当たり判定の付け方

過去記事はこちら

1.プレイヤーのインポート

今回作るゲームでは、プレイヤーを操作してフィールドを歩けるようにします。

使うのは「Blenderでのアニメーションの作り方【Blender4.0】」で作成したデータです。

説明のために過去の記事で作成したモデルを使っていますが、お持ちでない場合もあると思います。

その時は「ユニティちゃん」など、アニメーション付きの配布モデルをお使いいただけると良いのではと思います。

UnityのProjectにインポートしたプレイヤーのオブジェクトをSceneにドラッグします。

大きすぎたので、Hierarchyのプレイヤーオブジェクトを選択してScaleを小さくしました。

2.スクリプトを書く

次に、プレイヤーを動かすスクリプトを書きます。

Unityでは、Projectにあるプラスマークからスクリプトを追加することができます。

プラスマークをクリックすると以下の画面が表示されるので、「C# Script」を選択してください。

追加されたスクリプトを選択すると、自動的にエディターが開かれます(Visual Studioを使っています)。

ここに、プレイヤーを動かすコードを書いていきます。

まずは、右矢印キーを押しているときにプレイヤーが右に動くようにします。

ただ右に動かすだけでは、正面を向いたまま右に移動することになってしまうので、移動と同時に右を向く処理もつけます。

とりあえず、こんなスクリプトを書いてみてください。赤枠が追加したコードです。詳細の説明はこの後します。

コードの意味

やったことは

  • プレイヤーの移動速度の設定
  • 矢印キーを押している間だけ移動するようにする
  • プレイヤーの向きが移動方向と同じになるように回転させる

の3つです。

プレイヤーの移動速度の設定

「int speed = 3;」で移動速度を設定しました。フィールドの大きさによって適切な速さは変わるので、いい感じになるように調整してください。

右矢印キーを押している間だけ移動するようにする

矢印キーを押している間だけ移動するようにする処理は、以下のコードが対応しています。

if(Input.GetKey("right") == true)

{

    transform.position += new Vector3(0, 0, speed * Time.deltaTime);

    transform.rotation = Quaternion.Euler(0,0,0);

}

「〇〇している間だけ動かす」という、ある条件が満たされている時だけ行う処理のため、if文を使いました。

if文とは

条件を満たしたときに、どんな処理をするか書くために使うコードです。

以下のような書き方をします。

if(条件){条件を満たしたら実行する処理};

Input.GetKey」は、キーが押されているかどうかを判断するコードです。

Input.GetKey(“right”)であれば、右矢印キーが押されている時にtrueの値を返します。

かっこの中に入れる文字によって、どのキーにするか選べます。

right右矢印キー
left左矢印キー
up上矢印キー
down下矢印キー

また、「==」は左と右の値が同じということを意味します。

そのため、if(Input.GetKey(“right”) == true)の意味は

「右矢印キーが押されている(true)ときは、かっこ内の処理を頑張るぞー!」

みたいな感じになります。

Input.GetKey(“right”)がtrueのときに頑張ってもらう処理が、

transform.position += new Vector3(0, 0, speed * Time.deltaTime);

transform.rotation = Quaternion.Euler(0, 0, 0);

になります。

「transform」「Time.deltaTime」「Vector3」「Quaternion.Euler」のそれぞれについて解説します。

※スクリプト中に出てくる「new」の意味は理解しきれず、ここには書けませんでした。分かり次第記事にしようと思います。

未来のトナカイへ。分かったら書いてね。お願いね。

transform

transformは、オブジェクトの位置や回転などの情報を扱えます。

参考:Transform – Unity スクリプトリファレンス (unity3d.com)

transform.positionの場合は位置を、transform.rotationの場合は回転についての情報を持っていることになります。

Time.deltaTime

Time.deltaTimeは、「直前のフレームから現在のフレームになるまでの経過時間(秒)」を表します。

参考:Time-deltaTime – Unity スクリプトリファレンス (unity3d.com)

※Unityにおけるフレームの意味については、こちらの記事が参考になります。トナカイが書いたものではありませんが、映画のフレームという馴染みやすいものから説明されており、分かりやすいです。

Vector3

オブジェクトの位置関係を表す時に使います。

Vector3(X座標, Y座標, Z座標)となっています。

ひとまずZ座標の方向(画面の右方向)に動かすため、Z座標の引数にのみ「speed * Time.deltaTime」を入れました。

以上をまとめると、

transform.position += new Vector3(0, 0, speed * Time.deltaTime);

では

「プレイヤーのオブジェクトの現在の位置に、プレイヤーの移動距離を足す」

という処理を行っているということになります。

Quaternion.Euler

Quaternion.Eulerで、プレイヤーの向きを指定しています。

Quaternion.Euler(X軸の回転, Y軸の回転, Z軸の回転)になります。

Unityの座標軸を見てみると、Y軸で回転することがわかります。

回転の方向については、右方向が0度に対応していたため、Quaternion.Euler(0, 0, 0)としました。

結果として

transform.rotation = Quaternion.Euler(0, 0, 0);

では、

「オブジェクト(キャラクター)の向きにXYZ軸0度の回転を代入する」

という処理を行うことになります。

スクリプトを実行しよう!

ここまでできたら、Hierarchyにあるスクリプトを、Projectにあるプレイヤーオブジェクトにドラッグしてアタッチしてください。

この状態で再生し、右矢印キーを押すと動画のような動きをします。

なお、プレイヤーが壁をすり抜けてしまうのはRigidbodyとコライダーがついていないためです。この後の「3.プレイヤーに当たり判定を付ける」ですり抜けないように設定します。

右矢印だけではなく、他の矢印キーを押したときにも動くように、コードを追加しました。コードはこれで完成です。

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

public class PlayerController : MonoBehaviour
{
    int speed = 3;
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        if(Input.GetKey("right") == true)
        {
            transform.position += new Vector3(0, 0, speed * Time.deltaTime);
            transform.rotation = Quaternion.Euler(0, 0, 0);
        }
        if (Input.GetKey("left") == true)
        {
            transform.position -= new Vector3(0, 0, speed * Time.deltaTime);
            transform.rotation = Quaternion.Euler(0 , 180, 0);
        }
        if (Input.GetKey("up") == true)
        {
            transform.position -= new Vector3(speed * Time.deltaTime, 0, 0);
            transform.rotation = Quaternion.Euler(0, 270, 0);
        }
        if (Input.GetKey("down") == true)
        {
            transform.position += new Vector3(speed * Time.deltaTime, 0, 0);
            transform.rotation = Quaternion.Euler(0, 90, 0);
        }
    }
}

3.プレイヤーに当たり判定を付ける

このままだとプレイヤーが壁をすり抜けてしまいます。当たり判定を付けるために、プレイヤーオブジェクトのコンポネントにRigidbodyとコライダーを追加します。

Rigidbodyの追加方法

プレイヤーオブジェクトのInspectorにある「Add Component」から「Physics」へと進み、Rigidbodyを選択すれば完了です。

コライダーの追加方法

「コライダーってなんだろう?」という場合は、前回の記事「ゲームを作ろう:第2回「当たり判定の付け方とコライダーの確認方法」」をご覧ください。

ゲームのフィールドにはメッシュコライダーを使いましたが、Unityマニュアルによれば「メッシュコライダーは処理が重くなりやすいので使うのは控えめにしてね!」とのことです。

参考:Mesh Collider – Unity マニュアル (unity3d.com)

プレイヤーのオブジェクトは複雑な形をしていないので、別のコライダーを使おうと思います。

Box Colliderを使うことにしました。

前回同様、「Add Component」からBox Colliderを選択します。

コライダーを追加しただけではプレイヤーと当たり判定の大きさが合わないため、大きさを調節します。

InspectorにあるEdit Colliderの横にあるマークをクリックすると、コライダーの大きさを編集できるようになります。

前や横から見て、プレイヤーの大きさと合うようにしました。

まとめ

ここまで進めると、以下の動画の通りになります。

今回は、プレイヤーをキーボードで動かせるようにコードを書きました。

次回は、歩行モーションの追加と、カメラがキャラクターを追いかける仕組みを実装します。