1. はじめに
前回は、ゲームの走破距離の自己ベストを保存し、リザルト画面に表示する処理を実装しました。
今回は、いよいよ本連載の最終回です。
完成したゲームをPCでも快適に操作できるように、マウスとキーボードによる方向転換入力を追加します。
これに伴い、これまでのTap入力に直接依存していた処理を見直し、入力デバイスの違いを吸収するTurnInputManagerを導入します。
最後に、UnityのBuild Profilesを使用してWeb向けにビルドし、itch.ioで公開できる状態に仕上げます。
2. 入力処理の共通化
これまでは、画面の左右をTapすることでプレイヤーの方向転換を操作していました。
今回は、PCでも操作できるように、マウスとキーボードによる入力に対応します。
ただし、入力デバイスごとに方向転換の処理を追加していくと、PlayerCharacterManagerが個々の入力デバイスに依存する構造になってしまいます。
そこで、入力デバイスごとの検出処理と、プレイヤーへの方向転換指示を分離するために、TurnInputManagerを新たに導入します。
2.1. マウスとキーボードの入力を検出する
まず、マウス入力を検出するMouseDetectorと、キーボード入力を検出するKeyboardDetectorを作成します。
どちらもUnityのInput Systemを使用します。
MouseDetector
MouseDetectorでは、Mouse.currentからマウスの状態を取得し、各ボタンが押されたことを検出します。
Mouse mouse = Mouse.current;
if (mouse == null)
{
return;
}
if (mouse.leftButton.wasPressedThisFrame)
{
this.OnMouseButtonDown?.Invoke(MouseButton.LeftButton);
}
if (mouse.rightButton.wasPressedThisFrame)
{
this.OnMouseButtonDown?.Invoke(MouseButton.RightButton);
}
wasPressedThisFrameは、現在のフレームでボタンが押されたかどうかを判定するプロパティです。
ボタンが押されると、OnMouseButtonDownイベントを通じて、どのボタンが押されたかを通知します。
今回のゲームでは、左クリックを左方向への転換、右クリックを右方向への転換に使用します。
KeyboardDetector
キーボードについても同様に、Keyboard.currentからキーの状態を取得します。
Keyboard keyboard = Keyboard.current;
if (keyboard == null)
{
return;
}
if (keyboard.aKey.wasPressedThisFrame ||
keyboard.leftArrowKey.wasPressedThisFrame)
{
this.OnKeyboardButtonDown?.Invoke(KeyboardButton.LeftArrow);
}
if (keyboard.dKey.wasPressedThisFrame ||
keyboard.rightArrowKey.wasPressedThisFrame)
{
this.OnKeyboardButtonDown?.Invoke(KeyboardButton.RightArrow);
}
左方向への転換にはAキーまたは左矢印キー、右方向への転換にはDキーまたは右矢印キーを割り当てています。
こちらも、キーが押されたことをイベントで通知するだけで、プレイヤーの方向転換処理には関与しません。
2.2. TurnInputManagerで入力を共通化する
次に、各入力デバイスからの通知を受け取り、方向転換の指示に変換するTurnInputManagerを作成します。
マウスの左クリック、キーボードのAキーなど、入力方法は異なっていても、ゲーム内で実行したいアクションは同じ「左方向への転換」です。
そこで、入力デバイス固有の情報をTurnDirectionに変換し、共通のイベントで通知するようにします。
public event Action<TurnDirection> OnInputTurn;
TurnInputManagerでは、各Detectorのイベントを購読します。
public void Awake()
{
_mouseDetector.OnMouseButtonDown += OnMouseButtonDown;
_keyboardDetector.OnKeyboardButtonDown += OnKeyboardButtonDown;
}
public void OnDestroy()
{
_mouseDetector.OnMouseButtonDown -= OnMouseButtonDown;
_keyboardDetector.OnKeyboardButtonDown -= OnKeyboardButtonDown;
}
マウス入力を受け取った場合は、押されたボタンに応じて方向転換の指示を発行します。
private void OnMouseButtonDown(MouseButton pressedMouseButton)
{
switch (pressedMouseButton)
{
case MouseButton.LeftButton:
OnInputTurn?.Invoke(TurnDirection.Left);
break;
case MouseButton.RightButton:
OnInputTurn?.Invoke(TurnDirection.Right);
break;
default:
break;
}
}
キーボード入力についても、同様にTurnDirectionへ変換します。
private void OnKeyboardButtonDown(KeyboardButton pressedKeybordButton)
{
TurnDirection turnDirection =
pressedKeybordButton == KeyboardButton.LeftArrow
? TurnDirection.Left
: TurnDirection.Right;
OnInputTurn?.Invoke(turnDirection);
}
このように、入力デバイスごとの違いをTurnInputManagerで吸収することで、ゲーム側には方向転換の指示だけを通知できます。
2.3. PlayerCharacterManagerを変更する
最後に、PlayerCharacterManagerの入力処理を変更します。
これまではTapDetectorのイベントを直接購読していましたが、今後はTurnInputManagerのイベントを購読するようにします。
[SerializeField]
private TurnInputManager _turnInputManager;
イベントの購読と解除も変更します。
void OnEnable()
{
_turnInputManager.OnInputTurn += OnInputTurn;
// その他のイベント購読処理
}
void OnDisable()
{
_turnInputManager.OnInputTurn -= OnInputTurn;
// その他のイベント購読解除処理
}
また、方向転換の入力を受け取るメソッドを、TapSideではなくTurnDirectionを引数に取る形へ変更します。
private void OnInputTurn(TurnDirection turnDirection)
{
// 予約済みなら即終了
if (this._reservedAction != MainCharacterAction.None)
{
return;
}
// 方向転換のアクションを予約する
switch (turnDirection)
{
case TurnDirection.Left:
this._reservedAction = MainCharacterAction.TurnLeft;
break;
case TurnDirection.Right:
this._reservedAction = MainCharacterAction.TurnRight;
break;
}
}
方向転換の予約や実行の仕組みは、これまでと変わりません。
変更したのは、方向転換の指示を受け取る部分だけです。
これにより、PlayerCharacterManagerは、マウス・キーボードなどの入力デバイスを意識する必要がなくなりました。
今後、新しい入力方法を追加する場合も、TurnInputManagerでTurnDirectionへ変換すれば、プレイヤー側の方向転換処理を変更せずに対応できます。
2.4. 入力処理の共通化を終えて
今回の変更によって、入力処理は大きく次の3つの役割に分かれました。
-
MouseDetector、KeyboardDetector:各デバイスの入力を検出する -
TurnInputManager:入力を共通の方向転換指示に変換する -
PlayerCharacterManager:方向転換の指示を受け取り、アクションを予約する
機能としてはマウスとキーボードへの対応という小さな変更ですが、入力の検出とゲーム内の動作を分離することで、今後の拡張にも対応しやすい構造になりました。
3. Webビルド
マウスとキーボードによる入力に対応したので、最後にWebブラウザでプレイできるようにビルドします。
Unity 6では、Build Profilesからビルド対象のプラットフォームを選択できます。
3.1. ビルド対象をWebに切り替える
UnityのメニューからFile > Build Profilesを開きます。
左側のPlatformsからWebを選択し、Switch Platformボタンを押して、ビルド対象をWebに切り替えます。
プラットフォームの切り替えが完了すると、WebにActiveと表示されます。
また、Scene Listには、ゲームで使用するシーンが登録されていることを確認します。
今回はMainSceneのみを使用するため、次のシーンをビルド対象にしています。
Scenes/MainScene
3.2. Web向けにビルドする
プラットフォームの切り替えが完了したら、Buildボタンを押します。
保存先のフォルダを指定すると、Webブラウザで実行するためのファイルが生成されます。
生成される主なファイルとフォルダは、次のとおりです。
-
index.html:ゲームを表示するHTMLファイル -
Build:ゲーム本体のデータやWebAssemblyなどを格納するフォルダ -
TemplateData:Webページの表示に使用するテンプレート関連のファイルを格納するフォルダ
Webビルドは、Windows向けのビルドとは異なり、実行ファイル(.exe)を生成するものではありません。
また、生成されたindex.htmlを直接開いても、ブラウザのセキュリティ制限などによって正常に動作しない場合があります。
動作確認には、Build And Runを使用するか、ローカルのWebサーバーなどを利用します。
最後に、生成されたWebビルドをitch.ioにアップロードし、ブラウザからプレイできるようにします。
itch.ioへのアップロード手順については、サービス側のUI変更などもあるため、ここでは割愛します。
4. おわりに
今回は、マウスとキーボードによる入力への対応と、入力処理の共通化を行いました。また、Web向けにビルドし、itch.ioで公開できるようにしました。
これで、全24回にわたる「Unityで無限ランナーを作る」連載は完結です。
本連載では、プレイヤーの移動や床タイルの生成といった基本的な仕組みから始まり、方向転換、ゲームに緩急をつけるフェーズ制御、演出の追加、自己ベストの保存など、少しずつ機能を積み重ねてきました。
個々の機能を実装するだけでなく、それぞれのクラスにどのような役割を持たせ、どう組み合わせて一つのゲームとして成立させるか、という点も意識して開発を進めました。
完成したゲームは、以下のリンクからプレイできます。
Sky Bridge Runnerをプレイする(itch.io)
また、本連載をもとに、コードや説明を見直して再編集したPDF教材も制作しています。連載では説明しきれなかった設計上の考え方なども補いながら、順次執筆・更新しています。
全24回、最後までお読みいただきありがとうございました。
