見出し画像

アセットのパワーで初めてのゲームをつくった話

こんにちは。「Unityアセット真夏のアドベントカレンダー 2020」の28日目の記事になります。

背景

私はメディア系の会社でプロダクト設計の仕事をしています。業務でコードは書いてませんが、ウェブエンジニアとしての経験は結構あります。

会社の制度で半年に一度休暇をとれるのですが、この休暇では毎回、普段あまりできないプログラミングをエンジョイすることにしています。

今回はUnityでスマホ向けゲームをつくってみることにしました。

アセット頼りという開発方針

ゲームの開発に際して、最初に決めたことが以下です。

「ゲーム本編の開発に集中する」&「8月中にストアで公開する」

今回つくるのはスマホ向けゲームなので、ストアでの公開をひとまずのゴールとしました。限られた期間での開発になるので、大事な部分の開発に集中する必要があります。

画像13

ゲーム本編(ゲーム固有のロジックの部分)はしっかり書きたいが、それ以外の部分(汎用的な解決手段があるもの)については、できるだけラクしたい、と考えました。

そこでアセットの力に頼りまくることにしました。困ったらアセット。つまったらアセット。気がつけばアセット。

Unityもゲーム開発もわからないことだらけで始めたのですが、アセットストアを眺めていると、このアセットを使えばあれができそうこれができそうと勇気と希望をもらえ、モチベーション向上にもつながりました。

以下開発中のお困りポイントとそれを解決してくれたアセットをあわせてご紹介します。

円が描きたい! → Shaper2D

今回つくるゲームには「敵を狙ってショットを撃つ」という要素があります。操作を補助する画面UIとして、タップしている場所を示す円を描きたい、と思いました。
そこで出てきたのが「円の描き方がわからない」という切なくなるようなお悩み。調べてみたらLineRendererで円を描けるようなのですが、今回は線が太くて更に半透明の円を描く必要があり、LineRendererによる処理では円の始点と終点をつなげる部分が(自分がちょっと試した範囲では)キレイに描画できませんでした。

「Shaper 2D」は、さまざまな形を描画することができるアセットです。円、扇、三角、四角から何角形でも自由自在です。

使い方としては、ヒエラルキーを右クリック→2D Object→Shaper 2Dでオブジェクトを登録します。

画像9

インスペクタで各種設定を行えます。Sector Countで形状を指定します。3で三角形、4で四角形、という感じです。またArc Degreesで角度を指定することで扇形をつくることができます。

画像6

もちろんスクリプトで自由に制御できます。

Shaper2D s2d = obj.GetComponent<Shaper2D>();

// 円の角度
s2d.arcDegrees = arcDegrees;

// 回転の角度
s2d.rotation = degree + 180f - (arcDegrees / 2)

// 内径と外径
s2d.innerRadius = 10;
s2d.outerRadius = 100;

画像4

無事、半透明の円をキレイに描画できました。

ついでに、ゲームスタート時の演出もこのアセットで作成しました。タイトルからシーン遷移後、星のかたちが広がってゲームがスタートする、というものです。

画像4

こちらの実装としては、「Shaper 2D」で画面を覆う巨大な星を描いて、Inner Radiusをゼロから徐々にOuter Radiusの値まで大きくする、という手段をとりました。

Starrinesというプロパティによってギザギザのかたちをつくることができます。☆のかたちをつくるには、十角形(Sector Count=10)をつくり、Starrinesの値をいじってギザギザをつくります。

画像7

そうしてつくった星形のオブジェクトで画面を覆い、「DOTween」でinnerRadiusの値を徐々に大きくすることで、オブジェクトの下にある画面がだんだんと表示されるようにしました。

Shaper2D s2d = this.GetComponent<Shaper2D>();
DOTween.To(
    () => s2d.innerRadius,
    value => s2d.innerRadius = value,
    s2d.outerRadius,
    duration
).SetEase(Ease.InExpo);

余談)「DOTween」はアニメーション処理ではもちろん、遅延実行など幅広く活躍してくれました。また、Unity本を読みながら最初にインストールしたアセットであり、アセットというものを使えば手軽にすごい機能が実現できるんだーとアセットのすごさを思い知るきっかけになったもので、個人的に思い入れのあるアセットです。紹介記事もたくさん書かれてて大人気ですね(今回のアドカレでも、ゆーじさんが記事を書かれています)。

仮想コントローラーを使いたい! → Joystick Pack

というわけで狙いをつけるUIはできたのですが、移動用のUIもつくる必要があります。「Shaper2D」を利用して自分でつくってみようかと一瞬考えましたが、余計なことはせず素直にアセットに頼ることにしました。そこでみつけたのが「Joystick Pack」です。

使い方はとても簡単で、4種類のジョイスティックの中から好きな種類のPrefabをシーンに登録するだけです。

ジョイスティックの種類は以下の通りです。
・Fixed Joystick ・・・ 場所固定
・Variable Joystick ・・・ 場所固定で、領域外のタップにも反応
・Floating Joystick ・・・ タップした場所に表示される
・Dynamic Joystick ・・・ タップした場所に表示され、指の動きに追従する

画像6

今回のゲームの操作方法は「左右にフリックで移動、下にフリックで狙いモードになる」という少し変わったものです。
フリックする方向によって操作の種類が変わるので、UI表現もそれに応じて分岐させたいと考えました。

Dynamic Joystickをベースに以下のような使い方をしました。
・画面のどこをタップしてもJoystickが表示され、指の動きに追従する(Dynamic Joystick標準の挙動)
・左右のフリック(移動)中には場合にはY軸だけ固定する(AxisOptionというプロパティで有効にするXY軸を指定できる。Dynamic Joystickの場合には追従方向もそれに従う)
・下方向のフリック(狙い)中は位置を固定する(それらしきオプションはないが、追従の閾値を指定できるのでそれを大きく指定することで実質移動が発生しないようにした)

この「Joystick Pack」はとてもカスタマイズしやすくて、思ったようなUIにすることができました。
画面をタップすると、初期状態のジョイスティックが表示され、上下左右の方向に反応することがわかります。そこから左右に動かすとY軸がロックされた移動モードになり、下に動かすと円形で360度のコントロールを示唆する狙いモードにUIが変化します。

画像4


ちなみに「Shaper 2D」も組み合わせて使ってみました(ちょっと魔改造感)。

効率よくデバッグしたい! → SRDebugger

開発効率を上げるという意味において、今回すごく活躍してくれたのがこの「SRDebugger」です。

このアセットを使うと、ゲーム画面でもコンソールを利用することができる他、簡易的なパフォーマンスプロファイラを利用したり、デバッグ用の機能を任意で追加することができます。

実機でログを確認できるのはもちろん、自作のデバッグ機能を組み込めるのがめちゃめちゃ便利です。

画像9

たとえば敵の出現率を変えたり、移動速度を変えたり、ショットの挙動を変えたりなど、動かしながら色々試して調整を行えます。実機でプレイしながら「この値をいじったらもっと面白くなりそうだから試してみよう、ポチっとな」ということができます。

利用方法としては「SRDebugger」が用意しているパーシャルクラスSROptionsの一部としてプロパティやメソッドを定義するだけです。
ドキュメントによると、SROptions.Debug.cs や SROptions.Gameplay.cs など分類ごとにファイルを分けることが推奨されています。

プロパティを定義すると型に応じたUIが追加され、直感的に利用できます(boolだとオンオフのトグルになる、intだと数値入力欄になる、など)。
メソッドはボタンとして表現され、ワンタップで呼び出すことができます。

プロパティ定義の例:

// SROptionsのパーシャルクラスとして定義する
public partial class SROptions
{
    // Attributeでオプション指定が可能
    [Category("DebugInfo")]
    // プロパティを定義すると、型に応じたUIで表現される(例:boolならチェックボックス)
    public bool DebugInfo
    {
        get {
            return PlayerPrefs.GetInt(KeyDebugInfo, 0) == 1;
        }
        set {
            PlayerPrefs.SetInt(KeyDebugInfo, value ? 1 : 0);
        }
    }
}

メソッド定義の例:

public partial class SROptions
{
    [Category("Debug")]
    // public && 返り値がvoid && 引数がない メソッドを定義すると、ボタンになる
    public void IncreaseLife()
    {
        Player.Instance.IncreaseLife();
    }   
}

こんなかたちで、簡単に任意のデバッグ機能を仕込むことができます。

効率よくログを見たい! → Console Pro 

今回利用したアセットの中には、インストール後にWarningが出るものがありました。ログに不要なWarningが表示されると、本来みるべきものが埋もれてしまったりして、開発の効率が落ちます。

必要なログ以外は非表示にしたい、と思って調べていたら、コンソールの機能を強化してくれるアセットがあったので導入してみました。

この「Editor Console Pro」を使うと、任意の条件(ログの文字列、ファイル名など)を指定してフィルタリングを行うことが可能です。

例えば以下のように、導入したアセットでWarningが発生していたとします。

画像14

「Editor Console Pro」の設定画面で、無視条件を設定します。

画像12

結果、指定したログを非表示にすることができました。

画像11

このアセットには他にもログ出力周辺のソースコード表示機能や色分け、検索など便利な機能がついています。

ファイルサイズの減らし方がわからない! → Build Report Tool

ビルドして書き出されたファイルのサイズをみてみると、思いのほか大きくて、200MBくらいありました。なんかデカい気がするけどどうしていいかよくわからない、と思っていたときにみつけたのがこのアセットです。

「Build Report Tool」を使うと、ビルドにおいてどの素材がどのくらいの容量を使っているのかを簡単に把握することができます。

画像3

ビルドに含まれるファイルをサイズのランキング形式で示してくれるので、とても効率的に改善を行うことができます。私の場合は画像ファイルの圧縮、音楽ファイルの形式変更と使用曲数の削減によってだいぶサイズを改善できました。

また、とあるアセットがResourcesというUnityの予約フォルダ名を使っており、その下にある多数の画像ファイルが無駄にビルドに含まれてしまっていたことにもこのツールのおかげで気づけました。

なお、ビルド後のファイルサイズには関係ありませんが、使われていないファイルも確認できるので、不要なファイルの掃除にも役立てることができます。

設定も細かく行えます。デフォルト設定では、ビルド後に自動的に起動してレポートを表示するようになっています。レポート結果を保存しておくことなども可能です。

画像14

Unityのビルド後ってそのままXcodeでのビルドを行って手持ち無沙汰だったりするので、このレポートを見てさくっと概要を把握できるのはわりと有意義でした。

最後に

というわけで、各種アセットのパワーによって、ゲーム本編の開発に集中することができ、とても捗りました。

本記事で紹介したのは、主に初心者的な問題解決文脈でのアセットになりますが、他にもパーティクルやUIや画面効果などたくさんのアセットのお世話になりました。アセット作者の方々には感謝&リスペクトです。

今回つくったゲームはこちらになります。なんとかストア公開までこぎつけましたので、よかったら遊んでもらえると嬉しいです。

iOS版

Android版

--

明日のアドベントカレンダーはひつじさんの「Unityで簡単モデリング! UModeler」です。引き続きよろしくお願いします。

この記事が気に入ったらサポートをしてみませんか?