2020/11/09
「第16回 Unity1週間ゲームジャム」に参加しました!
time 2020/08/16
今回は8月10日~16日に行われたUnity1週間ゲームジャムに参加したので、そのお話になります。
https://unityroom.com/unity1weeks/17
お題は「ふえる」でした!
かなりイメージしやすいお題で、近年のお題の中では作りやすいほうかなーと感じます。
Unity初心者の方も参加しやすいお題になったのではないでしょうか。
目次
ゲーム紹介
「あつめてたたけ!アザラシ軍団」というゲーム名で公開しています。
https://unityroom.com/games/collect_azarashi_team
アザラシとシロクマの戦い第2弾!
「アザラシの逆襲」ではアザラシが一方的にボコボコにしていましたが、今回はターン制のRPG風なシステムで、交互に殴り合う感じです。
最大の特徴は「ほかの人のアザラシを呼び出せる」こと。
アザラシは「体力」「力強さ」などのパラメータがあり、敵を倒すとレベルアップし、ゲームクリアorゲームオーバー時にステータスがバックエンド側に保存されます。
コマンドで「アザラシをふやす」を選択すると、他の人のアザラシを呼び出し、一緒に戦わせることができます。
アザラシをふやしたり回復したりしながら、全7ステージのクリアを目指します。
各日の様子
0日目
前回同様、お題発表前にプロジェクトを用意しておきます。
unity1week用にテンプレートとなるプロジェクトを用意しているので、それを整理したくらいですね。
また今回は「ユニティちゃんトゥーンシェーダーver2」 (以下UTS2) を使うので、Unity公式のリポジトリから落としてインポートしておきました。
1日目 (月曜日)
いつも通りお題について考えます。といってもすぐこうなるんですけど
「ふえる」となれば、アザラシを増やすしかないでしょう!#unity1week
— あかざらし (@akaiazarashi) August 9, 2020
しかしお題の「ふえる」はあれこれアイデアを考えやすく、すぐに方向性も決められるかと思いきや、逆に浮かびすぎて苦悩するという事態に。
また、今回は以前作った「ばくげきうさぴょん」と同じように、他の人のプレイデータを非同期で呼び出して利用する仕組みを入れようと考えていました。
悩んだ末、今まで通りのアクションゲームにしても(開発的な)面白味に欠けると判断し、小規模なターン制RPGのようなゲームを目指すことにしました。
その後は画面構成や戦闘システムのフローを考えて書き出します。
若干「間に合わないんじゃね?」と思いつつも就寝。
起きたら最低限必要なキャラクターを作ります。とりあえずアザラシ2タイプとシロクマを用意しました。
その後はひたすらロジックを作ります。細かい部分は後回しで、ゲーム画面での戦闘が一通りできることを目標にしました。
見た目はさておき、最低限戦闘と呼べるものができました。あくまで最低限。
キャラクターやエフェクトの調整を行って1日目は終了。
2日目 (火曜日)
まずはコマンドボタンの位置の見直しから。
中央にでかでかと出すのをやめ、画面下に並べて表示させました。コマンド数もそんな多くないため、こちらのほうが見栄えよさそう。
はい…そこは反省点で挙げますので…。
その後はキャラクターモーションの調整を行い、ようやくターン制の戦闘っぽくなってきました。
アザラシとシロクマがターン制で殴り合います。#unity1week pic.twitter.com/3AHKjCXLDI
— あかざらし (@akaiazarashi) August 11, 2020
午後はまずキーボードを新調しに行きます。
というのも、今回は実家のPCで開発しているのですが、DELL標準のキーボードとマウスしかなかったわけですね。つまりすごく使いにくい。
なので近所の電気屋でDELLよりマシなキーボードとマウスを購入。
しかし頭痛が収まらずにダウン。夜までこれといった作業はできませんでした。
ちなみにこの間でタイトルを決めました。
復活後はゲーム画面を作りこんでいきます。
1フロア=1敵グループとしていくつかのフロアを作成し、フロアクリア時の処理と、ゲームクリア・ゲームオーバーの処理を実装していきます。
画面上にアザラシのリストが欲しかったので、FancyScrollViewで実装しました。
「アザラシ名 + 体力ゲージ」だけのシンプルな形式。
最低限のゲームループができたので、明日からはバックエンド側に着手しようと考えます。
AWS上で適当に準備して就寝。
3日目 (水曜日)
いよいよAWSでバックエンドを…!
の前に、防御力のステータスによるダメージ減算が効いていなかったので、そこをささっと実装します。
そしてバックエンド側の実装をしていきます。
まず「Lambda + API Gateway」に対してUnity上からリクエストし、値がとれることを確認しました。
その後はDynamoDBとのやり取りを書いていき、アザラシの出し入れができるようにします。
しかしAPI Gatewayを介してリクエストすると、Lambda側でリクエスト内容が受け取れていない問題が発生。
これはAPIがGETリクエストをしているのにevent['body']
を参照していたためで、event['queryStringParameters']
を見るようにして解決しました。
取得側ができたので、あとは登録側です。
取得で夜遅くまでかかってしまったので、この日は簡単に登録画面を作って終わり。
4日目 (木曜日)
朝からアザラシ登録画面を作りこんでいきます。
この手の名前のバリデーションチェックが地味に面倒で、英数字だけにしようかなーと考え中…。
でもやっぱりアザラシ名には日本語も使いたいよね…。#unity1week pic.twitter.com/Hvd51R2lOi— あかざらし (@akaiazarashi) August 13, 2020
入力文字のバリデーションチェックも作りました。
しかしバックエンド側の登録処理でこけてしまいます。
DynamoDBからのレコード取得時にThe provided key element does not match the schema
というエラーが出てしまっていました。
プライマリキーのほかにソートキーを追加していたので、get_iem
でソートキーも指定しなければならなかったのですが、ソートキーを指定するのは逆にまずいという面倒な展開に。
結局DynamoDBのテーブルを作り直し、ソートキーを削除しました。
また更新時はInvalid UpdateExpression: Attribute name is a reserved keyword; reserved keyword: level
というエラーが。
これはlevel
が予約語で引っかかっていたためで、update_item
のハッシュにexpression_attribute_names
を指定して突破しました。
さらにAPIGatewayを経由させると、リクエスト値が取得できない問題が発生。
リクエストパラメータはevent['body']
の中に入っているのですが、Lamda統合プロキシをONにしているので(?)、値は配列やハッシュ等になっておらず、文字列がそのままぶち込まれていました。
なのでCGI.parse()
でハッシュに直してから参照しました。
これらを経て、やっとバックエンドへのアザラシ登録ができました。
夜に経験値とレベルアップの概念を実装します。
といっても「次のレベルまでの経験値」は固定で、パラメータを乱数で上げて保存するだけ。
バックエンドへの更新は、先ほど作り終わった登録処理が追加と更新を兼ねるように作ったので、登録と同じようなリクエストを投げるだけ。すごく楽でした。
次にかいふくコマンドの実装。
当初は「攻撃」「アザラシ追加」「ガード」の予定だったのですが、ガードの必要性がよくわからなかったので、味方を回復するコマンドを入れました。ガードモーション作るのが面倒というのが一番の理由ですが
お次は弓アザラシの実装です。
剣とハンマーはすぐ作ったのに、弓は4日目まで放置していたりしました。実をいうと槍と入れ替えようかなーと考えていたためです。
ただ剣のモーションで「突き×2→なぎ払い」を作ってしまったので、予定通り弓で作りました。
ついでに剣とハンマーにも新規モーションを追加し、各武器とも3種類の攻撃ができました。
というところで4日目は終了。
5日目 (金曜日)
まだ一度もWebGLビルドを試していなかったのでそこから。
すんなり行くとよかったのですが…案の定というか、日本語入力ができなかったり、AWSとの通信に失敗したりと問題多発。
WebGLの日本語入力はこちらで紹介されているパッケージを使わせていただきました。
https://kou-yeung.hatenablog.com/entry/2019/04/02/123542
通信失敗の件はCORS絡みでした。
シンプルリクエストなのでプリフライトリクエストはありませんが、Access-Control-Allow-Origin
ヘッダは返す必要があります。
APIGatewayで「Lambdaプロキシ統合の使用」をチェックしているため、Lambda側のレスポンスで指定してあげないといけなかったようです。そこを指定したら無事解決。
午後は真っ先に「アザラシと敵の位置の調整」から入ります。
ゲームシステムがだいたい完成。
キャラが全員重なっていること以外は。#unity1week pic.twitter.com/R61xmBTIoJ— あかざらし (@akaiazarashi) August 13, 2020
いくつかフロアを作成する予定なので、いちいち空オブジェクトで位置を調整するのは現実的ではありません。
なのでswitch
文でごり押し。
残り3日ともなると、書くコードも動くこと最優先になってきますよね。#unity1week pic.twitter.com/GmNr6lDooY
— あかざらし (@akaiazarashi) August 14, 2020
いやー密だなー…。 pic.twitter.com/zZcffhn33s
— あかざらし (@akaiazarashi) August 14, 2020
お次はスコアの実装。「与ダメージ」「フロアでの経過ターン数」などから適当に算出します。
運要素の強いゲームなので公平性はすごくなさそうですが、ランキングないのもつまらないので…。
お出かけの後、夜から作業再開。まずはキャラクターにUTS2を適用します。
次に敵のシロクマのバリエーションを増やします。
本当はシロクマもこん棒や斧で武装させたかったのですが、時間がなくて焦っていたこと、またシロクマのモデルが重すぎてまともに操作できなかったため、アニメーションを増やすのみで妥協しました。
この時点での残タスクは「認識しているバグが2つ」「フロアごとの地形と見た目」「バランス調整」「アザラシの攻撃エフェクト」などです。
正直間に合う気がしないので要素を減らしたのですが、まだこれだけあるあたり、ちょっと焦りが大きくなってきました。
6日目 (土曜日)
朝起きてすぐ、弓アザラシの攻撃エフェクトを実装します。
剣とハンマーは最悪エフェクトなしでも問題ありませんが、弓だけは何やっているか全然わからないのでマストです。開発中のリスとアザラシのゲームのエフェクトを流用しました。
そのあとはゲームプレイ後の画面に「もういちど」ボタンを付けたり、ランキングが表示されないバグを直したりしました。
焦りを抱えたまま親の実家でお盆のお参りをします。
帰宅後に作業再開…と思ったのですが、熱中症っぽい症状でダウン。結局再開できたのは夕方からでした。
夕方はまずステージの見た目を整えます。
アザラシとシロクマなのでいつもどおり「海+流氷」のセットを作ります。
それに加えて、最近「流氷の上を歩くシルリスとゴマ」のイラストを描いてもらった関係で、背景に氷山が欲しくなりました。
skebでリクエストいただいた絵です。ありがとうございました❄️ pic.twitter.com/gLdVUXfnH4
— 宇野山 むじ (@uimss) August 1, 2020
ということでBlenderのアドオン「Add Mesh:A.N.T.Landscape」を使って山っぽいものを作っていきます。
Unityへインポートし、適当にテクスチャやマテリアルを設定します。
SkyBoxも設定します。今回はこちらのアセットを使用しました。
https://assetstore.unity.com/packages/2d/textures-materials/sky/customizable-skybox-174576
その後はフロアごとに地形と敵情報の設定を行いました。あれこれ問題を抱えつつも、これで最低限公開可能なレベルになりました。
ある程度レベルが上がると、自分のアザラシだけで余裕で殲滅可能になります。
これやればやるほど「ふえる」要素消えるじゃん…。#unity1week pic.twitter.com/lFfdvCu7Ix— あかざらし (@akaiazarashi) August 15, 2020
1ターンが長すぎる…。 pic.twitter.com/CbwPGH5tW8
— あかざらし (@akaiazarashi) August 15, 2020
シロクマは強さに応じて大きさを変えることで表現。
しかしさすがにラスボスだけは何か特別感を出したかったので、ラスボス用のシロクマを作りました。
そしてめちゃくちゃ強くしました。気になる方は実際にやってみてください。
7日目 (日曜日)
最終日です。とりあえずタイトル画面を作ってしまいます。
その際に細かいバグを2つ見つけたのであわせて修正。
次にLambdaの関数2つにエイリアスを設定し、APIGatewayのエンドポイントを開発用と本番用で分けました。
このあたりのお話はこちらの記事が参考になります。
https://dev.classmethod.jp/articles/version-management-with-api-gateway-and-lambda/
この時点で一度unityroomにアップロードし、公開準備と動作確認を行います。
特に今回はAWSへの非同期リクエストが絡むので、動くことの安心感は早めに得ておきたかったですね。
その他、気になった点を簡単に修正。
最後にランキングデータのクリアと、DynamoDB内のアザラシデータを整理します。
ゲームの性質上、ある程度他人のアザラシのデータがないとつまらないので、あらかじめプリセットとしていくつか登録しておきました。
最後の最後でタイトルに難があることに気付きましたが、今から変えるのは正直きついのでそのままにしました。
今になって「あつめて」じゃなくて「ふやして」とか、「これだとアザラシをたたくゲームに思われそう」とかあれこれ気付きましたが、時間も気力もないのでこのままで…。#unity1week pic.twitter.com/DciKrclD6f
— あかざらし (@akaiazarashi) August 16, 2020
感想と反省点
今回初めてターン制RPGなゲームを作りました。
これまでのアクションゲームと異なり、楽な部分もあればつらい部分もありましたが、大きな破綻もなくゲームにできたかと思います。そこは素直に評価点。
またバックエンド有りで、しかもAWSのLambdaを使った所謂「サーバーレス」構成でしたが、これも初回だけレスポンスが遅い意外は上出来かと。
非同期のゲームであれば頻繁にアクセスする必要はないので、サーバーレスの相性はかなりいい気がします。今回で手順を確立したので、次回以降の開発の幅が広がりました。
反省点は「設計と見積もりの意味がなかった」こと
今回は初日に「画面設計」「フローチャート」「DB設計」「工数見積もり」などを行い、だいたいの見通しを立ててから望んだつもりでした。
しかし役に立ったのはフローチャートくらいで、画面設計は2日目にして意味をなさなくなり、DB設計は定義ミスによりテーブルごと作り直す始末。
極めつけは工数見積もりで、お盆の休み期間中でなければ確実に間に合わなかったと思います。具体的にはバックエンドとロジック作成に時間がかかりすぎ。特に「Lambda + APIGateway」の組み合わせに苦戦しすぎました。webのバックエンドが本業の者としてちょっとなさけない。
総じて評価できる点もあれば反省点もある、いつも通りな開発になりました。
やっぱり設計のガバさを開発の気合で補っている感があるので、数をこなしてその精度をあげていきたいところです。
また3Dばかりなので、次回はできれば2Dに手を出したいです。第15回の感想でも似たようなこと言いましたが…
あとがき
そんなわけで、第16回Unity1週間ゲームジャムに参加しました!
ゲームジャム参加もこれで7回目です。さすがに第1回の頃と比べてクオリティは上がっているので、このまま続けていきたいですね。
次回もアザラシ…かどうかはわかりませんが、お楽しみに~!