作ったミニゲームの制作過程とグラフの中身を書き残しておきます。24時間であほなゲームを作って遊ぶイベントで制作しました。
普通の制作後記でもよかったのですが、ビジュアルスクリプティングでの資料を案外必要としている方がいるようですので簡単に解説します。何かしらの参考になれば幸いです。
注意:1日で作ったゲームです。最適化の余地がかなりあります。変数名はガバガバです。プログラマーではないです。
完成品
制作したゲームはブラウザで遊べます。
ありがたいことに実況動画をいくつか確認しています。感謝感謝。
仕様
- しまうまクリックでスタート
- 左からハケが流れてくるのでクリック長押しでしましまを描く
- 結果判定
- リトライボタン(はい)
- シェアボタン(3つ)
- 音量調整あり
今回はUnity6000で作りました。WebGL(ブラウザで遊べるタイプ)です。
内容
準備
- 画像
- 背景を透過したpngファイル数点
- 音声ファイル
- BGM
- SE
- UI
- アイコン
- フォント
画像はペイントとマウスで描きました。背景になる白いしまうまと、上面に表示される線画のしまうまを用意しています。png画像で背景は透過します。ペイントを久しぶり開いたらレイヤー機能が追加されていて驚きました。すごい!! 1年前(2023年)に追加されたとのこと。
なんかアルファチャンネル?をUnity側で制御すれば1枚で済みそうですが、未履修なのでゴリ押しです。
プロジェクト作成
新しくUniversal 2Dテンプレートで新規プロジェクトを作ります。
ヒエラルキーウィンドウで、Assets以下に適当名前のフォルダを作り、そこに準備したファイルを全部入れます。
プロジェクト設定→プレイヤー→解像度の欄から画面サイズを決定します。今回は960×540で制作します。
時間がないのでSample Sceneでそのまま作ります。シーンは1つです。
出来上がり時点のヒエラルキーはこんな感じです。急いで作ったままなので性格が出ますね……。
ポストプロセス
本来は最後にやるべきだと思いますがここでポストプロセスを導入します。
メインカメラのインスペクターで、ポストプロセスにチェックを入れます。背景をソリッドカラー・白にします。
ヒエラルキーを右クリックし、ボリューム → グローバルボリュームを選択。インスペクターから新規グローバルボリュームのプロファイルを作り、VignetteやFilmGrainなどをお好みで追加します。
UI
今回使わせていただいたフォントは源暎アンチックです。使いやすいし見やすいしありがたい!
ウィンドウ→TextMeshPro→フォントアセットクリエイターでフォントの設定をします。
ヒエラルキーを右クリックしキャンバスを生成します。インスペクターでUIスケールを「画面サイズに拡大」にし、スクリーンマッチモードを「展開」に変更。今回は960×560にします。この設定変更を怠るとブラウザの拡大率によりUIが崩れます。
タイトルテキストなどを配置します。スライダーを2つ作り音量バーとします。
ゲームが終わった後の退出ボタンとシェアボタンも作っておきます。
退出や音量などの素晴らしいアイコン素材はこちらからお借りしています。
ボタンのソース画像は時間がないので「なし」にします。このシンプルな四角形が最近気に入っています。お好みでインスペクターからShadowを追加するといいかんじになります。今回は気分により以前セールで買ったTrueShadowアセットで影をつけます。
このアセットを買った当時は、デフォルトでShadow機能があることを知りませんでした。知ってたら買わなかったかも。もう元は取れた気がします。
グラフ
空のオブジェクトを追加し、GameControlなどの自由な名前をつけ、インスペクターの「コンポーネントを追加」から Visual Scripting→Script Machineを選択。
SourceをEmbed(埋め込み)にしEdit Graphからグラフを編集します。最初に作ったプロジェクトでは上手く開けないことがあります。その場合はシーンやプロジェクトを開き直せば開けます。
DoTweenを使いたいので、グラフで使えるように設定します。無料版の内容でも問題ありませんが、私は有料版を使っています。今回のUIの動きやハケの移動は全てDotweenで行っています。
タイトル
メインカメラにPhysics 2D Raycasterを追加。これがあればUI以外のゲーム画面をクリックできるようになります。
しまうまの画像を配置し、Box Collider 2Dを追加。形を良い感じに整えます。
背景には薄っすら暖色系のスプライトを配置します。
画面ができました。時間が限られているので出落ちって大事だと思うんですよね。分かりませんが。
マウスオーバーすると画像が変わって音が鳴り、マウスを離すと元に戻るようにします。
余力があればしまうまの表情をもっと豊かにしたかったですね。今も可愛くて気に入っています。
「ぬる」のあたりに黒いパーティクル(ループしない・開始時に再生しない)を作って置いておきます。
しまうまクリックでゲームを開始します。
タイトル後処理
On Pointer Clickは、ノードのコルーチンにチェックを入れておきます。そうしないとWaitノードでエラーになります。
- Particle System・Playで、作っておいた黒いパーティクルを飛ばす
- Play One Shotでボム音
- Set Activeでボタンになったオブジェクトを非表示
- その下に本体のしまうまを配置しておきます。それかスタート時に有効化します。
- Do Rotateで1秒かけてタイトルUI(音量バー)をY軸90度回転
- 以前は横移動させていましたが、フルスクリーンでずれてしまっていたので変更しました。
- Text Mesh Pro UGUI・Set Textでメインテキスト「しまうまです。」を(空欄)に変更
- Set ActiveでText「長押しでしまを塗る」を表示
- Set Activeで灰色のハケ(単体でDotweenで移動)を表示
- Wait For Secondsで2秒待つ
- Set ActiveでタイトルUIを非表示
- Set Activeで灰色のハケを非表示
シークエンスなどでもっと小分けにし、後から変更しやすいように配置したほうがよさそうです。
ここからはゲーム本編です。
開始処理
上のグラフにノードをつなげていきます。
- グラフ変数(Boolean)の「Start」を作り、Set Variableで有効化
- Startが有効の間はしまを書ける状態です。
グラフ変数(Float)のTime0を作り、SetVariableにGet Timeで開始時間を取得- 結局使っていませんでしたこの変数……。
- Set Activeでハケを有効化
- Do Move Xでハケを8秒かけて4.7(最終点)に動かす
- Dotweenは初期設定のEaseが勢いある感じなので、Set EaseでLinerにしておく
- Wait For Secondsで8秒待つ
これで8秒待ったらハケが遷移し終わります。このノードに続けて終了処理をします。
- Set VariableでStartを無効化
- Sequence1
- ボタンを押し続けている状態ならしまが塗り終わる処理をする(後述)
- Sequence2 続きのノードに繋げる
- Set Activeでメインテキストを表示
- Set Activeで「長押しで塗る」テキストを非表示
- Sequence1
- Set Activeでハケを非表示
- Set Activeで集中線を表示
- Play One Shotで歓声を鳴らす
- Set Textでメインテキストに「完成!」を代入
- Do Colorで背景に配置した四角形スプライトの色を0.2秒かけて白色に変更
- Do FadeでBGMの音量を0.5秒かけて0に変更
- Sequence2 Wait For Secondsで3秒待つ
- Sequence3(結果判定)
- Sequence4
- Wait For Secondsで2秒待つ
- Set ActiveでUI(リトライボタンとシェアボタン)を表示
しましまを描く!!
いろいろな方法がありそうですが、今回はInstanceでしま(プレハブ)が生成されるようにしました。
生成したしまはボタンを押している間、Set Local ScaleでX軸方向に伸びるようにします。
開始した時間をGet Timeで取得して変数に保管。塗っているときの時間をハケが通り過ぎる時間(8秒)で割ることで、X軸全体のどこを塗っているか指定できます。
On Updateにノードをつなげていきます。ゲーム開始中か判断します。3つのIf判定を使っています。
Get Mouse Button Downで、クリック中かどうか判定できます。クリック中ならしまを塗り始めます。
Get Mouse Button Upで、クリック終了が分かります。その場合、しま塗り終わり処理をします。
それ以外でボタンを押している状態ならしまを伸長します。
マスク
ShimauMaskという渾身の名付けをした白色しまうまSpriteに、インスペクターでSpriteMaskを追加します。マスクのスプライトに白色しまうま画像を設定します。
しまオブジェクトを作ります。縦に細長くし、デフォルトの横幅は0にします。中心(ピボット)は左端にしておきます。プレハブにします。Sprite Rendererの設定でマスクインタラクションを「内部マスクの可視化」にします。レイヤーの順序は白色しまうまより大きい数字にします。しまを横方向に伸ばし、マスクに収まっているか確認します。
塗り始め
- Instantiateで縞プレハブを生成
- SetVariableでグラフ変数nowShima(Game Object)に生成した縞をセット
- Set PositionでハケのX位置に設置
- ハケの位置はGet Position → GetXで入手
- Set Variableでグラフ変数Pressing(Boolean)をON(押している状態か否か判定用)
- Set Variableでグラフ変数TimeD(Float)にGet Timeの時間を記録(塗り始め時間)
- SetOneShotで効果音再生
- Particle System・Playで黒色インクのキラキラを再生
あとはお好みで、結果用に本数を記録するなどします。
塗り終わり
- Set VariableでPressing変数をOFF
あとはお好みで結果判定用にどれだけ塗ったか記録するなどします。MAXの縞を記録するようにしたのに結局実装が間に合わないなどしました。心はあります心は。
伸長
しまを長押ししている状態(PressingがON)ならしまを伸ばします。変数名から英語が苦手なことが伺えます(ファイル名がShimaumaの時点でもうテキトーです)。
Set Local ScaleでしまをX方向に伸ばします。しまを塗り始めたときと現在との時間差を全体の秒数(8s)で割り、それに横方向の全体の長さ(8.37)を掛けて横の長さを決定します。
結果判定
しまが作られた本数と、全体が塗られた比率をグラフ変数に保存しておき、そこから結果が分岐するようにします。より細やかに、最大のしまの大きさや部位別の明暗を判定に影響させることもできますね。はい。
結果をIFで分岐させ、Set Textで結果のテキストを変更、Play One Shotで効果音を鳴らします。その他お好みで背景画像を追加したり、マテリアルを変更して残像的表現をしたりします。
ifでゴリ押ししていますが、本来はSwitchなどで条件分けしたほうが美しいのでは。
結果はたくさんあったほうが楽しいですね。
その他
リトライボタン
退室あるいは了承ボタン
DotweenのインスペクターでColorが変化する全体フェードを作っておき、それを有効化します。0.5秒後にシーンを再読込しています。
シェアボタン
シェアボタンの作り方は以前書きました。ボタンを3つ作ったおかげで、配信で3箇所にポストしてもらっちゃいました。感謝! (ボタンを作ったもののX以外のSNSは全然使いこなせていません……それどころかXすら活用できていない状態です。陳謝。)
時間があれば結果によってポスト内容が変わるようにするのがベストだと思います。
音量調整
以前書いたのと内容は大体同じです。
アプリ変数にBGMとSEをそれぞれFloatで作っておきます。BGMの初期値は0.2で、SEはそれより若干大きめにしています。アプリ変数にすればシーンを再読込しても変数が残っているので、その数値でバーの初期値を変更します。
今まで何度かゲームを実況していただく機会に恵まれ、その結果、数値は0.2くらいがいいのかなというところに落ち着きました。
ビルド
完成したのでunityroomに投稿しました。今回ランキング機能は使っていないので、PLiCyやitch.ioなどの別の投稿サイトに投稿しても良かったかもしれません。
配信でサイトと相性が悪かったらしく申し訳なく思いました。容量を使わせていただくのも申し訳ないですし、今後はなるべく自分のサイトに置いたほうがいいのかなと思いました。それはそれでWordpress初心者なのでちゃんと設置できるか心配ではありますが……。
WebGLの仕様上、最初に画面をクリックしないと音が鳴らないです。余裕があれば「クリックで開始」などのワンクッションを置いたほうが親切なのでは。
イベント所感
厳密な締切に1時間ほど遅刻してしまいました。「守らなくて大丈夫な締切」と公式が言ってくださっているほどですが、自分としては反省しています。
あほについての理解は道半ばですが、今回は少し手応えを感じています(イベント後の万能感)。他の参加者の方々は1日でオセロを作るなど技術的にもすごいな~と思うことをしているので、私も精進したいと思います。
おわりに
AIがコードを提案してくれるようになった昨今では、ますますVisual Scriptingを使い続けるメリットは少ないように思えます。学習用には良いかもしれませんが、これからUnityを始めるというかたにはそこまでおすすめできないかなあという気持ちです。……とはいえ私はVisual ScriptingがなかったらUnityを始めていなかったと思うので、とりあえず始めやすい方法で始めればいいと思います! C#スクリプトと併用できるので学んで損ということもないのでは。
というわけでVisual Scripting使用者に限らず、この記事が何らかの形で役立つことを祈っています。
はい。