この記事はロックマン風2D横スクロールアクションゲームの作り方講座の第3回です。
前回の記事ではプレイヤーキャラクターであるActorオブジェクトを横移動させる処理を実装しました。今回も前回に引き続きの基本的な動作を実装していきます。
前回の記事:
今回は物理演算機能を活かしてジャンプする機能から作成してみましょう。
また、スーパーマリオなどでも実装されている長押しジャンプ機能をここで開発し、よりアクション性を高めるための工夫も同時に行っていきます。
Unityでプレイヤーキャラクターのジャンプ操作を実装しよう
全開搭載したRigidbody2Dにより、重力によって自動で下方向にキャラクターが落下する動作は実装済みです。
ジャンプに関しても、ジャンプキーが押されたタイミングで上方向の速度をRigidbodyに与えるようにすればとりあえずは実現できます。ジャンプボタンは上矢印キーとします。
まずはシンプルなジャンプ動作をActorControllerクラスに実装してみましょう。
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 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
using System.Collections; using System.Collections.Generic; using UnityEngine; /// <summary> /// アクター操作・制御クラス /// </summary> public class ActorController : MonoBehaviour { // オブジェクト・コンポーネント参照 private Rigidbody2D rigidbody2D; private SpriteRenderer spriteRenderer; // 移動関連変数 [HideInInspector] public float xSpeed; // X方向移動速度 [HideInInspector] public bool rightFacing; // 向いている方向(true.右向き false:左向き) // Start(オブジェクト有効化時に1度実行) void Start() { // コンポーネント参照取得 rigidbody2D = GetComponent<Rigidbody2D> (); spriteRenderer = GetComponent<SpriteRenderer> (); // 変数初期化 rightFacing = true; // 最初は右向き } // Update(1フレームごとに1度ずつ実行) void Update() { // 左右移動処理 MoveUpdate (); // ジャンプ入力処理 JumpUpdate (); } /// <summary> /// Updateから呼び出される左右移動入力処理 /// </summary> private void MoveUpdate () { // X方向移動入力 if (Input.GetKey (KeyCode.RightArrow)) {// 右方向の移動入力 // X方向移動速度をプラスに設定 xSpeed = 6.0f; // 右向きフラグon rightFacing = true; // スプライトを通常の向きで表示 spriteRenderer.flipX = false; } else if (Input.GetKey (KeyCode.LeftArrow)) {// 左方向の移動入力 // X方向移動速度をマイナスに設定 xSpeed = -6.0f; // 右向きフラグoff rightFacing = false; // スプライトを左右反転した向きで表示 spriteRenderer.flipX = true; } else {// 入力なし // X方向の移動を停止 xSpeed = 0.0f; } } /// <summary> /// Updateから呼び出されるジャンプ入力処理 /// </summary> private void JumpUpdate () { // ジャンプ操作 if (Input.GetKeyDown (KeyCode.UpArrow)) {// ジャンプ開始 // ジャンプ力を計算 float jumpPower = 10.0f; // ジャンプ力を適用 rigidbody2D.velocity = new Vector2 (rigidbody2D.velocity.x, jumpPower); } } // FixedUpdate(一定時間ごとに1度ずつ実行・物理演算用) private void FixedUpdate () { // 移動速度ベクトルを現在値から取得 Vector2 velocity = rigidbody2D.velocity; // X方向の速度を入力から決定 velocity.x = xSpeed; // 計算した移動速度ベクトルをRigidbody2Dに反映 rigidbody2D.velocity = velocity; } } |
- 物理演算を行うオブジェクトの移動速度はRigidbody2D.velocityがベクトルで管理しています。
- ジャンプ力の数値は今回スクリプト内に直接記入しています。このような数字はマジックナンバーと呼ばれ、あちこちに書いてしまうとスクリプトを管理しにくくなるため非推奨です。
今回の講座では今後も解説とコード短縮のためにマジックナンバーを多用しますが、余裕があれば各自で定数を定義して置き換えたり、Inspectorから入力できるようにしたり、外部ファイルから読み込むような形式の実装にチャレンジしてみてください。
これでジャンプ入力を判定し、入力があれば上方向に速度をセットする処理が出来ました。
しかしジャンプ力は均一であり、更に空中でも何度でもジャンプが出来てしまう問題が発生しています。
キャラクターの接地判定を実装して空中ジャンプを制限しよう
まずは空中で何度もジャンプできてしまう問題を解決しましょう。
空中でジャンプできなくするためには、「今プレイヤーキャラクターが地上にいるかどうか」の判定を毎フレーム行えるようにする必要があります。
接地判定の手段はいくつかあり、例えばActorオブジェクトの真下にあるオブジェクトの情報を直接取得する(Raycast)方法などもありますが、今回はよりシンプルにBoxCollider2Dを使用した方法で実装します。
ではまず接地判定用のオブジェクトから作成します。
Actorオブジェクトの子オブジェクトとしてGroundSensorオブジェクトを作成しましょう。このオブジェクトが持つBoxCollider2Dによる当たり判定で地面との接触を調べます。
子オブジェクトを作成する時はHierarchyビューでの操作が手っ取り早いです。まずは親であるActorオブジェクトを選択して右クリック→[Create Empty]を選択します。
このCreate Emptyは空オブジェクトを作成するコマンドであり、Spriteオブジェクトと違ってSpriteRendererコンポーネントを初期で持ちません。(よってゲーム画面に表示されません)
表示はされませんが、Actorオブジェクトの子にあるためActorオブジェクトが移動を行えばそれに合わせてGroundSensorもついてくる形になります。
- オブジェクトやコンポーネントへの編集はテストプレイ実行中に行ってしまうとテストプレイ終了時に全て元に戻ってしまいます。注意しましょう
それではGroundSensorオブジェクトに地面との接触を判定するBoxCollider2Dをアタッチしましょう。Inspector画面でAdd Componentを押してBoxCollider2Dを選択します。
判定範囲としてはアクターよりも少し下側にはみ出すくらいが良いです。左右の幅もアクターより少し細いくらいが好ましいです。(幅が大きすぎると壁に触れただけでも接地判定になります)
今回はOffsetを(0.16, -1.835)、Sizeを(2, 0.1)にセットしました。もしActor側の当たり判定の大きさを独自に変えているのならこちらの大きさも調整しなおす必要があります。
さらに、この判定はあくまで地面との接触を検知する判定ですので、GroundSensorオブジェクト自体が他のオブジェクトとぶつかったりする必要がありません。物理演算を行わないようにするため「Is Trigger」パラメータはオンにしておきましょう。
接地判定クラスとなるC#スクリプトを作成
まだTrigger状態のBoxCollider2Dが存在するだけの状態なので、地面との接触のみを検出するために新規クラスとしてScripts > Actorフォルダの中にActorGroundSensorを作成します。
これによってActorSpriteクラスが正常に動作するようになり、テストプレイをすれば歩行時にスプライトが更新されるアニメーションが実現できていることがわかります。
まとめ
これでプレイヤーキャラクターに最低限必要な移動操作の実装が完了しました。今後も細かい機能追加をしていくこともありますが今回までに開発した機能がベースとなっていきます。
次回からはついにアクションゲームのマップステージ制作に入っていきます。一気に画面がアクションゲームらしくなっていくので楽しんでやっていきましょう!
次の記事:
コメント