【PlayStation Vita】やっぱりハードウェアボタンを使ったVitaのゲームを作りたい！Unityで！【Unity for PSM】

# はじめに

　Unityでゲーム開発を初め、Unityでモバイル向けのゲームを作っている方は、「ハードウェアキーがあるゲームも作ってみたい」と一度は考えたことがあるのではないでしょうか？

　Unity for PSMを使えば、UnityでPlayStation VitaそしてPlayStation Vita TV向けのゲームを開発することが可能です。ゲーム専用機のPlayStation Vita向けであれば、ハードウェアキーを使うゲームを開発することが可能です。

　自在にキャラクターを動かしたり、グルグルカメラを回したり、ギリギリで敵の攻撃かわしたり、シビアなタイミングで敵を攻撃をしたり。

　この投稿では、Unity for PSMでボタンとアナログスティックを扱う方法をまとめました。

# Input.GetKeyDownでボタン入力を検知

　各方向キーや、×△□○ボタンなどPlayStation Vitaのボタンの入力を検知するために、下記のInput.GetKey系のメソッドのKeyCodeを引数にとるオーバーロードを使ってみます。

* [Input.GetKeyDown](http://docs.unity3d.com/ScriptReference/Input.GetKeyDown.html)
* [Input.GetKey](http://docs.unity3d.com/ScriptReference/Input.GetKey.html)
* [Input.GetKeyUp](http://docs.unity3d.com/ScriptReference/Input.GetKeyUp.html)

などです。(それぞれの違いやタイミングについては、よかったら[こちら](http://qiita.com/RyotaMurohoshi/items/a5cde3c17831adda12db)を見てください。)

　Input.GetKey系のメソッドの引数として、例えば×ボタンにはKeyCode.JoystickButton0を、方向キー上にはKeyCode.JoystickButton8を渡すことで、そのボタンが入力されたかを調べることが可能です。

```csharp:InputGetKeyDownでPlayStationVitaのハードウェアキー入力を検知
void Update ()
{
	bool isPushCorss = Input.GetKeyDown (KeyCode.JoystickButton0);
	bool isPushDUp = Input.GetKeyDown (KeyCode. JoystickButton8);
}
```

　下記に各ボタンとそれに対応する[KeyCode](http://docs.unity3d.com/ScriptReference/KeyCode.html)の列挙型を示します。

| ボタン | 列挙型                   |
|:--------:|:------------------------:|
| ×ボタン | KeyCode.JoystickButton0  |
| ○ボタン | KeyCode.JoystickButton1  |
| □ボタン | KeyCode.JoystickButton2  |
| △ボタン | KeyCode.JoystickButton3  |
| Lボタン | KeyCode.JoystickButton4  |
| Rボタン | KeyCode.JoystickButton5  |
| SELECTボタン | KeyCode.JoystickButton6 |
| STARTボタン | KeyCode.JoystickButton7 |
| 方向キー上 | KeyCode.JoystickButton8 |
| 方向キー右	| KeyCode.JoystickButton9 |
| 方向キー下	| KeyCode.JoystickButton10 |
| 方向キー左	| KeyCode.JoystickButton11 |

　ちなみにInput.GetKey系のメソッドにはstringを引数にとるものもあります。×ボタンを検知するためには`"joystick button 0"` という文字列を、方向キー上を検知するためには`"joystick button 8"`を引数に渡します。渡す文字列は[こちら](http://docs.unity3d.com/Manual/ConventionalGameInput.html)を見てください。

　上記メソッドを使うことで各ボタンの入力検知を、一応することができます。しかし、それぞれのボタンがどのKeyCodeに対応するのかいちいち確認したり、もしくは覚える必要があり面倒です。

　そこでInputManagerの設定をします。例えばStartボタンの入力検知をやりやすくするために、GetButtonなどのメソッドに文字列`"Start"`を渡して、入力を検知できるように設定するのです。(InputManagerの設定などは[こちら](http://qiita.com/RyotaMurohoshi/items/688fe33f44de8339c497)の投稿を良かったら見てください。)

　上下左右の方向キー、×△□○ボタン、RLボタン、Start・Selectボタンの入力設定を自分でやっても良いのですが、実は便利なInputManager.asset(InputManagerの設定が保存されているファイル)がUnity for PSMのサンプルに同梱されています。

# Unity for PSM用のInputManager.assetをインポートする

　まずサンプルプロジェクトをインポートします。マウスカーソルをプロジェクトビュー上に持って来て右クリックをします。そして、Import Package > PSM Samples > Input And Motionを選択します。そうすると入力とモーションのサンプルコードがインポートされ、Assets以下にExamples/PSM/Inputというディレクトリが生成されます。これでサンプルプロジェクトのインポートが完了です。

　次にサンプル内のInputManager.assetをプロジェクトに反映させます。一度Unityを終了し、先ほどインポートしたプロジェクト内にあるzipファイルを解凍すると、その中にInputManager.assetというファイルがあります。このファイルと、unityプロジェクトルートの下にあるProjectSettingsというディレクトリにあるInputManager.assetというファイルを置き換えます。これでInputManagerのインポートはできました。

　この節の中身は、nakamura001さんのブログ「強火で進め」の[[Unity for PSM]公式のサンプル](http://d.hatena.ne.jp/nakamura001/20140623/1403532813)という投稿で、画像付きで大変分かりやすく説明されています。

　ちなみにProjectSettings以下のInputManager.assetは、入力に関するプロジェクトの設定が保存されているファイルです。メニューのEdit > ProjectSettings > Inputを選択することで、Inspectorビューにプロジェクトの入力設定ビューが表示されます。そのビューで入力設定を変更すると、InputManager.assetが変更されます。

# 分かりやすい文字列とGetButton系のメソッドでボタン入力を検知

　それでは先ほどインポートしたInputManagerの中身を見てみます。

　メニューのEditor > ProjectSettings > Inputを選択するとInspectorビュー中に入力設定ビューが表示されます。前節で紹介した手順でInputManager.assetを置き換えていた場合、次の画像のように表示されると思います。

![image0.PNG](https://qiita-image-store.s3.amazonaws.com/0/4125/65a5ab16-fb74-074d-88c3-37808daf1a48.png "image0.PNG")

　計36個の項目がありますね。実は通常の場合(PSM用のサンプル内に同梱されているInputManager.assetで置き換えていない場合)だと次の画像のように計15の項目しかありません。増えた21個はPSM用の入力設定です。

![image1.PNG](https://qiita-image-store.s3.amazonaws.com/0/4125/3312ea40-a09c-c48c-5b76-74a5c9d987e4.png "image1.PNG")

　それではPSM用の入力設定をいくつか見てみましょう。


### ×ボタンのCross
　まずはCross。

![image2.PNG](https://qiita-image-store.s3.amazonaws.com/0/4125/d5b541e5-3ed2-56ab-f9f2-12081a7afe46.png "image2.PNG")


　これはPlayStation Vitaの×ボタンを司ります。上記の画像のように、Nameは「Cross」でTypesは「Key or Mouse Button」、positive buttonは「joystick button 0」になっていますね。この「joystick button 0」という文字列はKeyCode.JoystickButton0と対応します。KeyCode.JoystickButton0をInput.GetKey系のメソッドの引数として渡すと、×ボタンの入力検知ができるのでしたね。

　このCrossという設定項目により、次のようにInput.GetButton系のメソッドに引数として`"Cross"`という文字列を渡すことで、×ボタンの入力検知ができます。

```csharp:Crossという文字列で×ボタンの入力検知
void Update ()
{
    bool isPushCorss = Input.GetButtonDown ("Cross");
}
```

### 方向キー上ボタンのDup

　次に方向キー上ボタン。このボタンはDupという項目が関係します。Dupは次の画像のように、Nameは「Dup」でTypesは「Key or Mouse Button」、positive buttonは「joystick button 8」になっていますね。

![image3.PNG](https://qiita-image-store.s3.amazonaws.com/0/4125/92f45747-32fa-b924-6edb-0df9c2a660d6.png "image3.PNG")

　次のコードで方向キー上ボタンの入力検知が可能です。

```csharp:Dupという文字列で方向キー上ボタンの入力検知
void Update ()
{
    bool isPushUp = Input.GetButtonDown ("Dup");
}
```

### StartボタンとStart
　StartボタンはStartという項目です。Nameは「Start」でTypesは「Key or Mouse Button」、positive buttonは「joystick button 7」です。


![image4.PNG](https://qiita-image-store.s3.amazonaws.com/0/4125/cb2395c8-a685-5ed7-86d2-d0fb12619bdc.png "image4.PNG")


```csharp:Startという文字列でStartボタンの入力検知
void Update ()
{
    bool isPushStart = Input.GetButtonDown ("Start");
}
```


### 入力ボタンと対応文字列
　このようにInputManagerでの設定により、KeyCode.JoystickButton0でなく、文字列の`"Cross"`とか`"Start"`などでボタン入力を検知をすることができます。下記に各ボタンと該当文字列(InputManagetの項目名)を示します。

| ボタン | 文字列(項目名) |
|:--------:|:---------:|
| ×ボタン | Cross |
| ○ボタン | Circle |
| □ボタン | Square |
| △ボタン | Triangle |
| Lボタン | Left Shoulder |
| Rボタン | Right Shoulder |
| SELECTボタン | Select |
| STARTボタン | Start |
| 方向キー上 | Dup |
| 方向キー右	| Dright |
| 方向キー下	| Ddown |
| 方向キー左	| Dleft |


# アナログスティクの入力を検知する
　前々節で説明したInputManagerの置き換えをしている場合、以下のコードでアナログスティックの入力検知ができます。

```
void Update ()
{
	float leftStickHorizontal = Input.GetAxis("Left Stick Horizontal");
	float leftStickVertical = Input.GetAxis("Left Stick Vertical");
	float rightStickHorizontal = Input.GetAxis("Right Stick Horizontal");
	float rightStickVertical = Input.GetAxis("Right Stick Vertical");
}
```

　これはInputManager内の以下の項目での設定によるものです。

* Left Stick Horizontal
* Left Stick Vertical
* Right Stick Horizontal
* Right Stick Vertical


　Input.GetAxisについて[こちら](http://qiita.com/RyotaMurohoshi/items/7868752a3f056affa2df)もどうぞ。

# 自作クラスと列挙型を作ってタイポしたり忘れないようにする
　"Cross"や"Start"、"Left Shoulder"などの文字列の方が、KeyCodeよりは分かりやすいです。ですがうっかり"Cros"ってタイポしたり、「あれ、"LeftShoulder"だっけ？スペースいれるんだっけ？」ってなってしまうと思うんですよ。

　これを避けるために、ボタンやアナログスティクの軸をそれぞれ表す列挙型とそれを扱うInputクラスをラップするPsmInputクラスを作ってみました。


```csharp:PsmInput.cs
using UnityEngine;

public static class PsmInput
{
	public static bool GetButton (PsmButton button)
	{
		return Input.GetButton (ToString (button));
	}
	
	public static bool GetButtonDown (PsmButton button)
	{
		return Input.GetButtonDown (ToString (button));
	}
	
	public static bool GetButtonUp (PsmButton button)
	{
		return Input.GetButtonUp (ToString (button));
	}
	
	public static float GetAxis (PsmStickAxis axis)
	{
		return Input.GetAxis (ToString (axis));
	}
	
	public static Vector2 GetLeftStick ()
	{
		return new Vector2 (
			GetAxis (PsmStickAxis.LeftStickHorizontal),
			GetAxis (PsmStickAxis.LeftStickVertical)
		);
	}
	
	public static Vector2 GetRightStick ()
	{
		return new Vector2 (
			GetAxis (PsmStickAxis.RightStickHorizontal),
			GetAxis (PsmStickAxis.RightStickVertical)
		);
	}
	
	static string ToString (PsmStickAxis axis)
	{
		switch (axis) {
		case PsmStickAxis.LeftStickHorizontal:
			return "Left Stick Horizontal";
		case PsmStickAxis.LeftStickVertical:
			return "Left Stick Vertical";
		case PsmStickAxis.RightStickHorizontal:
			return "Right Stick Horizontal";
		case PsmStickAxis.RightStickVertical:
			return "Right Stick Vertical";
		default :
			throw new System.ArgumentException ("Invalid PsmStickAxis argument.");
		}
	}
	
	static string ToString (PsmButton button)
	{
		switch (button) {
		case PsmButton.Cross:
			return "Cross";
		case PsmButton.Circle:
			return "Circle";
		case PsmButton.Triangle:
			return "Triangle";
		case PsmButton.Square:
			return "Square";
		case PsmButton.LeftShoulder:
			return "Left Shoulder";
		case PsmButton.RightShoulder:
			return "Right Shoulder";
		case PsmButton.Select:
			return "Select";
		case PsmButton.Start:
			return "Start";
		case PsmButton.Dup:
			return "Dup";
		case PsmButton.Dright:
			return "Dright";
		case PsmButton.Ddown:
			return "Ddown";
		case PsmButton.Dleft:
			return "Dleft";
		default :
			throw new System.ArgumentException ("Invalid PsmButton argument.");
		}
	}
	
}

public enum PsmStickAxis
{
	LeftStickHorizontal,
	LeftStickVertical,
	RightStickHorizontal,
	RightStickVertical,
}

public enum PsmButton
{
	Cross,
	Circle,
	Triangle,
	Square,
	LeftShoulder,
	RightShoulder,
	Select,
	Start,
	Dup,
	Dright,
	Ddown,
	Dleft,
}
```

```csharp:PsmInput.csの使い方
bool isPushCross = PsmInput.GetButton (PsmButton.Cross);
bool isPushUp = PsmInput.GetButton (PsmButton.Dup);
float leftStickHorizontal = PsmInput.GetAxis (PsmStickAxis.LeftStickHorizontal);
Vector2 leftStickInput = PsmInput.GetLeftStick ();
```

　これらの列挙型とクラスを使えばタイポすることもありませんし、あれスペースってどうだっけってなることもありませんんね。(このクラスを使うためには、サンプル内のInputManager.assetをインポートする必要があります。)

# 【おまけ】Vita TC onlyって？Vita TV onlyかな？

　サンプル内のInput.assetにあつ次の4個の項目

* Left Shoulder
* Right Shoulder
* Left Stick
* Right Stick

　これらは実は、Descriptive Nameの前半が、「Vita TC Only」となっています。これはVita TV Onlyなのでしょうか？タイポでしょうかね？確かにPlayStation Vita TVのコントローラのワイヤレスコントローラ(DUALSHOCK®3)には、RLボタンそれぞれ２個ずつありますし、アナログスティックもボタンみたいに押せるんですよね。これらのはVita TVのための設定項目なんでしょうか？

　ただ[ここ](https://psm.playstation.net/static/general/all/unity_for_psm/ja/Documentation/Manual/PSMInput.html)とかには、まったくVita TVについて言及していないんですよね。

# まとめ

　Unity for PSMでは、PlayStation VitaそしてPlayStation Vita TVでのボタン入力やアナログスティック入力をInputクラスのメソッドで管理できます。

　ボタンに関しては、KeyCodeを引数にとるオーバーロードのInput.GetKeyDownなどのメソッドでボタン入力を検知することもできます。ですが、PSMのサンプルにあるInputManaget.assetをインポートすることで、より分かりやすい文字列とInput.GetButtonDownなどのメソッドで入力を検知することが可能です。

　Unity for PSMで、自在にキャラクターを動かしたり、グルグルカメラを回したり、ギリギリで敵の攻撃かわしたり、シビアなタイミングで敵を攻撃をしたりするゲームが作りたくなってきました！

# 関連投稿

　Unity for PSMやUnityのボタン入力・キー入力に関する私の関連投稿です。良かったら読んでください。

* [PlayStation VitaのゲームをUnityで作ってみたい！という人のための最初のリンク集【Unity for PSM】](http://qiita.com/RyotaMurohoshi/items/921aeb256671defded2f)
* [GetKeyDownとかGetButtonUpとかがtrueになるタイミングの遷移について](http://qiita.com/RyotaMurohoshi/items/a5cde3c17831adda12db)
* [InputクラスのGetKey系とGetButton系のどっちを使えば良いの？を調べてみた](http://qiita.com/RyotaMurohoshi/items/688fe33f44de8339c497)
* [Input.GetAxisとInputManagerの関連設定について](http://qiita.com/RyotaMurohoshi/items/7868752a3f056affa2df)

# 参考ページ

* [Unity for PSM のインプットサポート](https://psm.playstation.net/static/general/all/unity_for_psm/ja/Documentation/Manual/PSMInput.html)
* [Conventional Game Input](http://docs.unity3d.com/Manual/ConventionalGameInput.html)

　次の2個のリンクは、nakamura001さんのブログ「強火で進め」の記事へのリンクです。

* [[Unity for PSM]公式のサンプル](http://d.hatena.ne.jp/nakamura001/20140623/1403532813) 
* [[Unity for PSM] PS Vita のゲームパッド入力を取得する時のパラメータ一覧](http://d.hatena.ne.jp/nakamura001/searchdiary?of=1&word=%2A%5BUnity%20for%20PSM%5D)