今回はUnityの横スクロールアクションで2Dのキャラクター移動を実装していきます。
これまでに、2D用のマップや、プレイヤーとなるキャラクターは作成しているので、これらを元にして今回はキャラクターを移動させてみたいと思います。
※準備した内容については本文でおさらいします。
移動といっても、2Dの横スクロールアクションの場合、プレイヤーとなるキャラクターの移動は横移動(左右)だけになりますが、この横移動ができるだけでも一気にゲームっぽくなります。
コンテンツ
2Dのキャラクターを移動させるための準備
冒頭でもお伝えした通りキャラクターを操作して移動させるためには準備が必要になります。すでにこれらの記事は読んだ!という方はこの項目は読み飛ばしていただいてOKです。
■2Dマップの作成方法
今回はUnityのタイルマップ(Tile Map)機能を使って2Dのマップを作成してみます。 タイルマップはUnity2017.2から導入された機能で、2Dゲームのマップ作成を効率化&楽しみながら行う事ができます。まるで …
■2Dマップにキャラクターを配置する
Unityでは2Dのエディターを使用してスーパーマリオの様な横スクロールアクションを作成する事ができます。 以前、Unityのタイルマップ機能を使って2D横スクロールアクション用のマップを作成しましたが(今回もおさらいは …
2Dのキャラクターの横移動
今回はPCのキーボードを使用して横移動できる様にします。
※スマホ等で操作する場合も考え方は同じですし、簡単に変更可能です。
PCの場合、横方向への移動は「←→」のキーで操作するのが一般的です。
まずは以下の様なC#スクリプトを用意してプレイヤーキャラクターのオブジェクトにアタッチします。
横方向のキー情報を取得する方法
Unityでキー操作情報を取得する場合は以下のメソッドを使用します。
Input.GetAxis
「←→」キーの操作情報を取得する場合は以下の様な引数を指定すればOKです。
Input.GetAxis(“Horizontal”);
Horizontalって何?と思うかもしれませんが、今の所は横方法のキーを取得する場合は、この引数を指定するんだくらいに思っていただければOKです。
※この引数の値はUnityの設定等で変更も可能です。
GetAxisメソッドは以下の戻り値を返します。
- 「→」を押した時:+の数値
- 「←」を押した時:ーの数値
- どちらも押していない時は:0
※詳細については以下の公式リファレンスも参考にして下さい
URL:https://docs.unity3d.com/ja/current/ScriptReference/Input.GetAxis.html
つまり、この戻り値を元にして、
- 戻り値が+の数値:キャラクターを右に移動
- 戻り値がーの数値:キャラクターを左に移動
- 0:キャラクターは動かない
という判定処理を実装すればOKです。
移動用のC#スクリプト
以下の様なスクリプトを作成しました。まずはこのスクリプトを確認してみて下さい。スクリプトの後に細かい説明も付けています。
■C#スクリプト
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 28 29 30 31 32 33 34 35 36 37 38 39 40 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerControl : MonoBehaviour { private Rigidbody2D rb2d; private float x_val; private float speed; public float inputSpeed; void Start() { rb2d = GetComponent<Rigidbody2D>(); } void Update() { x_val = Input.GetAxis("Horizontal"); } void FixedUpdate() { //待機 if ( x_val == 0) { speed = 0; } //右に移動 else if ( x_val > 0) { speed = inputSpeed; } //左に移動 else if ( x_val < 0) { speed = inputSpeed * -1; } // キャラクターを移動 Vextor2(x軸スピード、y軸スピード(元のまま)) rb2d.velocity = new Vector2(speed, rb2d.velocity.y); } } |
ざっくりと処理の流れをまとめておきます。
変数
変数として以下を用意します。
※変数名は適切な名称に変えていただいてOKです。
型と変数名 | 処理詳細 |
Rigidbody2D rb2d | 2Dで物理演算を行うためのコンポーネント。このコンポーネントを使用してキャラクターを移動させる。 |
float x_val | キー入力情報を保持する。 |
float speed | キー入力情報を元にスピード(+なら右/ーなら左/0なら待機)を設定する。 |
float inputSpeed | 上記のspeedとは別にUnityエディタから設定できるスピード。 ※speed×inputSpeedが実際の速さとなる。 ※この変数はスピードの調整用に用意しています。 |
各メソッドの処理詳細
各メソッド(Start/Update/FixedUpdate)では主に以下の様な処理を行います。
メソッド(Start/Update/FixedUpdate) | 処理詳細 |
Start | Rigidbody2Dコンポーネントを取得。 |
Update | GetAxisでキー入力情報を取得。 |
FixedUpdate | 1.GetAxisで取得したキー情報を元に分岐してスピード(+なら右/ーなら左/0なら待機)を設定する。 2.Rigidbody2D.velocityを使ってキャラクターを移動させる |
ここで、なんでUpdateとFixedUpdateを使い分けるの?と思うかもしれません。この覚え方は有識者からすると良くないと言われているのですが、物理演算を行う処理は一般的にFixedUpdateを使用するケースが多いです。
※細かい理由は別途ご紹介させていただきます。
実行前準備
これでやっと移動が可能になるはずですが、実行前に以下の準備をしておきましょう。
・C#スクリプトをプレイヤーキャラクターにアタッチしましょう
・以下の様にinputSpeedをUnityエディタのInspectorウィンドウから設定ができるので、まずは適当な値を設定してみましょう。
実行結果
さて、実行してみましょう。
キー入力「←→」に併せて以下の様に横移動ができれいればとりあえずOKです。
想定通りに動かない!2Dの横移動でよくあるバグ!
想定通りに動かい場合は以下を確認してみて下さい。
2Dの横移動でよくあるバグを紹介しておきます
キャラクターが回転してしまう。
以下の様に移動するとキャラクターが回転してしまう事があります。
このバグはすごく簡単に言うとRididbody2Dを付与する事でキャラクターに重要が設定され、Z軸方向に回転する力が与えられた事が原因です。このバグを解消するためには以下の操作でZ軸のFreeze Rotationを与えます。
Rididbody2D>Constraints>Freeze Rotation>「Z」にチェックを入れる
タイル一つ分しか移動できない – Composite Collider 2Dの適用
以下の様にタイル一つ分程度しか移動ができない場合は、こちらを読み進めてみて下さい。
Tilemapには「Tilemap Collider 2D」が既に適用されていると思いますが、「Composite Collider 2D」が設定されていない場合は、こちらを適用して下さい。
「Composite Collider 2D」を適用していない状態だとTilemapのTile一つ一つに当たり判定が付くイメージになります。そのため、TileとTileの間に引っかかってしまう事があります。
「Composite Collider 2D」を適用する事でTilemap全体に一つの当たり判定を付けるイメージになるので、上記の様なバグは発生しないと思います。
「Composite Collider 2D」を適用する手順は以下になります。
- 対象のTilemapのInspectorウィンドウで「Composite Collider 2D」を追加します。
- 「Tilemap Collider 2D」>「Used By Composite」にチェックを入れる
Tilemapを見てみると当たり判定が変わった事が分かると思います。
Tilemapの当たり判定が変わった事により、キャラクターがスムーズに横移動できる様になったかを確認してみて下さい。
画面がスクロールしてしまう
実行ボタンを押した後、急に画面が上下にスクロールしてしまう事があります。その場合は、以下の設定をしてみましょう。
Tilemapのコンポーネント「Rigidbody 2D」>Body Typeを「Static」に変更
■Rigidbody 2D>Body Typeが「Dynamic」(変更前)
■Rigidbody 2D>Body Typeを「Static」に変更
いかがでしょうか?事象は改善されているでしょうか。
キャラクターの向きも変更する
単に横に移動できる様にするだけではなくて、キャラクターの向きも変更しましょう。
上記の場合だと常に右方向だけを向いていますが、右を移動する時は右を向いて、左に移動する時は左を向くようにしたいですよね。
この修正は非常に簡単です。Fixedupdateの部分だけ変更をします。
左右に移動する場合に以下コードを追加すればOKです。
右の場合:transform.localScale = new Vector3(1,1,1);
左の場合:transform.localScale = new Vector3(-1,1,1);
察しが付くかもしれませんが、localScaleのx軸を-1にするとキャラクターがx軸の逆を向きます。元々が右向き(x = 1)ですが左移動の時は左を向く(x = -1)とすればOKです。
■C#スクリプト
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
void FixedUpdate() { //待機 if ( x_val == 0) { speed = 0; } //右に移動 else if ( x_val > 0) { speed = inputSpeed; //右方向を向く transform.localScale = new Vector3(1,1,1); } //左に移動 else if ( x_val < 0) { speed = inputSpeed * -1; //左方向を向く transform.localScale = new Vector3(-1,1,1); } // キャラクターを移動 Vextor2(x軸スピード、y軸スピード(元のまま)) rb2d.velocity = new Vector2(speed, rb2d.velocity.y); } |
実行をしてみると以下の様な挙動になります。
まとめ
今回は2Dの横スクロールアクションでプレイヤーキャラクターの移動を実装してみました。
もう一度おさらいをしておきましょう。
お伝えしたのは以下の流れになります。
- アセット(マップやキャラクター)を準備する
- キャラクターを横移動できる様にする
- 想定通りに動かない場合はバグ修正を行う
- 移動に併せてキャラクターの向きも変更する
横移動できるだけでも大分ゲームらしくなってきました。
キャラクターに他のアクションも付与してあげれば2Dのプレイヤーの操作は大体実装できてしまいます。しかも、ほとんどが今回実装したコードの応用でできてしまうのです!
せっかく移動できる様になったので、キャラクター操作を楽しんでみましょう。