Skip to content

第3回 自機を動かす ​

この回でつくるもの:初めてのスクリプト「PlayerController」を書いて、キーボードの WASD や矢印キー、ゲームパッドで自機を上下左右に動かせるようにします。

この回で学ぶこと ​

  • スクリプト(C#)ファイルの作り方と、ゲームオブジェクトへの付け方
  • Start と Update のちがい、Debug.Log で Console に文字を出す方法
  • Input System の Move アクションで入力を受け取る方法
  • 変数、Vector2 と Vector3、Time.deltaTime の意味
  • public 変数を Inspector で変える方法

前回までのふりかえり ​

第2回では、空のオブジェクト Player の下に Bank > Model(宇宙船のモデル)と Muzzle(弾が出る場所)を作り、右を向いた自機を画面の左側(x = -6)に置きました。 まだ自機は動きません。

1. スクリプトを作る ​

1-1. スクリプトとは ​

スクリプト(Script)は、ゲームオブジェクトに「どう動くか」を教えるプログラムです。 Unity では C#(シーシャープ)という言葉で書きます。 スクリプトもコンポーネントの1つで、ゲームオブジェクトに付けると動き出します。

1-2. PlayerController を作る ​

  1. Project ウィンドウで Assets/_Game/Scripts を開きます。
  2. 右側の何もないところで右クリックし、Create > Scripting > MonoBehaviour Script を選びます。
  3. ファイルができて、名前を入力できる状態になります。すぐに PlayerController と入力して Enter キーを押します。

よくあるまちがい

ファイル名とクラス名は必ず同じ にします。ファイル名は、スクリプトの中の public class PlayerController の PlayerController の部分と一致していないといけません。 名前を入れる前に Enter を押してしまったり、あとからファイル名だけ変えたりすると、ずれてしまいます。まちがえたときは、ファイルを消して作りなおすのがいちばん簡単です。 大文字・小文字も区別されます。playercontroller や Playercontroller ではダメです。

2. コードを書くエディタの設定 ​

2-1. コードエディタとは ​

スクリプトは、コードエディタ というアプリで書きます。次のどれかを使います。

エディタ特ちょう
Visual Studio Code(VS Code)軽くて、Windows でも Mac でも使える
Visual StudioWindows 向け。Unity のインストール時にいっしょに入れられる
Rider高機能。学生は無料で使えることがある

どれを使うかは、先生の指示にしたがってください。

2-2. Unity にエディタを教える ​

  1. Windows はメニューの Edit > Preferences、Mac はメニューの Unity > Settings を選びます。
  2. 開いたウィンドウの左側で External Tools を選びます。
  3. External Script Editor の欄を押して、使うエディタ(例: Visual Studio Code、Visual Studio Community 2022)を選びます。
  4. ウィンドウを閉じます。

ヒント

一覧に使いたいエディタが出てこないときは、Browse... を選んで、エディタのアプリを直接選びます。 VS Code を使う場合は、VS Code の拡張機能(Extensions)で Unity(Microsoft 製)を入れておくと、入力の候補が出て便利です。

先生へ

VS Code を使う場合、Unity 側は Window > Package Manager で Visual Studio Editor パッケージが入っていることを確認してください(Unity 6 のテンプレートには通常入っています)。VS Code 側は Unity 拡張機能(C# Dev Kit が一緒に入ります)を推奨します。

2-3. スクリプトを開く ​

  1. Project ウィンドウの Assets/_Game/Scripts にある PlayerController をダブルクリックします。
  2. コードエディタが開いて、次のようなコードが表示されます。
csharp
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    // Start is called once before the first execution of Update after the MonoBehaviour is created
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

これが、Unity が最初に用意してくれる「ひな形」です。

3. Start と Update ​

3-1. Start と Update のちがい ​

名前いつ動く?
Startゲームが始まったとき(そのオブジェクトが動き始めたとき)に 1回だけ
Updateゲーム中、毎フレーム(1秒に何十回も)くり返し

ゲームの画面は、パラパラまんがのように1枚ずつ絵をかきかえて動いています。この1枚を フレーム とよびます。 { と } の間に、やってほしいことを書きます。

3-2. Debug.Log を書いてみる ​

Debug.Log("文字") と書くと、Console に文字が出ます。プログラムが動いているか確かめるのに使います。

  1. コードエディタで、PlayerController を次のように書きかえます。
csharp
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    void Start()
    {
        Debug.Log("ゲームスタート!");   // ★追加
    }

    void Update()
    {
        Debug.Log("Update が動いた");     // ★追加
    }
}
  1. Ctrl+S(Macは Cmd+S)でファイルを保存します。
  2. Unity に戻ります。右下でくるくる回るマークが消えるまで待ちます。(Unity がスクリプトを読み込んでいます)

注意

  • 文の最後には、必ず ;(セミコロン)を付けます。
  • " や ;、( ) は 半角 で入力します。日本語入力をオフにしてから打ちましょう。(" の中の文字は日本語でもOK)
  • // から右は コメント(メモ)です。プログラムとしては無視されるので、日本語で説明を書いておけます。

3-3. スクリプトを Player に付ける ​

  1. Unity の Hierarchy で Player を選びます。
  2. Project ウィンドウの PlayerController を、Inspector のいちばん下の何もないところにドラッグして離します。
  3. Inspector に Player Controller (Script) というコンポーネントが追加されたことを確認します。

ヒント

Inspector の Add Component ボタンを押して、PlayerController と入力して選んでも付けられます。

3-4. 動作確認(Debug.Log) ​

  1. Project ウィンドウのとなりの Console タブを押して、Console を表示します。
  2. ▶ ボタンを押します。
  3. Console に「ゲームスタート!」が1回、「Update が動いた」がどんどん出てくればOK。
  4. もう一度 ▶ ボタンを押して止めます。

Start は1回、Update は何回も動いていることがわかりますね。

ヒント

Console の上にある Clear を押すと、出ているメッセージを消せます。Collapse を押すと、同じメッセージを1行にまとめて、右に回数を表示してくれます。

4. Move アクションを見てみる ​

4-1. Input System とは ​

Input System(インプット・システム)は、キーボードやゲームパッドの入力を受け取るしくみです。 「右へ動く」「撃つ」のような アクション(Action)を作っておき、そこにキーやボタンを結びつけます。 こうすると、プログラムでは「どのキーか」を気にせず、「Move の入力はどれくらい?」とだけ聞けば済みます。

テンプレートには、最初から InputSystem_Actions というファイルが入っていて、プロジェクト全体で使えるように設定されています。

4-2. InputSystem_Actions を開く ​

  1. Project ウィンドウの左側で Assets を選びます。
  2. 右側にある InputSystem_Actions をダブルクリックします。
  3. Input Actions のエディタ(アクションを編集するウィンドウ)が開きます。

4-3. Move を確認する ​

  1. いちばん左の Action Maps の列で Player が選ばれていることを確認します。
  2. 真ん中の Actions の列に Move、Look、Attack、Jump などが並んでいます。
  3. Move の左の ▶ を押して開きます。
  4. Left Stick [Gamepad](ゲームパッドの左スティック)や、WASD のようなセットがあることを確認します。
  5. WASD の ▶ を開くと、Up、Down、Left、Right に、W・A・S・D や矢印キーが結びつけられていることがわかります。
  6. 何も変えずに、ウィンドウを閉じます。

ヒント

Move を選ぶと、右側に Action Type が Value、Control Type が Vector2 と出ています。Vector2 は「x と y の2つの数」のことです。Move は「左右(x)と上下(y)がどれくらい押されているか」を教えてくれます。

注意

この回では InputSystem_Actions は 何も変えません。もしうっかり変えて「保存しますか?」と聞かれたら、保存しないで閉じましょう。

4-4. Move の値 ​

Move の値は、押したキーによって次のようになります。

押したキーxy
何も押さない00
→ または D10
← または A-10
↑ または W01
↓ または S0-1

ゲームパッドのスティックなら、少しだけたおすと 0.3 のような途中の値になります。

5. 自機を動かすコードを書く ​

5-1. コードを書く ​

  1. Project ウィンドウの PlayerController をダブルクリックして、コードエディタで開きます。
  2. 中身を 全部消して、次のコードに書きかえます。
csharp
using UnityEngine;
using UnityEngine.InputSystem;

// 自機を動かすスクリプト
public class PlayerController : MonoBehaviour
{
    public float speed = 6f;          // 移動の速さ

    InputAction moveAction;

    void Start()
    {
        moveAction = InputSystem.actions.FindAction("Move");
    }

    void Update()
    {
        // 入力を読む(左右が x、上下が y。-1 から 1 の値)
        Vector2 input = moveAction.ReadValue<Vector2>();

        // 動かす
        Vector3 move = new Vector3(input.x, input.y, 0f);
        transform.position += move * speed * Time.deltaTime;
    }
}
  1. Ctrl+S(Macは Cmd+S)でファイルを保存します。
  2. Unity に戻り、読み込みが終わるまで待ちます。
  3. Console に赤いエラーが出ていないか確認します。

5-2. コードの解説 ​

変数(へんすう)は、数や物を入れておく「名前つきの箱」です。

行意味
using UnityEngine.InputSystem;Input System の機能を使います、という宣言
public float speed = 6f;speed という名前の箱に、小数 6 を入れる。float は小数を入れる箱の種類。f は「小数だよ」という印
InputAction moveAction;Move アクションを入れておく箱
InputSystem.actions.FindAction("Move")プロジェクトのアクションの中から Move を探してくる
moveAction.ReadValue<Vector2>()今の Move の値(x と y)を読む
new Vector3(input.x, input.y, 0f)x と y と z の3つの数のセットを作る。z は 0(Z = 0 のルール)
transform.position += ...自分の位置に、動く分を足す

Vector2 と Vector3

名前中身使い道
Vector2x, y の2つの数入力(左右・上下)
Vector3x, y, z の3つの数3D の世界での位置や動き

入力は2つの数(Vector2)ですが、自機の位置は3D の世界なので3つの数(Vector3)が必要です。だから z に 0f を足して Vector3 に作りなおしています。

Time.deltaTime とは

Time.deltaTime は「前のフレームから何秒たったか」です。(1秒に60回 Update が動くなら、約 0.017 秒)

  • パソコンが速いと、Update は1秒にたくさん動きます。
  • パソコンが遅いと、Update は1秒に少ししか動きません。

speed * Time.deltaTime のように掛けると、どんなパソコンでも 「1秒に speed だけ進む」 ようになります。speed が 6 なら、1秒に 6 進みます。

ヒント

move * speed * Time.deltaTime は「向き × 速さ × 時間 = 進む距離」です。理科で習う「速さ × 時間 = 道のり」と同じ考え方です。

5-3. 動作確認 ​

  1. Ctrl+S(Macは Cmd+S)でシーンを保存します。
  2. ▶ ボタンを押します。
  3. Game ビューを1回クリックします。(キー入力が Game ビューに届くようにするため)
  4. W A S D キーや 矢印キー を押して、自機が上下左右に動けばOK。
  5. ゲームパッドを持っている人は、左スティックでも動くか試します。
  6. もう一度 ▶ ボタンを押して止めます。

先生へ

この時点では画面の外まで動けてしまいます。第4回でこの問題を直すので、生徒が気づいたら「次回直します」と伝えてください。

6. Inspector で speed を変える ​

6-1. public 変数は Inspector に出る ​

public を付けた変数は、Inspector に表示されて、そこから値を変えられます。

  1. Hierarchy で Player を選びます。
  2. Inspector の Player Controller (Script) を見ます。Speed という欄に 6 が入っています。
  3. Speed を 10 に変えます。
  4. ▶ ボタンを押して動かしてみます。さっきより速く動きます。
  5. ▶ ボタンを押して止めます。
  6. 好きな速さが決まったら、その値にしておきます。(迷ったら 6)

ヒント

コードでは speed(小文字)ですが、Inspector では Speed(先頭が大文字)と表示されます。Unity が読みやすく表示してくれているだけで、同じものです。

注意

Inspector の値と、コードの = 6f の値がちがうときは、Inspector の値が使われます。コードの数字を変えても速さが変わらないときは、Inspector の値を確認しましょう。

6-2. プレイ中の変更は元に戻る ​

  1. ▶ ボタンを押して、プレイを始めます。
  2. プレイ中に、Inspector の Speed を 20 に変えます。すぐに速くなります。
  3. ▶ ボタンを押して止めます。
  4. Speed を見ると、プレイ前の値に 戻っています。

プレイ中は「ためしに変えてみる」のに便利ですが、止めると元に戻ります。 いい値が見つかったら、数字をメモしておいて、止めてから入れなおしましょう。

よくあるまちがい

プレイ中だと気づかずに、たくさん設定を変えてしまい、止めたら全部消えた…というのはよくある失敗です。▶ ボタンが青く光っているときはプレイ中です。

6-3. 保存する ​

  1. Ctrl+S(Macは Cmd+S)でシーンを保存します。

チャレンジ課題 ​

  • Start に Debug.Log("速さは " + speed); と書くと、Console に今の速さが出ます。試してみましょう。(試したら消してOK)
  • new Vector3(input.x, input.y, 0f) を new Vector3(input.x, 0f, 0f) にすると、どうなるでしょう? 試したら元に戻します。
  • Time.deltaTime を消すとどうなるか、予想してから試してみましょう。(すごく速くなります。試したら元に戻します)

つまずきポイント ​

こんなときはここを確認
スクリプトを付けようとすると「クラスが見つからない」と出るファイル名とクラス名(public class の後ろ)が同じか。Console に赤いエラーがないか
Console に赤いエラーが出る; の付けわすれ、{ } の数、全角の文字がまざっていないか。エラーをダブルクリックするとまちがいの行が開く
キーを押しても動かないGame ビューを1回クリックしたか。Player に PlayerController が付いているか。Speed が 0 になっていないか
NullReferenceException というエラーが出るFindAction("Move") の Move のつづりが合っているか。Edit > Project Settings > Input System Package で Project-wide Actions に InputSystem_Actions が入っているか
コードを変えたのに動きが変わらないコードエディタで保存したか。Inspector の値が優先されていないか

まとめ ​

  • Create > Scripting > MonoBehaviour Script でスクリプトを作り、ゲームオブジェクトに付けると動きます。ファイル名とクラス名は同じにします。
  • Start は最初に1回、Update は毎フレーム動きます。
  • InputSystem.actions.FindAction("Move") で入力を受け取り、speed * Time.deltaTime を掛けて動かします。
  • public 変数は Inspector で変えられます。プレイ中の変更は止めると元に戻ります。