エディトリアルデザイナーのアプリ制作日記

Unityで遊ぶ個人開発者のメモ書き

Unityアクションゲーム制作記 その11 アプリサイズで七転八倒

 日々、適当仕様のバグ取りに追われながら制作していたとき、ふと唐突にアプリサイズのことが頭をよぎりました。

 アプリの省サイズ化は、もう少しやりたいことを突っ込んでからと思っていたのですが、試験勉強のときに部屋の掃除がはかどるように、煮詰まっていたり、やらなければならないことがあるときに限って、本筋とは違うことが気になって仕方ない状態になり……少しはスリムにしておいたほうがいいだろうと、結局手をつけることになりました。 

 まずは、アプリの中身がどうなっているのかがどうなっているのか調べなきゃ、と見つけたのがここ↓。

soyliquid.blogspot.jp

 ごちゃごちゃとアセットを突っ込みまくっているので、何が出るかなーと思っていたら、使いもしない9MのWAVデータ(テスト用に初期状態として突っ込んでいたファイル。すぐ書き換えられて実際には使用されることはない)やら、初期の頃にメインタイトルの背景として使っていた8Mくらいの画像ファイル(放置していたオブジェクトにアタッチされてた)などが、ログにゴロゴロ出てきました……。これらを整理しながら、テクスチャや音楽データなどのサイズを変更したりして、だいたい60Mあたりに落ち着かせたのですが、ある日、2つのシーンを行き来できるようになったタイミングで、問題が起きました。

f:id:hamazakifactory:20161004135218j:plain

 正確には問題というか気付いたことが1点、内訳の中になにやら突出してクソでかいサイズのものがある……。巨大なLevelsという項目の中身はなんなのか、しばし検索してみるも、どうにもよくわからず。名称からゲームレベル(=シーン)なのかなとあたりをつけて、試しにステージのオブジェクトを置いている2つのシーンを外してビルド。すると……

f:id:hamazakifactory:20161004140304j:plain

すげー減ってる!

f:id:hamazakifactory:20161004140551j:plain

f:id:hamazakifactory:20161004140605j:plain

 ちなみに2つのシーンに置いていたオブジェクトはコレ↑です。いまさらながら中身を確認していくと、パーツ1つで、最大15Kの頂点、9Kの面で構成されていて、FBXのサイズが200K〜300Kくらい。これが50個ほど、1つのシーンに置かれていたのですから、サイズがでかくなるのは当然といえば当然。なのですが、「このアセットかっこいいよねー、モバイルでも動くから大丈夫かなー」と頭の悪い子状態で購入したときには、こんなことになろうとは全く想像していませんでした。

f:id:hamazakifactory:20161004143057j:plain

f:id:hamazakifactory:20161004143123j:plain

 シーンを1個にしてオブジェクト群をON/OFFしたり、メッシュインポートの圧縮設定を変えたり、試しにオブジェクトを増やしてみたり、いろいろ条件を変えて見たところ、シーンに生成されたオブジェクト(+α)が、ビルドしたときにがっつり含まれていると判明。知らないって怖い……。

 AssetBundleを利用して、必要に応じてシーン(ステージデータ)を読み込むようにすればいいのでしょうが(1シーンを数Mまで圧縮することもできそう、ふつーのゲームはそうしているんだろうなあ、きっと)、AssetBundleを使うとなると、当然シーンデータをやりくりするためのモノを作らなきゃならないだろうし、そもそも現在のUnityエディタの上でステージを作成する方法自体も手間のかかるもの。パーツの大きさだけが問題なら利用するアセットのサイズが小さいものに変えればいいともいえますが、これもすぐに物理的限界(アプリサイズ100M)を迎えそうで、根本的な解決になりません。設計段階できっちり仕様を決めておく、という当たり前のことをしていなかったツケがきたということでした。

 やれるだろうと思っていたことが無理と分かり、折れかけている心をなんとか騙しつつ、なんとか現状でステージを増やせないかアレコレ調べたりしましたが、解決策は見つからず。手間をあまりかけずにいい方法はないか、と思い詰めていたときに降ってきた言葉が「自動生成」でした。

 ダンジョン自体の自動生成までやらなくても、↓こんな感じで、

f:id:hamazakifactory:20161004150806j:plain

スプレッドシートに書かれたマップ情報からダンジョンの生成をシーンにできないか……しばし悩むこと数日。うん、これならなんとかなるかもしれない。という方法が見つかったので、できるかどうか……いや、できるよにするためにがんばっていこう、きっとなんとかなる!

 

 

Unityアクションゲーム制作記 その10 ダンジョンを走る!

 

youtu.be

 終わらない敵ロジックの実装&バグ取りをしつつ、遠隔系の攻撃を実装し、なんとか、ダンジョン内を走り回れるまでになりました! あちこちバグだらけですが、同じことばかりやっていて気が滅入っていたので、敵ロジックはある程度見切りをつけて放置。やりたいことを優先して詰め込むように作業を進めました。

 アセットストアにあったド派手なエフェクトを使い(↓コレとか)、

>Magical - Pro Edition

https://www.assetstore.unity3d.com/jp/#!/content/55713

扇状にオブジェクトを発射するものと、噴射タイプの二種類を実装。オブジェクトを発射するタイプは、生成したオブジェクト任せで自律行動できるように組み込むようにしました。今回このアセットを使って学んだのが、

「機能ごとに特化したコンポーネントスクリプト)をうまく組み合わせて使う」

ということでした。「Magical」では、移動するのみ、出現時にランダムの回転・位置を与えるといった単純なものから、何かに当たったら別のオブジェクトを生成するといった感じのスクリプトなどが用意され、それを必要に応じてスクリプトをアタッチしているという構成。必要な機能を組み合わせて、最小限の大きさでいろいろなものを作っていく、Unityのゲーム制作の基本というか 当たり前のことをいまさらながら体感しました。なにぶん古い時代のマイコン世代でのプログラミング経験しかないので、汎用的に使えるものを作ろうとしたときに、なんでもかんでも1つのスクリプトに詰め込んでいた始末。この辺をうまく機能を切り分けるのも、今どきの出来るプログラマーなんだろーなーと一人で納得してました。

 とりあえず使えるものは使いつつ、似たような感じで作り直していきましたが、特に問題となったのが、接触判定。アセットのままでは単純な接触判定しか行っておらず、魔法のオブジェクト同士が干渉してしまったりするので、うまくレイヤーの設定やら詳細なチェックが必要だったりするなど、自分の作っているゲームに合わせての調整は必要でした。

  ダンジョンでのゲームを進行は、

・部屋に入る

・扉が閉まる

・出てきた敵を全滅させたら扉が開く

という具合にして、敵とのバトルを中心にダンジョン内を探索する楽しみも提供できたらなーと。ダンジョン自体は、もりもりとオブジェクトを置いていき、1シーン=1階層という形にしてみました。次の階層へ移動したときは、該当シーンを読み込んでいけばOKって感じです。

f:id:hamazakifactory:20160928180559j:plain

 ここでハマったのが、扉の初期状態を作るところ。鍵のかかっている扉は閉じたままにしておき、それ以外は開けておくというふうにしていたのですが、エディタ上ではちゃんと動いているのに、スマホの実機上では開いているはずの扉が閉まったまま…。どうにも初期化処理がうまくいっていない。

 扉の管理は、扉オブジェクトの一つ上に置いておいた管理用のオブジェクトでまとめて管理していました。実機で動かないものをチェックしていくのは面倒だなぁと思いながら丁寧に追いかけていくと、どうやら管理している扉のオブジェクトの生成が初期化処理のタイミングで間に合っていない模様。管理用のオブジェクトが扉の初期化処理を行おうとしたタイミングで、初期化したい扉のオブジェクト自体がないわけですから、初期化されるわけがない。

 要は、シーンデータが読み込まれて実際にオブジェクトが生成される順番は決まっていないという大前提を、すっかり忘れていた(というより考えもしなかった)というものでした。結局、扉自身に初期化を行わせるように変更してなんとか解決しましたが、ごくごく基本的な考えなのに、いまだ慣れないなぁ……ちゃんと順番を考えた安全な作りを心がけないといけないのね……と反省。

 なんとかダンジョン内を探索っぽい動きもできるようになったところで、セーブデータはどうするんだ? とか、ギミックも多少入れないプレイヤーは飽きるぞ? とか、報酬アイテムはどうするの? などといった根本的な問題が大噴出……この辺は、階層移動の仕組みを組み込んだあとにちゃんと考えよう、きっと考えるだろう。うん。

Unityアクションゲーム制作記 その9 コンボ追加〜

 ここ1ヶ月くらい、ずっと細かい調整と何か機能を追加するたびに起こるエンバグデバッグ作業の繰り返し…。ようやく、今度こそ攻撃コンボはコレで! というところまでこぎつけました(あちこちバグはアリだけど)。

youtu.be

 これまでに用意していた攻撃コンボは、連打とチャージ(押しっぱなし)の2種類でした。そこにタイミングを見て攻撃する目押し系のコンボを追加したのですが、これがまた難産というか、適当に仕様も決めずにやってきた継ぎ足し継ぎ足しのフラグ管理のツケが回ってきたというか……あっちこっちで不具合を引き起こして、ホント対応に苦慮しました(泣)。しかも片手1タップの操作だけで、3つのコンボを気持ち良く使い分けなければ意味がないので、その辺りの調整もしんどかった。

 で、最終的にまとまったのが以下の3つの連続攻撃です。

連打攻撃>特徴:前方への範囲攻撃が強い

 操作:とにかく連打しているだけで、連続攻撃を繰り出してくれる

コンビネーション攻撃>特徴:360度、全方位への攻撃が可能

 操作:攻撃マーカー(赤いもやもや)の出るタイミングにタップすると全方位への連続攻撃を繰り出してくれる。他のタイミングでタップしてしまうと攻撃は繋がらない

チャージ攻撃>特徴:突進による強力な吹き飛ばし攻撃で敵を砕く

 操作:ダブルタップ後、押しっぱなしにしているとエフェクトが発生。最大まで大きくなったあと、画面から話すと現在向いている方向へ突進する

 コンビネーション攻撃の受付時間には、ド派手なエフェクトを用意して、タイミングがわかる用意もしてあります。ただ、受付時間自体が短いので、見てから押しても間に合わないこともあるのかも…ここは体でタイミングを覚えてもらうしかないかなと。

f:id:hamazakifactory:20160901180034j:plain

 とりあえず、これでなんとか遊びやすくまとまったはず! しかしテストプレイしている自分が慣れてしまっているだけの可能性もあり、ちゃんとできているかどうかは判断に苦しむところですけど。

 ま、これからバグを潰しつつ細かい演出面での課題を拾いながら、ゲームとして面白くするための方法を探っていきます(いまさらだけど)。とにかく前に進めて頑張っていかないとだ。うん。

Unityアクションゲーム制作記 その8 メニュー周り

 やることはいっぱい、ゲームの中身を作り込まなくてはいけないのですが、ここのところは中身とは関係のないメニュー周りをいじり倒してました。縦横自由に持ち替えられるようにするためのメニューはどうすればいいのかなーと、ぼんやり考えながら行き着いた先がコレ⬇︎

youtu.be

 ぶっちゃけていうと、メニューとして置くパーツ(ボタンやイメージ)それぞれに縦・横のレイアウト情報(表示の位置座標)を持たせ、切り替わったらそれぞれの位置へDOTweenを使って移動させるだけという力技。まだボロが出るときもなきにしもあらずですが、一応、さまざまな解像度の端末で、ある程度見苦しくない程度でレイアウトを維持できるような仕組みができたかなと。予想通りというか、完全自動化とかは無理でしたけど♪ あと、せっかく(?)なので背景の穴埋めにFayeちゃんを置いて、見た目だけは豪華にしてみました。他には、ゲーム中に敵へ与えたダメージ表示を入れたり、ゲームオーバー場面を作ったりしているだけで結構な時間が経過してしまいました。

 このゲーム、そもそも「わらわらと集まって来る敵をぶっ倒す」というコンセプトだけで適当に制作を進めてきたおかげて、ゲーム全体の構成をどうするかとかを考え、具体的に形にしようとすると…とにかく決めなくてはならない細部&作らなきゃいけないものが多いことに気づかされます。やっぱりゲームを作るのは大変だなぁ。楽しいけど。ということで、広げすぎた風呂敷をうまくバランスよく整えつつ、引き続きがんばっていこう。うん。

Unityアクションゲーム制作記 その7 操作系の調整&敵ロジックの組み込み

 ここのところは、敵をザクザクぶっ倒していく気持ちのいいアクションをストレスなく実現する操作性、そして倒される敵のバリエーションを追加すべく地道な作業をしていました。

youtu.be

 操作性に関しては、連打系のコンボとタメ打ち系のコンボの2つをストレスなく使い分けれるようにすることを目指しました。最初よりはずいぶんと良くなったので、ひとまず操作系はこれでいったん終了。なにかもっといい方法が思いついたら改良したいところ。

 敵は、ある一定の条件で行動を繰り返すという、簡単なロジックを実現できるようなものを目指してみました。ただ、バリエーションを作りたいので、なるべくならその行動を繰り替えす条件を個別にカスタマイズできるようにしたい。でも、いちいち敵ごとにスクリプトを書くのはどうにもきつそう。どうしよっかなーと、考えた末に……

1)敵はいくつか設定された基本行動を繰り返す

  行動時間や設定目標を達成したら次の行動へ移行するようにする

 ・敵が取りうる基本行動

  待機・索敵・移動・回避など

2)基本行動中に割り込み行動が起きたら、その割り込み行動に応じた行動へ移るようにする

 ・基本行動中に反応すべき割り込み行動

  行動終了、プレイヤーから攻撃を受けた、プレイヤーを見つけた(見失った)、

  攻撃範囲に入った(出た)、目的の場所へ移動したなど

 こんな感じで敵本体のスクリプトに基本行動を実行するメソッド群をまとめて実装することで、スクリプトを使い回し出来るようにしました。で、個別のロジックを別ファイルに記述すれば、そこそこの手間でザコ敵は回せるかなーと。とりあえず近接系の敵(片手、両手攻撃)、遠隔武器系の敵を1つ作ってみたところ、そこそこ量産できそうな感触でした。

 もちろん、決められた行動をトレースしているだけなので、障害物があれば引っかかるし、敵同士で押し合いへし合いのダンゴ状態にもすぐなったりします。要は敵自身の周りの状況判断ができていなかったりしている状態です。これはまぁ、現状どうやればいいのかまったく見えてないので、他のことを実装しつつ勉強していきます。

 ちなみに、今回、口果音として「夏恋 karen〜」で声をお願いした櫻庭彩華さんにお手伝いいただきました。声に負けないように中身も頑張らなくては。うん。

Unityアクションゲーム制作記 その6 レーダー・BGM・効果音など追加

 ここのところは、レーダーを追加したり、BGMと効果音を入れたりと外側を固める作業に終始しました。自分にしては珍しく早い段階で音を入れてみたのですが、やっぱり音が入るといいですね(↓の映像は音が出ます)。

youtu.be

 さて本題っと、かねてより縦持ち・横持ちでのプレイをしたかったのでその辺の実装をしていきました。まずは、uGUIで画面比率を変えてもレイアウトを崩さないようにするにはどうするんだっけなーとググって見つけたのが、このページでした。

【Unity】UIを端末に合わせたサイズに調節する|ドジキャンラボ

 必要な設定は、

1)Canvas ScalarにあるUI Scale ModeをScale With Screen Sizeに変更

2)Reference Resolutionを1080x1920に設定(縦持ちの場合)

3)Matchを横持ちなら0、縦持ちなら1

以上でOK。実際の設定はこんな感じ。

f:id:hamazakifactory:20160711234642j:plain

 今回はリアルタイムに縦横を切り替えたいので、Canvasに現在どっちの向きであるかの監視スクリプトを追加します。

f:id:hamazakifactory:20160712135805j:plain

 レーダーは、プレイヤーを中心にして画面外にいる敵がどちらの方向にいるかを示すものを用意します。表示方法は、ParticleSystem.Emiitで表示する方法を選択。ヒットエフェクトのパーティクルをEmitで一度に多くのエフェクトを生成たときに、あまり重くならなかった(性能の低い端末で多くのエフェクトを一度に表示させた時、引っかるような動作がなくなる)ので、こちらでも使うことにしました。

tsubakit1.hateblo.jp

 あとは、そこそこの数の敵をバッタバッタとなぎ倒したいということで、敵の出現方法を矩形の塗りつぶしと円形のライン状に一度に出せるようにしました。

f:id:hamazakifactory:20160712140345j:plain

f:id:hamazakifactory:20160712140352j:plain

 大きさと位置を変えるだけで結構なバリエーションが出せるので、ひとまず敵の出現はこの2つをうまく使い回す方向でいきます。物足りなくなったら、追加すればいいや。

 他にもプレイヤーの死亡判定もつけたので、とりあえずゲームとしての最低限の体裁は整えられたかな。とはいえちょっと寄り道が過ぎたので、今度こそ、ほったらかしの敵の管理をちゃんとやらなきゃ…うん。

・BGMで使用したアセット

Heavy & Metal Loops

https://www.assetstore.unity3d.com/jp/#!/content/53112

 

Unityアクションゲーム制作記 その5 コンボ&攻撃リアクション概ね実装

youtu.be

 アセットに含まれた5つの攻撃モーションから、どうしたら攻撃バリエーションを増やして楽しめゲームにできるか。無い知恵を絞り出した結果が上の映像にあるような感じです。敵をガンガンぶっとばす気持ちのいいゲームになりそうな雰囲気になってきた…かな。ちなみに攻撃の流れは、

 通常攻撃>通常攻撃>通常攻撃>通常攻撃>コンボフィニッシュ攻撃

こんな感じ。この流れは自由にカスタマイズできるようにして、使いやすいコンボを目指すといった遊び方もできるようにしていきます(予定)。片手操作可能にしたいということで、タップをしていくとあらかじめセットしておいた攻撃を繰り出していくというお手軽仕様。そして複数回攻撃を繰り返し、最後に多少派手なコンボフィニッシュ攻撃で〆るという流れにしてみました。攻撃は、静止状態から発動するものと、走り状態の後に発動するものの2種類を用意しています。走りからのコンボスタートは、最初の一撃に仰け反り効果を付加したりという差別化をつける予定です。

 ちなみに、この攻撃の種類は成長によって増えていくのか、それともクエスト報酬によって増えていくのか…はたまた両方か…というのは、まだ悩み中です。

・基本のノーマル攻撃(8種類)

 1つのモーションを無理やり分割して数を増やしたたため、つながりがややおかしいものもなきにしもあらずなのが残念なところ。とはいえ、ここはこれ以上どうこうするのは厳しいので、ひとまず〆としておきます。

・攻撃が当たった時のリアクション(4種類)

 ノーリアクション:ヒットエフェクトのみ表示(敵が動き、攻撃してくる)

 仰け反り:一瞬敵の動きが止まる(敵の攻撃が止まる)

 吹き飛ばし(ノックバック):強制的にプレイヤーから敵が離される

 気絶:一定時間、敵が行動不能になる

 敵を打ち上げたり、毒のような継続的にダメージを与えるリアクションも見当してみました。しかし、3Dアクションにまともに対応できていないのと継続ダメージで勝手に敵が死ぬ状況を回避するのがめんどかったので、これはとりあえず保留。いずれ、かっこいい空中コンボとか決めたいなぁ…。

 ・コンボフィニッシュ攻撃(仮で三種類)

 まずは、回転(周囲吹き飛ばし)、突進(前方吹き飛ばし)、打ち下ろし(範囲気絶)を用意。ここはいろいろ工夫できそうなので、いずれ数を増やしていきます。

 あと、外見があまり変わってないのですが、唯一の見栄えが変わったところとしては、敵のHPゲージが付きました。

f:id:hamazakifactory:20160630232727p:plain

上のような64x8ドット、32パターンのスプライトを切り替えるという原始的な方法です。敵の数が多くなりそうだったので、単純な方法にしてみたのですが…効果があるかどうかは謎だったりします。

 いろいろ悩んだ視点に関しては「邪魔になりそうな障害物は置かない」 という方針にして、現状の見下ろしで固定し、余計なことをしないことにしました。それよりも、コンボフィニッシュ攻撃のときにカッチョイイカメラアングルに凝るとか、そういうところに注力していこうと思います。

 ということで、プレイヤーキャラに関しては一通りできたので、次は敵のアルゴリズムやら管理やらを詰めていく予定です。効率的に敵を動かし、増産できるように…したいなぁ。いったい、どういう風に作ればいいんだろうか…がんばって考えようっと。