UnityのInputで入力を扱う


同じ内容を解説した勉強会の動画

概要

キーボードやマウス、ゲームパッドなどから自在に入力を受け取るInputクラスを使ってみる。

Inputとは

Inputはさまざまな入力を取得することができるクラス。またInput Managerを使うとアプリケーション起動前にボタンごとの役割などを設定する事もできる。
またジャイロやタッチパネルなどのモバイルデバイスの入力も扱える。

キーボード

文字だけでなく、矢印キーやファンクションキーなどを扱う事ができる。
キーの指定には文字列表記かKeyCodeクラスの定数を使う。KeyCodeを使うと補完が効いてとても楽。
PC向けにほぼ限定されてしまうが設定などがシンプルなのでちょっとした動作確認には便利。

if (Input.GetKey(KeyCode.Space)) {
    transform.position = new Vector3(0f, transform.position.y + 0.1f, 0f);
} else {
    transform.position = new Vector3(0f, transform.position.y - 0.1f, 0f);
}

補完に頼れば覚える必要はないがKeyCodeは次のような定数。

名前 内容
KeyCode.Space スペース
KeyCode.Return リターンキー
KeyCode.UpArrow 上向き矢印
KeyCode.A a
KeyCode.LeftControl 左側のコントロールキー

使うメソッドによって入力を返すタイミングが異なる。

名前 内容
Input.GetKey キーを押している間は常に(連射状態)
Input.GetKeyDown キーを押していない状態から押した時
InputGetKeyUp キーを押している状態から話した時

ゲームパッドのボタン

ゲームパッドのボタンはゲームパッドの種類によってまちまちな部分が多いのでInput ManagerでJump、Fireといった論理的なボタンを作り、そこに実際のデバイスのボタンを割り当てるというステップを踏む。若干わかりにくい。またゲームパッドがない場合にキーボードでは何を使うといった設定も可能、また配布したゲームを実行する際にはプレイヤーが自分で割り当てを変更することも出来て柔軟性が高い。

標準で設定されている論理ボタンは下記のとおり。

名前 内容
Jump スペースキー または ジョイスティックのボタン3
Fire1 左Ctrl 左クリック ジョイスティックのボタン0
Fire2 左Alt 右クリック ジョイスティックのボタン1
Fire3 左Cmd 中央クリック ジョイスティックボタン2

とりあえずはこの初期設定のボタンを使えばキーボードとジョイスティックに両対応した状態の動作に出来るのが魅力。
ただし、複数のジョイスティックを繋いだりキーボードと同時に操作すると全ての動作がマージされる。

よくわからない時はEdit > Project Setting > Inputで確認する。

新しいボタンを追加する時はSizeを変更するか既存の設定をDupulicateする。

ボタン名さえわかればGetButton系のメソッドで自由に状態を取得できる。

名前 内容
Input.GetButton ボタンを押している間は常に(連射状態)
Input.GetButtonDown ボタンを押していない状態から押した時
InputGetButtonUp ボタンを押している状態から話した時
if (Input.GetButton("Jump")) {
    transform.position = new Vector3(0f, transform.position.y + 0.1f, 0f);
} else {
    transform.position = new Vector3(0f, transform.position.y - 0.1f, 0f);
}

ボタン名は大文字小文字を区別するので注意。
このコードだとボタンとキーボードの双方に反応するようになっている。

ゲームパッドの方向

ゲームパッドの方向もInput Manegerの設定を元に取得する。同じ名前の軸を作り、キーボードなどを割り当てることもできるが、アナログ的な入力はシミュレーションになる。

方向を取得するメソッドは次のとおり。

名前 内容
Input.GetAxis 入力された軸に補正をかけて-1から1までの数値で返す。
Input.GetAxisRaw 入力された軸に補正をかけずに-1から1までの数値で返す。

方向の押され具合を反映したアナログな動きをする場合とそうでない場合で利用するメソッドを変える。

transform.position = new Vector3 (
    transform.position.x + Input.GetAxis("Horizontal"),
    0,
    transform.position.z + Input.GetAxis("Vertical")
);

上記はじわじわした動き。

transform.position = new Vector3 (
    transform.position.x + Input.GetAxisRaw("Horizontal"),
    0,
    transform.position.z + Input.GetAxisRaw("Vertical")
);

モバイル向け

モバイル向けの入力も扱えるが、デバイスによってタッチ可能な数などが違ったりする。

タッチパネル

Input.touchesを使う。タッチした位置からRaycastを飛ばして何をタッチしたのかを判定する。
開発時はUSBでスマフォをつなぎ、UnityRemote4をインストールする。

Edit > Project Setting > Editorを参照。

var particle : GameObject;
function Update () {
    for (var touch : Touch in Input.touches) {
        if (touch.phase == TouchPhase.Began) {
            // 現在のタッチ位置からRaycast
            var ray = Camera.main.ScreenPointToRay (touch.position);
            if (Physics.Raycast (ray)) {
                // ヒットした場合はパーティクルを作成
                Instantiate (particle, transform.position, transform.rotation);
            }
        }
    }
}

Unity自身がマウス操作をエミュレートする機能ももっているのでマウス操作に対応した処理があればタッチパネルでもそれなりに動く。

CrossPlatformInput

Standard AssetやSample Assetにバーチャルパッドのアセットが含まれている。
遊んだことがある人はわかると思うけれど、かなり癖があるのでよく考えてデザインする必要がある。

コードとしてはCrossPlatformInputクラスを使う。

iOS7 GamePad

iOS7のゲームパッドは普通に使える。ボタン番号がやたらデカイので注意。

複数のゲームパッドを使うと?

けっこうハマった。