うまげーむのゲームブログ

ゲームの情報を主に投稿します。

【Unity】ソースコードコピペ可能!マリオ風2Dアクションゲームの作り方 #8 パーティクル・コントローラー対応・エクスポート

はじめに

どうも。

実はこのUnity2Dアクションゲーム制作シリーズは今回で終了です。Unity関連の記事についての今後の予定はこの記事の最後に書いておきます。

今回はUnityのパーティクルシステム、クリア判定の作成、コントローラー操作への対応、ゲームのエクスポートをやります。

前回:

www.umagame.info

パーティクルの追加

マテリアルの追加

まず、第六回で追加した破壊可能ブロックの破壊時のエフェクトを追加します。

エフェクト用のスプライトを追加します。いつも通りテクスチャの設定を行います。(単位毎のピクセル数、フィルターモード、圧縮を変更)

マテリアル用のフォルダを作成します。パーティクルに画像を使用する場合、画像ファイルのままでは使えずマテリアルというのを作らないといけません。

Materialsフォルダ内で右クリック→作成→「マテリアル」をクリックして、新しくマテリアルを作成します。

名前は長いですがBricksParticle1Materialにします。(第六回で破壊可能ブロックを二種類作ったので、1と2に分けます)

作ったマテリアルのインスペクター上部の「Shader」を、上画像のように「Alpha Blended」に設定します。(Legacy Shaders→Particles→Alpha Blended)

その後、「Particle Texture」に用意した画像ファイルを設定します。ちなみに今回は上画像右下に表示されている4x4の画像を用意しました。

「Tint Color」を上のように設定します。V(明度)を75ぐらいにすると元画像と同じ明るさになります。

同様の手順で、BreakableBricks2用のマテリアルも用意します。

パーティクルシステムの作成

パーティクルを作ります。

ヒエラルキーで右クリック→「エフェクト」→「パーティクルシステム」をクリックします。名前はBricksParticle1としました。

これがパーティクルシステムの設定画面(インスペクター)です。初めて触る方は設定項目が多すぎて何がなんだか...と感じるかもしれませんが意外と簡単です。

ですが、それぞれを解説するのは時間がかかるので割愛します。

とりあえず、今回は以下のように設定しました。

  • ループ→チェックなし
  • 開始時の速度→9~7のうちランダム(設定方法は後ほど説明)
  • 開始時のサイズ→0.2
  • 重力ソース→2D 物理演算
  • 重力モディファイア→3
  • ゲーム開始時に再生→チェックなし

「開始時の速度」のところは、入力欄の右にある三角をクリックして「2つの値間でランダム」をクリックすればOKです。

「放出」タブ:

  • 時間ごとの率→0
  • +ボタンをクリックして数を12に設定

「形状」タブ:

  • 角度→15
  • 半径→0.5

そして、「レンダー」タブの「マテリアル」に先程作ったマテリアルを適用します。

これでパーティクルは完成です。

プレハブの作成・スクリプトの編集

作成したパーティクルを、プレハブとして保存します。第六回(多分)で作ったPrefabsフォルダにBricksParticle1をドラッグアンドドロップします。

同様に、茶色レンガのパーティクル(BricksParticle2)も作ってプレハブにします。(コピーしてマテリアルを変えるだけです)

プレハブを作ったら、シーン内に存在するパーティクルは削除してもらって構いません。

第六回では破壊可能ブロックの判定としてタグを使っていましたが、それだけだとレンガの色の判別が出来ないので仕方なくスクリプトを使います。

計画性のなさが露呈してしまいました。

スクリプトは以下のようにします。

public class BreakableBricks : MonoBehaviour
{
    public int ID;
}

public int変数のIDを持っているだけです。タグとほとんど変わらないです。

BreakableBricks1と2のタグを「Untagged」(タグ無し)に設定します。このタグはもう使わないので、削除してもらって構いません。

そして、BreakableBricks1・2にこのスクリプトを適用してIDを設定します。

その後、Player.cs(プレイヤーのスクリプト)を以下のように編集します。

public class Player : MonoBehaviour
{
    public ParticleSystem BrickParticle1;
    public ParticleSystem BrickParticle2;

    private void OnCollisionEnter2D(Collision2D collision)
    {
        GameObject obj = collision.gameObject;

        //Breakable
        BoxCollider2D c = GetComponent<BoxCollider2D>();
        if (obj.GetComponent<BreakableBricks>() != null && rb.velocity.y == 0 && //タグではなくBreakableBricksスクリプトで判定するように
            obj.transform.position.y - obj.GetComponent<Collider2D>().bounds.size.y / 2 >= this.transform.position.y)
        {
            GameObject.Destroy(collision.gameObject);
            BreakSE.Play();
            if (obj.GetComponent<BreakableBricks>().ID == 1) //IDによってパーティクルを変える
            {
                Instantiate(BrickParticle1, obj.transform.position, Quaternion.identity).GetComponent<ParticleSystem>().Play(); //パーティクルを生成+再生
            }
            else if(obj.GetComponent<BreakableBricks>().ID == 2)
            {
                Instantiate(BrickParticle2, obj.transform.position, Quaternion.identity).GetComponent<ParticleSystem>().Play();
            }
        }
    }
}

コメントをつけたところに変更を施しています。

タグを使って衝突先のオブジェクトがBreakableBricksかどうかを判定していた所を、スクリプトによって判定を行うようにして、

そのIDによって生成するパーティクルを変えるようにしてあります。生成はGameObject.Instatiateを使っています。

Playerオブジェクトのインスペクターから、パーティクルのオブジェクトを設定します。

これで、ブロックの色に対応したパーティクルが出るようになりました。

ステージクリア判定の作成

旗のオブジェクトの作成

次に、ゴール(クリア判定)を作ります。

旗を追加して、旗に触れるとクリアになるようにします。旗のテクスチャをインポートして設定をします。

右クリック→2D オブジェクト→スプライト→正方形で新しくオブジェクトを作成します。

名前はFragにします。

インスペクターから「Sprite Renderer」の「スプライト」に画像ファイルを設定します。

「Box Collider 2D」を追加して、「コライダーの編集」で当たり判定を設定して「トリガーにする」にチェックを入れます。

スクリプト内での旗の判別のためにタグを追加します。タグ→タグを追加をクリック。

新しく「Frag」という名前のタグを追加して、Fragオブジェクトに適用します。

スクリプトの編集

Player.csを編集します。

//Player.cs
public class Player : MonoBehaviour
{

    public TextMeshProUGUI GameoverText;

    private void OnCollisionEnter2D(Collision2D collision)
    {
        GameObject obj = collision.gameObject;

        //InstaDeath
        if (obj.CompareTag("InstaDeath"))
        {
            GameoverPanel.SetActive(true);
            GameoverText.text = "Game Over!"; //テキスト変更
            Time.timeScale = 0;
        }
    }
    private void OnTriggerEnter2D(Collider2D collision)
    {
        GameObject obj = collision.gameObject;

        //Frag
        if (obj.CompareTag("Frag"))
        {
            GameoverPanel.SetActive(true);
            GameoverText.text = "Stage Completed!"; //テキスト変更
            Time.timeScale = 0;
        }
    }
}

OnTriggerEnter2Dに旗に触れたときの処理を追加しています。

クリアしたときに表示される画面は、第五回で追加したゲームオーバー画面(GameoverPanel)を流用しています。

そのため、GameoverPanel内のテキスト(GameoverText)の文字列をデス時とクリア時で変更するようにしています。

プレイヤーのインスペクターから、テキストのオブジェクトを設定します。

これで、旗に触れるとこのようにクリア画面が表示されるようになりました。

コントローラー操作への対応

エクスポートする前に、コントローラー(ゲームパッド)でゲームをプレイできるようにします。

編集→プロジェクト設定から、

入力マネージャーを開いて、Dash・Escape・Jumpの「正方向ボタン(副)」にそれぞれ対応させたいコントローラーのボタンの名前(「joystick button #」、#に数字)を入力します。

どの数字がどのボタンに対応しているかは、調べればいくつか出てきます。

https://discussions.unity.com/t/xbox-one-controller-mapping-solved/187077 より

これは一例で、Xboxのコントローラーの場合です。

この設定で、ダッシュ・ポーズ画面の表示・ジャンプをコントローラーのボタンで行えるようになりました。

その後キーボードでの操作に使っていた軸(第三回参照)とは違う軸として、新しく「Horizontal」という軸を用意してこのように設定します。

「無効」という項目はデッドゾーンです。小さくしすぎるとコントローラーを触ってなくても動くようになってしまいます。

感度は好きなようにしてもらって構いません。(今回の場合、第三回で水平軸をGetAxisRawで取得しているので感度を変えてもあまり意味はないです)

これで、左スティックで移動ができるようになりました。

そして、上で設定した軸とは違う軸として新しく「Horizontal」を用意して(3つ目)、上のように設定します。

これで十字キーによる左右移動が実装できました。

スティックまたは十字キーの操作は「タイプ」を「ジョイスティック軸」にしていないと反応しないことに注意してください。

今回は尺の都合上やっていませんが、前回(第七回)で追加したボタンの操作をコントローラーでできるようにすることも可能です。

エクスポート

最後に、ゲームのエクスポート(exeファイルとして実行ファイルを作成)をします。

まず、編集→プロジェクト設定の、

「プレイヤー」タブからゲーム名(プロダクト名)、バージョン、アイコンなどを設定します。今回はデフォルトのままにしておきます。

その後、ファイル→ビルド設定から、

「ビルドに含まれるシーン」のタイトルのシーン(TitleScene)が一番上になっていることを確認して、「ビルド」ボタンを押します。

保存するフォルダを指定します。指定したフォルダの直下にいくつかのファイルが生成されます。

これで、エクスポートは完了です。exeファイルを開くとゲームが起動します。

今回の進捗 / ソースコード

今回はパーティクルの追加、クリア判定の作成、コントローラー操作への対応、ゲームのエクスポートを行いました。

一応この動画は、エクスポートしたゲームをGeForce Experienceの録画機能を使って録画しています。(特に設定しなくても、GeForce Experienceにゲームとして認識されました)

ソースコードこちらからアクセスできます。(TutorialGame/8にあります)

さいごに

今回は以上となります。

最初に言った通りこのUnity2Dアクションゲーム制作シリーズは今回で終了です。

他にも色々紹介したいやつ(複数ステージ・ステージ選択画面、動く床ギミック、複数レイヤーの背景などなど...)があったんですが、それらを全て紹介していると一生終わらない気がしたので、

ソースコードコピペ可能!マリオ風2Dアクションゲームの作り方」シリーズとしては一旦ここで終わらせて、紹介したいギミック等の実装は単発の記事として作ることにします。

今回作ったゲームは一応まともに遊べるレベルには改良を続ける予定なので、その過程も報告できればなとも思っています。

シューティングゲームなどの他のジャンルのゲームの作り方も一応やる予定です。それがいつになるかはわかりませんが。

とりあえず、私はシリーズ物の記事を続けるのが苦手なので早めに終わらせることが出来てよかったです。

それでは。