シンプルなアクションゲームを作ってみようの第22回です。
今回は新しい入力システムであるInput Systemに対応していきます。
前回はライトのベイクをしました。
シンプルなアクションゲームを作ってみようの他の記事は
シンプルなアクションゲームを作るのを通してUnityの使い方を学ぶカテゴリです。
から参照出来ます。
Input Systemについて
ここまでの記事ではInput Managerで設定したキーやボタンを押した時(例えばInput.GetAxis(“Horizontal”)やInput.GetButtonDown(“Jump”))に、キャラクターの移動やジャンプの処理をさせてきました。
しかし、ボタンの設定を変更するといった機能をゲーム内に用意する場合は柔軟に変更することが難しいです。
新しい入力システムのInput Systemでは拡張可能でカスタマイズ可能になっています。
Input Systemに対応するので、これを機会にPS4のコントローラーにも対応してしまいます(InputManagerでも対応は可能です)。
Input Systemを使う前の注意
Input Systemパッケージをインストールすると、『入力方法をInput Systemに変更しInput Managerを使えなくするか?』というダイアログが出てきて、Yesを押すとここまで使っていたInput Managerが使えなくなります。
自分で設定を変更すればInput Managerを使うように戻せますし、両方を使う事も出来ますので、今回はNoを押して自分で設定をし、両方の入力システムを使えるようにします。
Input Systemのインストール
まずはInput Systemのインストールを行います。
UnityメニューのWindowからPackage Managerを選択します。
Package Managerのパッケージの種類をUnity Registryにし、Input Systemを選択してInstallボタンを押しインストールします。
インストール途中で以下のようにダイアログが表示されます。
このダイアログではInput Systemを使用するにあたって有効にし、Input Managerを無効にして再起動するかを聞かれているのでNoのボタンを押します。
Input ManagerとInput Systemを両方有効にする
次にInput Systemを使えるようにする為の設定をします。
UnityメニューのEditからProject Settingsを選択し、Playerを選択します。
PlayerのOther SettingsのConfigurationのActive Input Handlingの設定をBothと変更します。
以下のようなダイアログが出て、設定を有効にするにはUnityエディターを再起動する必要があると表示されるので、Applyボタンを押して設定を有効にします(Unityエディターが再起動されます)。
UIのイベント処理をするEventSystemの更新
Input SystemとInput Managerの両方を有効にしましたが、UIのイベントを処理するEvent Systemゲームオブジェクトの更新をしてInput Systemでの対応にします。
Stage1シーンのEventSystemゲームオブジェクトを選択し、インスペクタでStandalone Input ModuleコンポーネントのReplace with InputSystemUIInputModuleボタンを押してInput Systemに対応します。
ボタンを押すと以下のようにInput Systemに対応した表記に変わります。
Input Actionsの作成
次にInput Systemで使うアクションの割り当てをするファイルを作成します。
Assets/Settingsフォルダで右クリックからCreate→Input Actionsを選択し、名前をMyControlsとします。
MyControlsファイルでの設定がInput Managerのボタン設定と同じ感じです。
MyControlsファイルをダブルクリックするとアクションの設定ウインドウが開きます。
次にAction Mapsの+を押し名前をPlayerとします。
Actionsに新しく出来たNew Actionの部分をダブルクリックし名前をMoveと変更します。
またPropertiesのControl TypeをVector2にします。
<No Binding>の部分を選択し、PropertiesのBindingのPathでGamepad→Left Stickを選択します。
次にMoveアクションを選択した状態で右クリックからAdd 2D Vector Compositeを選択し、名前をArrowとします。
次にUp: <No Binding>を選択しPropertiesのBindingのPathを押し、出てきたウインドウのListenを押し次にキーボードの↑のキーを押し、出てきたUp Arrowをマウスで選択し設定します。
各方向も同じように該当するキーボードの矢印キーを設定してください。
矢印キーの設定は以下のようになりました。
次にActionsの横の+を押し新しいアクションを追加して名前をJumpにします。
Jumpに対応するのはSpaceキーとGamepadのButton Southを設定します。
設定の仕方は同じです。
<No Binding>を選択し、PropertiesのBindingのPathを押し、Listenを押してSpaceキーを押し、出てきたSpace[Keyboard]をマウスで選択し、設定します。
Jumpを選択した状態で右クリックからAdd Bindingを選択し、<No Binding>を選択した状態でPropertiesのBindingのPathを押し、Gamepad→Button Southを選択します。
Button SouthはPS4で言うと×ボタンにあたります。
次にActionsの右の+を押し、Pauseアクションを作成します。
PauseアクションにはEscapeキーとStart[Gamepad]を設定します。
EscapeキーはListenから探せないので、Keyboard→By Location Of Key→Escapeを選択します。
Start[Gamepad]はGamepad→Start[Gamepad]で選択します。
これでアクションの設定が終わりました。
PlayerにPlayerInputコンポーネントを追加する
アクション設定のファイルが出来たので次はこのアクションファイルを設定するコンポーネントをPlayerゲームオブジェクトに取り付けます。
Stage1シーンのヒエラルキーのPlayerゲームオブジェクトを選択し、インスペクタのAdd ComponentからInput→Player Inputを選択し取り付けます。
Player InputのActionsに先ほど作ったMyControlsファイルをドラッグ&ドロップして設定します。
スクリプトの入力をInputSystemに変更する
スクリプトでInputManagerを使った入力処理を記述しているので、InputSystemを使った処理に書き換えます。
InputManagerの処理を消したくない場合は別途スクリプトを作るのでもいいです。
PlayerControllerスクリプトの入力を変更する
PlayerControllerスクリプトの処理を変更します。
まずはusingディレクティブの指定と、PlayerInputコンポーネントを入れるplayerInput、PlayerInputに設定したMyControlsファイルで指定しているMoveとJumpのアクションを入れるmoveActionとjumpActionを宣言します。
1 2 3 4 5 6 7 | using UnityEngine.InputSystem; private PlayerInput playerInput; private InputAction moveAction; private InputAction jumpAction; |
StartメソッドのcanControlの処理の前に以下の処理を追加します。
1 2 3 4 5 6 7 | void Start() { playerInput = GetComponent<PlayerInput>(); moveAction = playerInput.currentActionMap.FindAction("Move"); jumpAction = playerInput.currentActionMap.FindAction("Jump"); } |
PlayerInputは自身のゲームオブジェクトに取り付けたPlayerInputを取得します。
moveActionとjumpActionは取得したplayerInputから現在のアクションマップを取得し、FindActionメソッドで引数で指定したアクションを取得します。
次にMoveメソッドでinputに代入する処理を変更します。
1 2 3 4 | //input = new Vector3(Input.GetAxis("Horizontal"), 0f, Input.GetAxis("Vertical")); input = new Vector3(moveAction.ReadValue<Vector2>().x, 0f, moveAction.ReadValue<Vector2>().y); |
入力値は取得したmoveActionのReadValueメソッドでVector2の値を取得し、xとyをVector3のxとzに設定しています。
次にJumpメソッドのJumpボタンが押されたかどうかで判断している部分の処理を変更します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | // ジャンプ処理 private void Jump() { // 接地している場合 if (isGrounded) { // ジャンプ処理 //if (Input.GetButtonDown("Jump")) { if (jumpAction.triggered) { isGrounded = false; animator.SetBool("IsGrounded", isGrounded); isFirstJump = true; //velocity.y += jumpPower; //rigidBody.velocity = new Vector3(rigidBody.velocity.x, rigidBody.velocity.y + jumpPower, rigidBody.velocity.z); rigidBody.velocity = new Vector3(rigidBody.velocity.x, jumpPower, rigidBody.velocity.z); animator.SetTrigger("Jump"); } // ダブルジャンプ } else if (isFirstJump && jumpAction.triggered ) { isFirstJump = false; rigidBody.velocity = new Vector3(rigidBody.velocity.x, doubleJumpPower, rigidBody.velocity.z); } // ジャンプ力をアニメーションパラメータに設定 animator.SetFloat("JumpPower", rigidBody.velocity.y); } |
最初のジャンプの時のJumpボタンを押した時の処理でInput.GetButtonDown(“Jump”)で判断していたのをjumpAction.triggeredでJumpに指定したボタンがトリガーされた時に変更しています。
ダブルジャンプ時の条件にもjumpAction.triggeredに変更します。
PauseScriptスクリプトの入力を変更する
次にPauseScriptスクリプト内の処理を変更します。
1 2 3 4 5 6 7 | using UnityEngine.InputSystem; [SerializeField] private PlayerInput playerInput; private InputAction pauseAction; |
PauseScriptはGameManagerゲームオブジェクトに取り付けているのでPlayerInputのアクションファイルを自身から取得する事は出来ません。
そこでインスペクタでPauseScriptのPlayerInputにPlayerゲームオブジェクトをドラッグ&ドロップして設定出来るようにします。
pauseActionはPlayerInputに設定しているアクション設定ファイルからPauseアクションを取得し入れます。
Startメソッドを書き換えます。
1 2 3 4 5 6 7 8 9 | // Start is called before the first frame update void Start() { pauseAction = playerInput.currentActionMap.FindAction("Pause"); // スタート時にポーズUIを非表示にする pauseUI.SetActive(false); } |
PlayerInputからPauseアクションを取得します。
次にUpdateメソッドを変更します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | // Update is called once per frame void Update() { // ポーズボタンを押した時 //if(Input.GetButtonDown("Pause")) { if(pauseAction.triggered) { if(Mathf.Approximately(Time.timeScale, 1f)) { Time.timeScale = 0f; pauseUI.SetActive(true); } else { Time.timeScale = 1f; pauseUI.SetActive(false); } } } |
pauseAction.triggeredでPauseアクションがトリガーされた時にポーズをするようにします。
実行して確認してみる
機能が出来たので実行して確認してみましょう。
今回はPS4コントローラーで動かすだけなので、動画では違いがわかりませんので載せません。(^_^;)
PS4コントローラーを接続しても操作が出来ない場合はパソコンを再起動すると動く可能性が高いです。
終わりに
今回はInputManagerからInputSystemに入力システムを変更しました。
次回はCinemachineを使ってカメラがキャラクターの追尾をするようにしていきます。