![こじゃら](/wp-content/uploads/avatars/avatar-0001-01.png)
![こじゃら](/wp-content/uploads/avatars/avatar-0001-01-dark.png)
Input Systemを使ってキャラを走らせたりジャンプさせたりする方法を教えてほしいの。
![このは](/wp-content/uploads/avatars/avatar-0002-01.png)
![このは](/wp-content/uploads/avatars/avatar-0002-01-dark.png)
Input SystemとCharacter Controllerと組み合わせれば簡単かもしれないわ。
Input Systemを用いてキャラクターを操作する方法についての解説記事です。
本記事では、Input SystemとCharacter Controllerを組み合わせて、キャラクターを操作する方法を紹介します。
Character Controller自体は、主にゲームオブジェクトを移動させる役割のみを持つコンポーネントで、コントローラーからの入力を受け取る機能はありません。
参考:Character Controller コンポーネントのリファレンス – Unity マニュアル
そのため、Character Controllerによってキャラクターを移動させるためには、次のような実装が必要になります。
- Input Systemのセットアップ
- Character Controllerのセットアップ
- Input Systemからの操作入力を受け取る処理の実装
- 操作入力を元にCharacter Controllerを移動させる処理の実装
なお、Character Controllerを用いてキャラクターを移動させるやり方は、Unity公式アセットであるStarter Assetsでも使われているので、こちらのサンプルプロジェクトを覗いてみても良いでしょう。
本記事では、Input SystemとCharacter Controllerを用いてキャラクターを移動させたりジャンプさせたりする方法を具体的な手順とともに解説していきます。
- Unity 2022.1.5f1
- Input System 1.3.0
目次 非表示
前提条件
事前にInput Systemがインストールされ、有効化されているものとします。
ここまでの手順が分からない方は、以下記事をご覧ください。
また、本記事ではPlayer Inputを用いてInput Systemの操作入力を受け取るものとして手順を解説します。
Player Inputの使い方が分からない方は、以下記事をご覧ください。
また、シーンには次のように操作対象のキャラクター(カプセル)が配置されているものとします。
![](/wp-content/uploads/2022/06/unity-input-system-character-controller-1-1024x581.png)
例では、このカプセルをInput Systemの入力に応じて移動させるものとします。
Player InputおよびInput Action Assetの設定
Player Inputが生成するデフォルトActionを用いるものとします。
まず、操作対象のゲームオブジェクトを選択し、Player Inputコンポーネントをアタッチします。
Player InputコンポーネントのCreate Assetsボタンから、Input Actionアセットを適当な場所に保存します。
すると、次のようなデフォルトのInput Actionアセットが生成されます。
![](/wp-content/uploads/2022/06/unity-input-system-character-controller-2.png)
例では、PlayerマップのMoveアクションを移動量の操作入力として使用することとします。
また、ジャンプ操作を実現するためにJumpアクションを追加で定義することとします。
上の動画では、キーボードのスペースキーとゲームパッドのSouthボタンをジャンプボタンに割り当てています。
Input Actionの定義方法がよく分からない方は、以下記事も併せてご覧ください。
Character Controllerの適用
ゲームオブジェクトを移動させるために、対象オブジェクトにCharacter Controllerコンポーネントをアタッチします。
必要に応じて、Character Controllerの各種パラメータを調整してください。パラメータの詳細な説明は、以下公式リファレンスにて説明されていますので、必要に応じてご確認ください。
参考:Character Controller コンポーネントのリファレンス – Unity マニュアル
![このは](/wp-content/uploads/avatars/avatar-0002-01.png)
![このは](/wp-content/uploads/avatars/avatar-0002-01-dark.png)
次はいよいよスクリプトを書いていくわ。頑張って付いてきてね。
![こじゃら](/wp-content/uploads/avatars/avatar-0001-01.png)
![こじゃら](/wp-content/uploads/avatars/avatar-0001-01-dark.png)
はい!がんばりますっ!
キャラクター操作スクリプトの実装
Input Systemから操作入力を受け取り、キャラクターを移動させたりジャンプさせたりするスクリプトを実装していきます。
実装すべき内容は以下の通りです。
- Input Systemの入力値を受け取る
- 落下速度の計算
- 移動速度の計算
- Character Controllerに移動量を指定する
- 向きの計算・反映
ここまでの流れを一通り実装したスクリプトの例を示します。ここではカメラの向きは敢えて考慮していません。向きを考慮した例は後ほど示します。
上記スクリプトをPlayerController.csという名前で保存し、操作対象のオブジェクト(CharacterControllerがアタッチされているオブジェクト)にアタッチします。
必要に応じてインスペクターから各種設定を行ってください。
![](/wp-content/uploads/2022/06/unity-input-system-character-controller-3.png)
設定が終わったら、Player Inputからサンプルスクリプトに入力値を渡すようにします。
Player InputのBehaviourをInvoke Unity Eventsに変更し、Events > Player > MoveにOnMoveメソッドを、Events > Player > JumpにOnJumpメソッドを登録します。
最終的に次のような設定がPlayer InputにされていればOKです。
![](/wp-content/uploads/2022/06/unity-input-system-character-controller-4.png)
実行結果
ここまでの手順を成功させると、次のようにプレイヤーを移動させたりジャンプさせたりできるようになります。
キーボード操作のほか、ゲームパッド操作にも対応しています。
スクリプトの解説
先述のサンプルスクリプトの処理について一通り解説します。
入力値の受け取り
Player Inputから入力値を受け取る部分は以下コードです。
移動の入力値受け取りでは、入力値をフィールドに保持するだけの処理を行っています。ここでCharacter Controllerによる移動処理を行わない理由は、OnMoveメソッドのコールバックは基本的に入力値が変化した時しか呼ばれず、変化しないときは静止してしまうためです。
ジャンプボタンの入力受け取りでは、ボタンが押された瞬間(context.performedがtrue)かつ着地している状態(CharacterControllerのisGroundedプロパティがtrue)のみジャンプ操作として、鉛直上向きに速度を与えるようにしています。
落下速度の計算
Updateイベント内の以下のコードにて、重力加速度を考慮した落下速度(鉛直方向の速度)計算を行っています。
着地判定フラグ(isGrounded)をチェックし、空中にいるときは下向きに重力加速度を与え、徐々に下向きに加速させるような速度計算を行っています。
着地しているときは、自由落下したときの初速を常に与えるようにしています。これは、後述するCharacterControllerによる移動時に、傾斜面や段差などから落ちる動きを実現するためです。
移動速度の計算
キャラクターの移動速度を計算する処理は次の部分です。
移動入力のxy成分をそれぞれxz方向の移動量として計算します。入力値は通常-1~1の範囲となるので 、これに速さを掛けています。
y軸方向には、前述の落下速度計算によって得られた速度を指定しています。
Character Controllerへの移動量反映
以下コードにて、実際の移動が行われます。
移動速度に前フレームからの経過時間Time.deltaTimeを掛けて移動量を求め、この移動量分だけ移動するようにCharacterController.Moveメソッドを実行しています。
参考:Time-deltaTime – Unity スクリプトリファレンス
このメソッドは、指定された方向に移動させ、コライダーがあったらぶつかって止まるように振る舞うことができます。
前述の移動速度の計算より、着地しているときは斜め下向きに移動しようとしているため、次のように段差を降りるような動作も実現できます。
向きの計算・反映
最後に、以下コードで移動方向に振り向くような動きを入れています。
移動入力があった場合にのみ、振り向かせたい角度をMathf.Atan2メソッドで計算しています。
参考:Mathf-Atan2 – Unity スクリプトリファレンス
この時、角度を直接指定しても良いですが、急ではなく徐々に振り向くようにさせたかったので、Mathf.SmoothDampAngleメソッドで徐々に回転させるようにしています。
参考:Mathf-SmoothDampAngle – Unity スクリプトリファレンス
Mathf.SmoothDampAngleメソッドの具体的な使い方は、以下記事でも解説しています。
カメラの向きを考慮した例
先述のサンプルスクリプトでは、カメラが回転した場合も、ワールド空間の軸を基準に移動してしまっていました。
これをカメラの向き基準で移動できるようにした例も紹介しておきます。
使い方は、一つ目のスクリプトと一緒です。主な変更点は次の2か所です。
移動量計算
向き計算
カメラの角度分だけ回転させて補正する処理が追加されています。
実行結果
カメラの向きに応じて移動方向も変化するようになりました。
さいごに
Input SystemとCharacter Controllerを用いてキャラクターを動かす方法を解説しました。
本記事で紹介した方法はあくまで基本的な部分で、例えばアニメーションやその他のアクション動作などはありません。このような追加の動きは、本記事で紹介した方法を理解すると応用可能になるでしょう。
また、サードパーティー製のCharacter ControllerアセットをInput Systemに対応させたい場合は、移動量を受け取る部分をInput Systemのものに置き換える(またはスクリプトを修正する)といった対応が必要になるかもしれません。
入力値の受け取りとキャラクターの移動という2つのロジックに綺麗に分離されているアセットであれば、前者を変更すれば良く、Input Systemの移行も比較的楽になることでしょう。