Unity1week「回」を振り返った

創作意欲が湧いてくる今日この頃,Unity1weekに参加しました。今回のお題は「回」でした。自身の参加は学生以来の2回目です。

ちなみに作ったゲームはこれ。良かったら遊んでみてください。(宣伝)

unityroom.com

現時点で「面白い!」「気持ちよかった!」という評価コメントを頂いて,テンションがめちゃめちゃ上がっている。 実況プレイ動画を撮ってくださる方もいて,本当にありがたい。

しかし,友人の評価を聞いてみたり,プレイ動画を眺めたりすると反省するところも沢山出てくる。 まだ相互評価期間も終わってないけど,上手くいったところと反省点をまとめておこうと思う。

上手くいったところ

面白さの作りこみをしっかりやった

「面白い!」「気持ちいい!」の評判に一番効いたのはここだと思う。 Unity1week初日には一切Unityを開かず,ひたすら机上でアイデア作りをして,面白いと断言できるところまで持って行った。 どんな感情を与えるゲームにしたいか,というコンセプトをしっかり固めて,あとはそのコンセプトを実現する仕組みを決めていけば良いと考えた。

コンセプトの設定

お題の「回」を聞いた時点で,せっかくなら回ることそのものが楽しさや気持ちよさにつながるゲームが作りたいと考えた。 回ることが敵を倒す手段とか,回ることがゲームのギミックの一部とかではなく,回ること自体をゲームの楽しさにしたかった。 とかとかいう謎のこだわりが発生したので,それをそのままコンセプトとした。

コンセプト:回ることそのものが楽しい,どんどん回したくなる,回るほどうれしい

具体的には「人生で回って楽しかった経験」をひたすら思い出してみた。コマ,ハンドスピナーに始まり,ペン回し,事務イスと続き,最後は体操競技に行きついた。 (実は中学時代は体操部だった。しかし下手だったので,体操についてはその後の人生で見る専を決めた。)

回ることが楽しいというコンセプトと体操競技というテーマが決まってから,Youtubeで体操の動画を沢山眺めてアイデアを練った。 体操の動画,観てるだけでめちゃめちゃ楽しい。例えば鉄棒の大技「コバチ」は,大車輪から真上に飛んで1回転した上でまたバーをつかむ技だけど*1, これがもっと高く飛んで,2回転,3回転と回転数が増えたらめちゃめちゃ見ごたえあるだろうし,それを自身の手で実現できるゲームにしたら絶対楽しいだろうなと思った。

かくして,「鉄棒的な,段違い平行棒的な競技*2で回転しまくれる超人体操ゲームを作ろう!」という思いで2日目のゲーム制作に移った。まだUnityは触らない…

f:id:shinji00:20210305234856p:plain
ゲームアイデアが固まってきたあたりのOneNoteのメモ。バーが1本だとつまらないので増やした。これが後々上手く機能するとは思わなかった。

類似ゲーム調査

ゲームジャンル?が決まったので類似ゲームの調査をした。 実際にプレイしてみると参考にしたい部分もある一方,イライラを感じることもあったので,そういうのは自分のゲームからもなるべく取り除くべきだと考えた。

体操の,特に鉄棒のゲームは沢山あるが,やってみると難易度の高い死にゲーが多いように感じた。バーに衝突したり,バーをつかみ損ねて落ちたり,着地に失敗して頭から落ちたり…という具合だ。 確かに体操競技って難しいし,その難しさを超えた時の達成感もあるので,そういうゲームになるのも道理があるかなと思った。失敗したときのシュールさも絵になるし。 ただ前記コンセプトが頭にあると「かっこいい技を決めたいのに死にゲーをやらされている!」というネガティブな気分になった。

なので,自分のゲームでは「沢山回る」以外の部分は極力イージーに作ることにした。 体のどこがバーに接触しようがバーをつかめるようにしたし,どの角度から地面に激突しても足を下にして着地するようにした。 バーも1本ではなく6本にしたことも,狙いの角度に飛べなくてもどこかしらにつかまれるという効果があった。

f:id:shinji00:20210306121607p:plain
類似ゲーム調査時のメモ。素直に思ったことを全部書いた。

そもそもunity1weekで400作品も投稿される中から遊んでもらうわけなので,想定プレイヤーは「2,3回触ってみて微妙だったら止めて他のゲームを遊ぶ」人たちである。 そのプレイヤーたちになるべく早く成功体験を積んでもらって,その先の高みを目指してもらうためにも,今回のイージーな設定は必要だったと思う。

ゲーム化

コンセプトが損なわれない範囲で制約を作りゲーム化した。

この時点でできているゲームルールは「大車輪からバーを離して飛ぶ。回転しながらほかのバーに飛び移る。飛んでいる間の回転数を競う。抱え込みをすると回転数が速くなる。」だった。 このままでは飛んだ瞬間抱え込んだままにすれば最高得点が出てきてしまうことになり,それではゲームにならない。

「抱え込みをしたままバーに当たるとミスになる」というルールを導入した。これなら「バーに近づくギリギリまで抱え込んで回転数を稼ぎたいが,バーに近づいたら離さなければいけない」というジレンマが生まれる。 工夫したのは,バーに近づく直前だけにジレンマを導入したことである。これにより,バーから遠い「飛んでから落ちる」間は何も考えずに純粋に高速回転を楽しむことができる。 もし回転している最中,何か別の心配事や難しい操作があると,回って楽しいというコンセプトを実現できないのではと考えたのである。

もう一息ジレンマを起こすためにルールを追加した。「中央のバーを飛び越えるような移り方は配点が高い」「抱え込みをすると当たり判定が狭くなる」というルールである。 「ミスを覚悟で抱え込みをして中央のバーをぎりぎり飛び越えて高得点を狙う」というハイリスクハイリターンなプレイと,「飛び移り高得点は狙わないので,中央のバーが近づいたら抱え込みを解除する」ローリスクローリターンなプレイを選択可能にした。(なおこのジレンマは後述の理由により,あまり機能しなかった。)

f:id:shinji00:20210306134012p:plain
抱え込みのリスクとリターン

f:id:shinji00:20210306134413p:plain
飛び移り技の配点表のメモ

コンセプトとテーマ,基本ルールとジレンマを作る仕組みができたところで,2日目(祝日)の午後やっとUnityを開いた。(数年ぶりだったのでログインとかアプデとか色々大変だった。)

Classの役割と参照関係を定義してからプログラムを書いた

自分が今まで作ってきたソースコードたちはスパゲッティになりがちだったので,反省してちゃんとクラス設計をすることにした。 1週間という短い期間だからこそ,大急ぎで手を動かすのではなく,手戻りが無いように設計しておきたかった。 といってもそのあたりあまり詳しくないので,どこかで聞いたことのある「1つのクラスには1つの役割」「循環参照はしない」だけ守ることにした。

f:id:shinji00:20210306135826p:plain
クラス設計図。主に参照関係を定義した。UMLとやらの書き方を参考にしたけどよく分かりません。

Visual Studioを開いて,参照に関係するコード(public float GetScore(){return 1.0f;}とか)だけ書いてエラーが起きないことを確認してからコーディングを開始した。 そのクラスの心配だけしながらコードを書けて,安心かつ手戻りナシで良い感触だった。この辺の勉強もっとやりたい。

反省すべきところ

コンセプトも定義して,そのための仕組みも作ったので,「こういう反応やこういうやりこみをしてくれたら成功」というのは頭にあった。 まさにその通りのコメントも頂いて一時はテンション上がったけど,プレイした友人の反応や実況動画を見る限り,必ずしも成功とは言えなかった。

回るゲームにするつもりがつかむゲームになった

あれだけ気を使った飛び移るギミックが思いのほか難しく,回転を稼ぐよりも飛び移りの成功を目指すことがゲームになってしまった。

バーに近づけばつかむこと自体に苦労はないが,そもそもバーとバーの間をすっぽ抜けたりしてつかめないということが多かった。 バーをつかむためにはバーを離して飛ぶタイミングをかなり気にしなければいけなくなった。 具体的には3回くらい飛んでみたら失敗するくらいの確率だった。(自分のテストプレイでは習熟しすぎてて気づかなかった。あるある。)

プレイヤーの反応も「1回でも多く回るぞ!」「あのバーに飛び移るぞ!」ではなく「つかまなきゃ…!飛ぶタイミングをミスれない…!」「10回も飛べない!」という感じだった。 このおかげで,前記飛び移り配点表の存在を意識してプレイする人はあまりいなかっただろう。(得点ポップアップの意味が分かりづらいのもあると思う)

対策としては,単純にバーのつかみ判定を広くするか,バーを増やしたり,配置に気を使うといったことが考えられそう。 また,バーを離すのはキーを押した瞬間ではなく,キーを離した瞬間という仕様だったが,もしかしたら前者の方がやりやすい人もいるかもしれないので,再検討してもよさそう。 「ゾーン」に入った時のように,キーを押した瞬間スローモーションにして離すタイミングを決めやすくするのもありかもしれない。 マリオのように飛んでいる間も位置のコントロールができるようにしても良いかもしれない。

やっぱり第3者にテストプレイをしてもらって,面白さに到達するまでに思わぬ難易度の壁が無いか確認するべきである。 チーム開発やっている人が毎日テストプレイ会を設けているのもそういう理由だと思う。

UIに時間をかけすぎた

現在のスコアと,技を決めた時の加点スコアを表示するために。次のような仕様書を作った。

f:id:shinji00:20210306142425p:plain
UI(というかスコアビューアー)の画面仕様書

すごく簡単そうに見えるだろう。筆者はこれの実装で土曜日を潰したのである。 Canvas座標の理解に苦しんだり,思った通りに動かすのに苦労している内にかなり時間を使ってしまった。 この時間が節約できれば,絵作り(背景とか)や調整に時間をかけることもできただろう。サムネや背景を作りこんで人を呼ぶこともできたかもしれない。ランキング昨日も実装できたかも。

結果の画面表示そのものにゲームとしての独自性はないし,とはいえ必要なことだし,どんなゲームにも共通する作業なのでパパっと手間なくできるべきである。 DOTweenとかいうのが便利そうなので,次は活用してみようと思う。

実はUIちょっと動かす時も,カメラ操作するときも,「timerフィールド用意して,speed*Time.deltaTimeでちょっとずつposition動かして,timer<0になったら止める」とか「止めたい位置周辺まで来たらposition=target_positionする」とか,そういう面倒くさいことをやっていた。DOTweenなら一行で,しかもUpdate()ごとではなく一度で,簡単なアニメーションが実行できるので,使わない手はない。

というわけで,この辺の反省は次回のUnity1weekに参加するときや,このアプリをブラッシュアップしてスマホアプリ化するときにでも生かそうと思う。

*1:この動画見た方が早いです https://www.youtube.com/watch?v=AgSjm7Gd21w

*2:できたゲームは段違い平行棒という女子体操の競技が冠されているけど,モデルはぱっと見男性…100年後のオリンピックという設定だし,正確にはバーが6本ある"Neo段違い平行棒"だし,こまけぇこたぁいいんだよの精神で作りました。