原カバンは鞄のお店ではありません。

Unityを使ったゲーム制作のあれこれを綴っていきます。

【レポート】福岡インディーゲームエキスポ2024に出展した話

D-Pad

インディーゲームの展示会に出展したら大柄な外国人4人に囲まれて展示したゲームについて議論を交わしているけど英語がサッパリなのでオロオロするだけだった英語弱者な皆さんこんにちは。取り合えず十字キーの事をD-Padと呼んでいる事は分かりました。展示したゲームが言葉での説明を必要としないゲームだった為か、外国の方でも楽しんで頂けたようで良かったです。有難うございました。

 

福岡インディーゲームエキスポ2024

というわけで3/23(土),24(日)の二日間にわたって開催された福岡インディーゲームエキスポ2024に出展してきました。

www.fukuoka-indiegame.com


開場がキャナルシティ博多という大きな商業施設という事もあり、開催日両日とも生憎の雨模様だったものの来場者が途切れるという事があまりなく、手が空いて時間を持て余したのは初日の開始一時間と二日目の終了一時間前の時間帯ぐらいでしょうか、おかげさまで配布用に用紙していた紙製のクリアファイルは全て捌ける事が出来ました(一日目で全部配布し終えそうな勢いでした)

 

去年まではアーリーアクセス版の宣伝のために「W.T.」を展示会に出展していたのですが、今回は次回作の製作に向けて市井の方が方々から意見をもらう為に「Under A Groove」のデモ版を出展しました。ノーツが降ってくるようなリズムゲームとは少し趣向を変えて遊べるMV的なリズムアクションゲームとなっています。

youtu.be

全く無名のゲームタイトルなだけに展示会では素通りされるかと不安でしたが、存外にも多くの方に遊んで頂き、狙い通りに様々な意見を頂けて意義のある出展になりました。

特に初日の土曜日にはゲーム好きな方だけでなく、ゲーム実況をされている方、ゲームを制作している方などゲームに対して一家言ありそうな方々が多く来場されていたようで、こちらがプレイした感想を求めると、結構詳細に意見や疑問点を伝えてくれる方が多かった印象です。

そのおかげで自分では気づけなかった問題点や、改良点を知ることが出来ましたし、このゲームに対して私が強み(アピールポイント)だと思っている部分について賞賛頂ける事が多く自信を持つことが出来ました。

なので今回は展示会のレポート言うよりは、試遊された方から頂いた意見や質問などから、私が感じた事、気づいた事について記事に纏めてみたいと思います。

 

パブリックイメージ

上にあげているプレイ動画は初日に頂いた意見を元に応急処置で二日目に間に合いそうな箇所を修正したバージョンのプレイ動画です。
修正した箇所はいずれもゲーム中に起こるイベントで、パブリックイメージ(広く一般に認識されているイメージ)とは異なるリアクションとなっていた為に違和感を訴えられた箇所でした。

 

◆修正点1:正否を表現する色

画面下部の両端からノーツが移動してくるバーはノーツが中央に来るタイミングで色が変わります。
これはボタンを押すジャストのタイミングを表現していますが、当初は画面の背景に青系の色が多い事もあり、視認しやすいように赤系の色に変わるようにしていたのですが、これを「(操作を)間違ったのか?」と戸惑う方が多かったようで「操作の正否が分かりづらい」との意見を頂きました。

多くのゲームではプレイヤーが操作を誤った際のエフェクトには赤系の色が使われているため、赤系の色を見るとNGだと認識される方が多いのだと思います。逆に青、緑系の色はSafeの印象となるので、二日目は緑色の表示に変更しました

 

◆修正点2:ゲームパッドの振動

プレイ動画からは分かりませんが、ボタンを押したタイミングで判定がOKの場合はゲームパッドが振動するように処理を行っていました。

これはこのゲームを作る際に参考にしたゲーム(洋ゲー)がチェックOKの時にパッドが振動するようになっており、私も「操作が正解した」手ごたえを感じる事ができると思い、この仕様を採用したのですが、こちらもパッドが振動するのはミスをした所為だと勘違いされる方が多く、プレイ後に「パッドが振動するのはOKの時?NGの時?」と質問される事が多々ありました。

多くのアクションゲーム等で自機がダメージを受けた際にパッドが振動する為に、このゲームでも同じような認識を持たれたのだと思います。
二日目にはパッドが振動する条件を逆に(誤った時に振動)すると、このような意見を言われる方はいなかったので、こちらの方がパブリックイメージとして浸透しているのだと感じました。

 

ゲームの仕様を決める際にはデザイン的な趣向や制作側の都合よりもパブリックイメージを考えて、遊んでいる方が違和感を感じないような仕様にした方が無用なストレスなく遊んでもらえるという事が分かったので今後の参考にしたいと思います。

 

盲点だった事

展示会開催中での修正は間に合わなかったのですが頂いた意見の中で最も多かった意見は「操作が成功した時のエフェクトを派手にした方が成否が分かりやすい」というものでした。
これは私としては意外な意見で、というのも、このゲームでは操作の正否によって発生するアニメーションが大きく異なるような仕様になっている為です。

操作の成否によるアニメーションの分岐

それでもこのような意見が聞かれるのはどうしてだろう?と自問したところ、「そもそも初見のプレイヤーは正否のアニメーションを知らない」という事に気づきました。つまりOKの場合のアニメーションを見ても、NGの場合のアニメーションを見ても、初見のプレイヤー側はそのアニメーションが「OKを表現しているのか、NGを表現しているのか分からない」という事。

これは気づけば単純な事ですが、制作者として完全に盲点でした。

通常の音ゲーのように「JUST」や「BAD」等の文字ではなくアニメーションの変化でそれを表現しようとしましたが、それだけではプレイヤーに伝わらない、とは言え「(正否を文字表示するのは)ダサいから止めた方が良いですね」とおっしゃる方もいたので、ここら辺はもう少し表現方法を練る必要がある事に気づかされました。

 

他にも途中でゲームコントローラーを表示して十字キーの上にノーツを表示する、ようなイベントの箇所では、ボタンではなく実際にコントローラーの十字キーを押して操作しようとする方もチラホラ見受けられ、ここは「全てがボタン一つで操作可能とするか」「画面の通りにスティック、十字キーも押して操作できるようにするか」悩みどころだと感じました。

感想を下さる方の中でも意見が分かれていたので、対応策はこれから模索していくことになると思います。

 

全体の感想

色々と課題点を上げましたが、試遊して頂いた方の反応はおおむね好評だったと思います。中には手放しで絶賛してくれる方もいて非常に心強い思いになりましたし、小さなお子さんが私のゲームを指さして「これやりたい」と駆け寄って来てコントローラーを手に取ってもらった時は本当に嬉しかったです。

また、今回はいつになく名刺交換をさせて頂く機会が多かったり、周りの出展者の方とも少なからずお話しすることが出来ましたし、空いた時間で遊ぶことも出来ました。(東京で出展した前二回は他のブースに遊びに行くような余裕はなかった)

それにこのブログの読者さんにも声を掛けてもらったりと(嬉しかったです)、非常に実りある出展になったのではないかと思っています。

心残りは一日目の終わりに開催された懇親会に出席できなかった事ですが、これは次回のお楽しみに取っておきたいと思います。

 

来てくださった方々、遊んで下さった方々、

本当に有難うございました!

【告知】福岡インディーゲームエキスポ2024に出展します

香水

満員電車の中で横に並んだオバさんの香水の匂いがきつくて吐きそうになった弱者男性の皆さんこんにちは。あんなのラジカセ担いで爆音で鳴らしているのと同じだからね、あなたの好みが他者の好きとは限らないので匂いのテロは本当に迷惑だと分かって頂きたい。

 

福岡IGE2024

ここ4,5年の間にインディーゲームという存在が広く一般的に認知されてきた影響なのか、全国各地でインディーゲームの出展イベントが開かれるようになりました。
古くからあるデジゲー博の他に、東京ゲームダンジョンやゲームパビリオンjp(大阪)、ぜんため(岐阜)、BITSUMMIT(京都)、INDIE GAME MARKET(仙台)など多々あり、私の地元福岡でも一度2022年に出展イベント(福岡インディーゲームエキスポ)が開かれています。
残念ながら去年は諸般の事情により開催されなかったのですが、今年は早々に福岡インディーゲームエキスポ(福岡IGE)の第2回目の開催が決定しております。

www.fukuoka-indiegame.com

今回は3/23,24の二日間による開催で、しかも福岡を代表する商業施設であるキャナルシティ博多が会場となっています。
出展作品数が40弱と、他のイベントに比べ若干少ない事は否めないのですが、その分、出展する側はアピールするチャンスが多いという事なので、去年東京ゲームダンジョンやデジゲー博に出展した経験を活かし、会場を訪れたお客さんに作品をアピールしたいと思います。

また、上記のリンクでも記載されていますが、ゲーム展示以外にも地元タレントさんや、ゲームクリエイターによるトークショーがあったり、多数のVtuberさんによるゲーム紹介があったりと、ゲーム展示というよりゲーム祭り的な雰囲気のイベントになりそうなので、多くの方に来場してもらい楽しんで頂けたらなぁ、と思っています。

 

Under A Groove

東京ゲームダンジョンやデジゲー博ではSteamでアーリーアクセス版を配信している「W.T.」の展示会用Ver.を出展しました。

store.steampowered.com

福岡インディーゲームエキスポでも当初は「W.T.」を出展する予定だったのですが、前二回の出展で「W.T.」に対するお客さんの大体のリアクションは掴めたので、今回は宣伝を目的とするよりも次回作として試作中のゲームに対する反応を知りたいと思い、新しゲームを出展することにしました。

 

Under A Groove」というタイトルで「シチュエーションをGrooveする 」をゲームコンセプトに一風変わったリズムアクションゲームとなっています。

未だ構想と試作を繰り返している段階でゲームとしてハッキリと仕様が固まってないのですが、今の段階で遊んでもらう事でこのゲームのコンセプトを伝えるために不足しているもの、必要な要素を見つけたいし、このゲームの売りと(私が)考えている部分に思い違いがないか確かめたい、そんな考えで出展を決めました。

 

このゲームについては「Snow Town Under A Groove」というタイトルで今回とは別のバージョンでUnity1Weekに参加したのですが、思うようにコメントをもらう事が出来なかった事も福岡IGEでの出展の要因の一つとなっています。

unityroom.com

なので少し不安もありますが、遊んで頂く以上は楽しんで頂きたいのはゲーム開発者なら誰でも思う事、福岡IGEまでには少しでもブラッシュアップして、より面白いと思ってもらえるようなバージョンに仕上げていくつもりなので、当日参加される方は是非手に取って遊んでみてください!

 

私の出展ブースはNo.16、上の図の場所となっています。周りにはインディゲーム界隈では有名な方も出展されていますが、気後れせずお客さんに声を掛け、この「Under A Groove」を遊んで頂き、配布物を配っていきたいと思います。

 

ちなみに配布物はいつも通り紙製のクリアファイルでデザインは以下のようになっています。

(青枠の部分はクリアファイルの形で実際には印刷されていません)

 

3/23,24 キャナルシティ博多でお待ちしております。

よろしくお願いいたします!

 

 

【Unity】クロマキーシェーダを使って動画を合成する

会社行事

コロナ禍が収まったおかげで会社の色々な行事が復活し、4月の新人歓迎会が今から戦々恐々な皆さんこんにちは。わが社では新人歓迎会で既存の社員一人一人が壇上に立ち新入社員に対して自己紹介するという地獄のコーナーがあるので本当に憂鬱で仕方ありません。頑張って新人相手に自己紹介したところで3年以内に1/3は辞めるし意味ないのになぁ。

 

謎解き×謎解きなゲーム

ストレートな謎解きの一歩手前でその問題の意味自体を解読するという謎解きで包んだゲームが丁度セールで安くなっていたので購入しました。

多民族がそれぞれ異なる言語で分断された世界を舞台に、主人公(プレイヤー)が各々の民族が語る言葉の意味を解き明かしながら、民族間の軋轢を解消していく、という形でゲームは進みます。
「軋轢を解消していく」とは言え、主人公が民族間の紛争に積極的に介入していくというわけでなく、各民族が暮らすそれぞれの世界へ侵入し、そこで交わされている言葉と行動を見ながら各民族が使う文字の意味と文法を理解して、間接的に民族間の会話の翻訳者となり、それにより民族間の誤解が解けていく、というストーリーとなっています。

各民族の世界では主人公(プレイヤー)は歓迎されたり、敵視されたり、助けを求められたりするので、それらの問題に対処するための解決法を探り、提示された謎解き(パズル)を行っていきます。

謎解き(パズル)自体は記号の順序立て(並べ替え)やスライドパズル、お使い系(必要なアイテムを探してくる)といった既存のADVゲーム、脱出系ゲームにありがちなもので目新しさはないのですが、その問題を解くために先程の言語解読という謎解きを行う必要があるため、そういった二段構えの謎がプレイヤーの探求心をそそり、ゲームプレイを奥深いものにしています。
言語の解読というと難しいテーマに思われがちですが、想像よりもかなり遊びやすくデザインされており、プレイヤーが途中で挫折しないよう色々と仕掛けが練られて非常に完成度の高い作品だと思います。謎解きが好きな方はチャレンジをお勧めします。

 

素材提供

詳細は省きますがつい先日、大物Vtuberの方が自身のMVの一部を合成用素材として公開されています。

t.co有難い事に綺麗なブルーバックの動画となっているので、これならUnityでも気軽に合成してゲーム内に取り入れられるのでは?と思いチャレンジしてみました。

上記の公開されている動画はYoutubeからダウンロードしてUnityのProiectウィンドウ内にドラッグ&ドロップすればプロジェクト内に取り入れる事ができます。

 

Unityで動画を再生するのは非常に簡単で、まずは動画を表示するためのオブジェクト(PlaneやQuad)をゲーム内に作成します。

中央の白い四角がスクリーン用オブジェクト

スクリーン用のオブジェクトは出来るだけ動画のアスペクト比に合うようにサイズ調整します。
次にオブジェクトにInspectorウィンドウのAdd Componentから、VideoPlayerコンポーネントを追加します。

後はVideoClip欄に再生したい動画ファイルを指定してデバッグを実行すれば自動的に動画が再生されます。

動画を再生

これはVideoPlayerの「Render Mode」の設定に「Material Override」が指定されているので、スクリーンオブジェクトのマテリアルに動画の映像が上書きされている為ですが、このままの指定だと上の動画のようにブルーバックも表示されてしまう結果となります。

 

クロマキーシェーダ

ブルーバックを消す(透過させる)にはクロマキーシェーダを使用する方法が最も手軽な方法でしょう。
クロマキーシェーダとはその名の通り特定の色を透過させるシェーダで、アセットストア上には有料アセットとして存在していますが、今回は凹みTipsさんが公開しているクロマキーシェーダを使用します。

tips.hecomi.com

このクロマキーシェーダでは使用するTextureに対して指定した色を透過させてオブジェクトを表示します。
このTextureにVideoPlayerが再生する画像を指定すれば良いわけです。

VideoPlayeが再生する画像をTextureに描き出すには先程の「Render Mode」の設定を「Render Texture」に変更します。

 

RenderTextureはProjectウィンドウ上で右クリック→Createから作成します。

作成したRenderTextureは解像度(サイズ)を再生したい動画のアスペクト比に合うように設定します。

 

そして先程のVideoPlayerコンポーネントのTargetTexture欄に作成したRenderTextureを指定します。

 

クロマキーシェーダはスクリーン用オブジェクトのマテリアルのシェーダに設定します。

シェーダのTextrureにVideoPlayerコンポーネントで指定したRenderTextureを指定、ChromaKeyのColor欄に動画のブルーバックの色(青)を指定します。

実行結果はこちら、Unityのゲーム空間内に大物Vtuberさんの動画を合成させる事ができました。

 

別バージョンがこんな感じ、違和感なく動画を合成できます。

 

宣伝

数学的脱出ゲーム「W.T.」早期アクセス版リリース中です。
歯ごたえのある脱出ゲームとなっているので腕に自信のある方のチャレンジ、お待ちしております。

store.steampowered.com

【Unity】UniTaskのWaitUntilやWaitUntilValueChangedは便利

DLC

エルデンリングDLCの為に一年以上ぶりにエルデの地へ降り立ったものの操作方法を忘れて遺灰すら呼び出せない褪せ人の皆さんこんにちは。なんでも情報によるとDLCで遊ぶ為にはモーグウィン王朝のクリアが必須らしいのですが、二周目を始めて中途半端に放置していたせいで王朝へ辿り着くまでの道のりが遠すぎて今更そこまで到達できるか不安です。なんせ二周目開始早々に白面のヴァレーを倒してしまったので聖別雪原まで行かないといけない。早く操作方法を思い出して6月までにはDLC開始条件を満たしておきたいと思います。

 

ソウルライクである必要がなかったゲーム

PS Plusの2月分のフリープレイ対象になっていたのでダウンロードして遊んでみました。

18世紀のフランス革命を舞台にしたソウルライクゲームで主人公はマリーアントワネットに使える機械人形(オートマタ)という設定。
同じソウルライクゲームのLies of Pと似たような設定ですが、発売はこちらの方が早く、「ぼくのかんがえたさいきょうのダークソウル」的なLies of Pと比べ、「ソウルライク」のゲームルールに乗っ取りながらも手軽にスピーディなアクションが楽しめるゲームとなっています。
剣や斧、槍といったオーソドックスな武器は殆ど使用せず、鉄扇やトンファー、マスケット銃、仕込み爪といった一風変わった仕掛け武器を使用してオートマタという設定を活かした独特なモーションによる戦闘は独自性に富んでいて非常に楽しい要素でした。
各ステージも建物の上や地下を巡り立体的に交差して迷宮的な構造を成しており探索して飽きない作りになっていたと思います。

とは言え、「ソウルライク」と銘打っているものの難易度的には非常に低く、それほどゲームが上手くない私でも殆どのボスを初見で撃破できる程。その反面、道中の敵は複数体を同時に対処しなければならないよう配置されており(特にゲーム後半)、少し鬱陶しく感じる場面も多かった気がします。
自キャラの操作はスムーズで、戦闘の軽快さや爽快感は非常に高いものがあります。普通のアクションRPGとして見れば十分に評価されるべきゲームだと思うのですが、「ソウルライク」という縛りがあるせいで、「ソウルライク」特有の難易度と攻略の達成感を期待するプレイヤーには物足りなく感じるでしょう。
開発側はユーザ層を広げる為に初心者向けの「ソウルライク」を目指したのかもしれませんが、普通に新規のアクションRPGとしてゲームデザインを組み立てた方がもっと評価を得られたのではないでしょうか。

 

UniTask

Unityで非同期処理っぽい事をするにはCoroutineを使うのが一般的でしたが、ここ最近ではUniTaskを利用する方が増えてきているようです。

UniTaskとはC#のTaskと同じような機能を持つAPIですが、Unity用に最適化されておりC#の標準のTaskやUnityのCoroutineよりもパフォーマンス性が高く、既存のCoroutineからの処理の転用も容易、かつ無料なので、まぁ導入にはメリットしかないわけです。

UniTaskの導入はGitHubから取得したunitypackageをインポートするだけです。

github.com

 

UniTaskの基本的な使用法はC#のTaskとほぼ同様で、async/awaitを使って非同期処理を実施します。例えば「3秒待ってstring型の戻り値を返す」という処理なら

private async UniTask<string> UniTaskWait()
{
    // 待機処理はawait
    await UniTask.Delay((int)(3 * 1000));

    return "End";
}

という実装になります。

 

静的メソッド

UniTaskを利用する大きな利点の一つとして静的メソッドが豊富に用意されている事も挙げられます。

上記の指定時間を待つ「Delay」というメソッド以外に1フレーム待機するメソッド(Yield)や、起動したTaskの全ての完了を待つメソッド(WhenAll)、もしくはどれか一つの完了を待つメソッド(WhenAny)と色々ありますが、特に使用頻度が高いのは、指定した条件がtrueになるまで待機するメソッド(WaitUntil)と指定したオブジェクトの特定の値が変化するまで待機するメソッド(WaitUntilValueChanged)ではないでしょうか。

ちなみにWaitUntilの逆で指定した条件がfalseになるまで待機するメソッド(WaitWhile)もちゃんと用意されています。

 

WaitUntilでは条件文を指定できるので例えば

// Y方向の位置が0超過するまで待機
await UniTask.WaitUntil(() => transform.position.y > 0); 

Debug.Log("上昇");

上記のような条件で処理を待つことができます。

 

WaitUntilValueChangedの場合は下記のような指定により

//Y方向への移動を検知する
await UniTask.WaitUntilValueChanged(transform, x => x.position.y); 

オブジェクトの状態(Y方向)が変化するのを待つことが出来ます。

 

使用例

具体的な使用例としてカウントダウンタイマのようなものを作ってみました。

中央の数字がカウントダウンする毎に背景色が変化し、カウントダウンが終了したら「Start」の文字を表示します。

背景色の変更はWaitUntilValueChangedを使用しカウントを表示するテキスト(TextMeshPro)の変更を待って行います。「Start」の文字表示は終了条件に達したフラグを参照するようにWaitUntilを使って待っています。

public TextMeshPro ContText;
bool isStart = false;

private async UniTaskVoid ColorChange()
{
	// ContTextの文字(text)の変更を待つ
	await UniTask.WaitUntilValueChanged(ContText, x=> x.text); 
	
	// 背景色を変更する
} 

private async UniTaskVoid WordDisp()
{
	// フラグ(isStart)がtureになるのを待つ
	await UniTask.WaitUntil(() => isStart); 
	
	// Startの文字を表示
} 

 

宣伝

数学的脱出ゲーム「W.T.」早期アクセス版リリース中です。
歯ごたえのある脱出ゲームとなっているので腕に自信のある方のチャレンジ、お待ちしております。

store.steampowered.com

【Unity】VContainerの使用例(MVPパターン)

ロゴ変更

プロジェクトのロゴを変更して切羽詰まった気分を一新したいルーザーの皆さんこんにちは。以前のロゴはとある方に発注して作成して頂いた物だったので、変更するのは忍び難かったのですが、昨年末からどうも思うようにいかない事が多く、停滞気味の状況に変化を加えるべくロゴを新しくしました。
(それに伴いブログのタイトル画像も変えました)

 

ファーストインパクトで乗り切るゲーム

Xでトレーラーが発表された時にかなり話題になっていたものの、本編発売後はそれほど取り上げられることが少なかったゲームを購入しました。


「写真をかざすと写真の中の世界が顕在化(3D化)する」というアイデアはパズルのメカニクスとして斬新でゲーム開始時のファーストインパクトは非常に大きいと思います。思わず「すげー」と声がでそうになるほど。

同じようなコンセプトのゲームで『Superliminal』というゲームがありますが、遠近感の錯覚を利用しオブジェクトの大小を変えることで解法を探す『Superliminal』と比べ、こちらは「2Dの写真で3D空間を上書きする」というメカニクスであるため、到達不能と思える場所には壁を写した写真をかざして足場を作る、数が不足しているアイテムは写真に映してコピーを作るといった、どちらか言えばストレートな考え方で正解に辿り着く問題が多い印象です。

この為、パズルの難易度的には低く、ゲーム後半でも詰まる場面は殆どありませんでした。ボリューム的にも3,4時間程度で終わってしまう為、人によっては物足りないものに感じるかもしれません。
とは言え、Steamのレビューでも「非常に好評」となっているように、「写真で空間を上書きする」というアイディアを可能な限り活かしてゲームに落とし込めており、徐々に難易度が上がっていくパズルに対して、それを解いた時の爽快感は終盤まで落ちる事はありませんでした。
3,4時間程度で終わるボリュームの少なさも、逆に言うと「写真で空間が上書きされる」という最初の驚きを超えるような事象は最後まで起きないので、このクリア時間程度で終わるのが丁度良い塩梅なのかもしれません。

 

VContainerとMVPパターン

前回の記事でUnityでDIコンテナを実現するアセットVContainerを紹介しました。

www.karvan1230.com

その具体的な利用例として最も最適なのがMVPパターンによる実装だと思います。
MVPパターンとはデザインパターンの一種で、ザックリ説明するとPresenterという仲介者を挟むことでプロジェクトの内部処理(Model)と表示処理(View)との依存関係を無くそう、という設計思想になります。


上の図では事務処理を行う部署(Model)とプレゼンテーションを行う部署(View)は互いの仕事に全く関与せず、それを仲介する部署(Presenter)を通してデータのやり取りを行っています。こうすることで、たとえどちらかの部署に大きな内部変更があったとしても、もう一方の部署の業務には影響を与えることが無くなります。
これよりModelとViewとは互いの依存関係は無くなりますが、逆にこれらを仲介するPresenterはどうしてもModelとViewに依存する形となってしまいます。
そこでVContainerを利用すればPresenterもModelとViewに依存しない形として実装することが可能となります。

サンプルプロジェクト

今回はUnity公式からデザインパターンの学習用としてリリースされているサンプルプロジェクトを使って見たいと思います。

github.com

こちらにMVPデザインパターン用のシーンがあります。

 

このシーンでは画面中央の的に対してマウスをクリックすると画面下部のHealth値とそれを示すバー(スライダー)が減っていきます。

これはマウスの入力(Clickイベント)を受け付けると

  1. Presenterに対してHealthの更新を依頼する
  2. PresenterはModelに対してHealthの減算を依頼する
  3. 同時にPresenterはModelが発行する更新ベントの受け手に登録
  4. ModelがHealthの減算を行い、更新イベント発行
  5. イベントを受けたPresenterがViewへ表示の更新を依頼

という順序で処理が行われます。

上図でもわかる通り、現状ではModelとViewは互いに疎結合ですが、PresenterはModelとViewに依存しています。

 

VContainerを導入

ここでVContainerの登場です。

 

まず事前準備としてPresenterは参照しているModelとViewのインスタンスをコンストラクタの引数に設定してVContainerから受け取れるようにします。

次にVContainerのLifeTimeScopeを継承したクラスを作り、その中でPresenter,Model,Viewを登録します。

各クラスの登録は必ずConfigureメソッド内で行いますが、登録に用いるメソッドはPresenter,ModelとViewで異なります。

Model、Presenterはそれぞれシーン内で一意で良いため、「Lifetime.Singleton」というオプションをつけて登録(Register)します。
Viewは、シーン内に存在するスライダー(Viewがアタッチされている)が処理の対象となるため、ヒエラルキー内でViewクラスがアタッチされているオブジェクトを探して登録する必要があります。この為、登録には「RegisterComponentInHierarchy」を使用します。

ここまで実装出来たらVContainerへの登録は完了したので、後はマウスクリックの入力を受け付けたタイミングでVContainerから取得したPresenterクラスへHealthの更新を依頼して処理を実行します。

■実装例

 

おわりに

VContainerの使用例の説明を行いました。

DIコンテナを導入することでSOLID原則に沿った綺麗な設計を行うことが出来る事が分かった思います。

とはいえ、このパターンを実装すれば色んな問題が解決する、というわけではないので導入前にはプロジェクト内のどの場面で利用できるのかきちんと整理する事が重要です。

 

宣伝

数学的脱出ゲーム「W.T.」早期アクセス版リリース中です。
歯ごたえのある脱出ゲームとなっているので腕に自信のある方のチャレンジ、お待ちしております。

store.steampowered.com

 

【アセット紹介】DIコンテナを使った疎結合デザインの実現 VContainer -概要編-

マスク

コロナ禍が一旦落ち着いてやっとマスクから解放されたと思っていたらインフルエンザと花粉症で再びマスク生活に戻った皆さんこんにちは。ここ最近外を歩くとマスクをしている人の方が多い気がします。電車とかノーマスクで乗っていたらちょと視線を感じるし。

 

SOLID原則

個人でゲームを開発している分には開発した本人がメンテナンスを出来さえすればどんなコードでも構わないのでしょうが、チーム開発だったり、私みたいに作っている最中に仕様変更を繰り返すような人間には出来るだけSOLID原則に沿った設計で開発を進める方が、後々の作業のし易さに直結すると思います。
SOLID原則とはソフトウェアの拡張性や保守性を高めるために設計時に考慮すべき開発原則で、ネットで調べれば解説記事が数多く上がっていますし、私もこのブログで記事にしています。

www.karvan1230.com

 

SOLID原則の中では基本的に各クラスは一つの役割を担うべき(複数の機能を持たない)なので、設計時に機能を細分化して各クラスに実装しますが、とはいえメイン処理に該当するクラスでは各機能を担うクラスへ処理依頼を出したり、処理結果を取得したりする必要があり、どうしても各クラスを参照する密結合な実装になりがちです。

密結合な例

 

そうするとメイン処理側は参照している各機能クラスが全て実装された後でないと実装できないし、各機能クラスが更新される度に影響を考慮する必要となります。

この為、それらの問題点の回避策として各機能クラスへの参照は共通的なInterfaceを介して行うようにする、といったデザイン設計がとられる事が多いです。
そうすることでメイン処理側も各機能の実装を待たなくても良いですし、各機能クラスの更新や入れ替えといった作業にも耐えうることが出来ます。

Interfaceを利用した疎結合モデル

 

上の図のようにメイン処理側が参照する各機能クラスのInterfaceは外部から渡される形式とすればメイン処理と各機能クラスは完全な疎結合な状態になることができます。では、各機能クラスのインスタンスは誰が生成してメイン処理に渡してくれるのか?
そういった役目を担ってくれるのが「DIコンテナ」と呼ばれるフレームワークになります。

DIコンテナの利用

 

VContainer

DIコンテナはクラス間の密な依存関係を外部で一元管理して疎結合な関係を実現し、問題を解決します。
Unityでは「Extenject(旧 Zenject)」といったアセットが有名ですが、今回は「VContainer」というアセットを取り上げます。

VContainerはExtenjectと比較して軽量で、シンプル形式のAPIを使用するため実装がわかりやすく、且つ無料です。
GitHubにunitypackageがリリースされているので、そちらをダウンロードしてUnityのプロジェクト内に取り入れる事ができます。

github.com

Unityでは基本的にGameObjectにMonoBehaviourを継承したクラスをアタッチして処理の起点としますが、VContainerを使用することで、純粋なC# クラスのエントリポイントをつくることができます。

これによりMonoBehaviourとは切り離して純粋なロジックのみのクラスを実装でき、より依存性が低い設計モデルを構築する事ができます。

 

概要

VCointanerは以下の流れで使用します。

  1. ContainerBuilderを生成
  2. ContainerBuilderに使いたいクラスを登録
  3. ContainerBuilderからIObjectResolverを生成
  4. IObjectResolverを通して使いたいクラスを取得

これを先ほどの図を使って表すとこんな感じ

VContainerを使用した関係図

手順だけを見ると少し複雑でコードの量が増える気さえしますが、上の1~3の部分はそれを担うコンポーネントがシーン内に一つあればよく、IObjectResolverから受け取るクラス(上の図ならMainService)はContainerBuilder内で一様(Singleton)に保持されているのでどこから取得されても同じものを使用する事ができます

これよりクラス間のデータの引き渡しもコンテナ内のクラス(上の図ならMainService)を介して行う事ができるので利便性が向上します。

 

Hello Worldは次回

概要の説明だけで記事が長くなってしまったので、具体的な使用例は次回紹介したいと思います。

 

【小ネタ】DOTweenのSetEaseの第二引数って何に使うのか

アベイラブル

「デフォルト」や「エビデンス」などの言葉を会話の中に混ぜる人はよくいますが「アベイラブル」を使ってくる人は初めて遭遇した皆さんこんにちは。どうやら「available=利用可能=手が空いてる」らしいのですが、何の連想ゲームですか?それなら素直に「手が空いてます」と言えよ。

 

福岡インディーゲームEXPO

先週末は東京ゲームダンジョン4が行われていた為、X(旧Twitter)やYoutubeでは展示作品の紹介や会場のレポート、プレイした感想等の投稿を見る事ができます。東京から遠く離れた地方民としては会場の様子を知ることができて有難い限りなんですが、やっぱり参加したかったなぁ、という思いが強いです。
去年初めて展示会イベントに参加して、自作ゲームを遊んでもらえて、直接感想を聞ける体験の重要さを知ったので、展示会イベントには積極的に参加しようと決めたのですが、東京に行くにも大阪に行くにもそれなりに時間と経費が掛かり、懐の関係上、おいそれと出掛ける事は出来きません。
出来れば地元の福岡でもインディーゲームの展示会イベントがあればなぁ、と思っていたところ、つい先日福岡インディーゲーム協会より「福岡インディーゲームEXPO」が開催される発表がありました!

www.fukuoka-indiegame.com

キャナルシティ博多で3/23,24の二日間行われること以外の詳細は発表になっていないのですが、展示会イベントに参加できず燻っている私にとっては非常に嬉しい発表です。
「福岡インディーゲームEXPO」は2022年にも一度開催されていますが、その時は参加できなかったんですよね。「次に開催された時は」と思っていたので、準備期間が約二か月とあまりありませんが、これから参加の準備を進めたいと思っています。まぁ、現時点では参加要項が分からないので参加できるのかわかりませんが。

 

Easing

DOTweenでEasingを指定する時は大抵「Ease.Liner」「Ease.InSine」などDOTweenが用意した列挙型クラスを使うのですが、変化率を確認しながら指定したい場合はAnimationCurveをSetEaseにそのまま指定することもできます。
一般的なEasingのAnimationCurveは有難い事に有志の方がPackageとして公開されているのでこちらを導入することをお勧めします。

baba-s.hatenablog.com

上記のPackage導入後は、AnimationCurveのウィンドウで歯車アイコン→Presetsから「EasingFuncitions」指定して使用することができます。

 

第二引数

DOTweenのドキュメントを確認して知ったのですが、SetEaseには特定のEasingにのみ対応したパラメータが存在します。

assetstore.unity.com


まず、Back系のEasing(InBack,OutBack)に対しては「Backする大きさ」を第二引数で指定できます。
試しにInBackでデフォルト値(1.70158)より大きな値を第二引数に指定して比べてみるとこんな感じ。

確かにBackする距離が伸びている事が分かります。

 

次にElastic系(InElastic,OutElastic)に対しては「振幅の大きさ」を第二引数で指定できます。
こちらも先程と同じようにデフォルト(1.70158)と、それより大きな値を第二引数に指定した場合を比べてみると

こんな感じで挙動に違いが出る事が分かりました。

 

EaseFactory

SetEaseには拡張的な使い方として「EaseFactory」を使用してストップモーションで再生しているかのように動作させる事もできます。
指定の仕方は以下のように、Easingをラッパーして第一引数に停める頻度?を設定するようです。

transform.DOMoveX(4, 1).SetEase(EaseFactory.StopMotion(5, Ease.InOutQuint));

イマイチ使いどころが分からないんですが、取り合えずEase.Linerについて比較してみます。

確かにTweenが途切れ途切れで再生されるような感じですが、EaseFactory.StopMotionの第一引数は「停める回数」の指定ではないようで、値を大きくすれば止まる回数は多くなりますが、値の回数分止まるわけではありませんでした

3を指定したら3回止まるわけではない。

う~ん、やっぱり使いどころが分からない。この機能を使った良いアイデアがある方はぜひご教授下さい。


◇プライバシーポリシー

●個人情報の利用目的

当ブログでは、メールでのお問い合わせ、メールマガジンへの登録などの際に、名前(ハンドルネーム)、メールアドレス等の個人情報をご登録いただく場合がございます。

これらの個人情報は質問に対する回答や必要な情報を電子メールなどをでご連絡する場合に利用させていただくものであり、個人情報をご提供いただく際の目的以外では利用いたしません。

●個人情報の第三者への開示

当サイトでは、個人情報は適切に管理し、以下に該当する場合を除いて第三者に開示することはありません。

・本人のご了解がある場合
・法令等への協力のため、開示が必要となる場合

個人情報の開示、訂正、追加、削除、利用停止
ご本人からの個人データの開示、訂正、追加、削除、利用停止のご希望の場合には、ご本人であることを確認させていただいた上、速やかに対応させていただきます。

アクセス解析ツールについて

当サイトでは、Googleによるアクセス解析ツール「Googleアナリティクス」を利用しています。

このGoogleアナリティクスはトラフィックデータの収集のためにCookieを使用しています。このトラフィックデータは匿名で収集されており、個人を特定するものではありません。
この機能はCookieを無効にすることで収集を拒否することが出来ますので、お使いのブラウザの設定をご確認ください。

●免責事項

当サイトからリンクやバナーなどによって他のサイトに移動された場合、移動先サイトで提供される情報、サービス等について一切の責任を負いません。

当サイトのコンテンツ・情報につきまして、可能な限り正確な情報を掲載するよう努めておりますが、誤情報が入り込んだり、情報が古くなっていることもございます。

当サイトに掲載された内容によって生じた損害等の一切の責任を負いかねますのでご了承ください。

●プライバシーポリシーの変更について

当サイトは、個人情報に関して適用される日本の法令を遵守するとともに、本ポリシーの内容を適宜見直しその改善に努めます。

修正された最新のプライバシーポリシーは常に本ページにて開示されます。