tanaka's Programming Memo

プログラミングについてのメモ。

LEGO MicrogameのBUILD YOUR OWN GAME!コンテストに応募しました!

子供の時に遊んでいたLEGOがUnity上で動く!

そんなUnity Hubからインストールできる学習プロジェクトの一つLEGO Microgameを使ったゲームコンテストがLEGO IDEASで開催されるということで応募してみました。応募総数は1,150作品!? 盛り上がってます。

コンテストページはこちら。

ideas.lego.com

応募したゲームは以下から遊べます。

ideas.lego.com

日本だと「ブロック」って言ってますけど、英語表記だと「Brick(ブリック=レンガ)」なんですね。今回初めて気づきました。

目次

制作過程

2/1のUnityさんのツイートでコンテストを知りました。

この直後にUnity Learningが日本語化され、LEGOチュートリアルも日本語化されました。

2/18に青木ととさんが解説してくださいましたUnityステーションのLEGO® を使ったゲーム開発コンテスト「BUILD YOUR OWN GAME!」に参加しよう!YouTube動画で概要を把握した辺りから実働開始。

Unity Hubで2019.4.xや今なら2020.3.xで新規プロジェクトを作成する際に、左のテンプレートに注目するとLEGO Microgameがあります。これをチュートリアルでインストールすると、使い方を短い動画などで知ることができるので、それをざくざくやっつけていきました。

f:id:am1tanaka:20210323180546p:plain
LEGO Microgameのテンプレート

この当時は基本的な指示は日本語化されてましたが動画内は英語でした。操作は出ますし今どきはGoogleアプリとかで簡単に和訳できるので大丈夫だと思います。

動画をぼんやり聞いていたため肝心なところを聞き逃していて備忘録的にツイートしたら青木ととさんからお返事いただけました!ありがとうございました!!

LEGO Microgameで作った作品はunityroomにアップできないということで、習作を1週間ゲームジャムに、という野望は潰えました。今回はLEGOを触りたかったのでこちらのコンテストに専念です。

2/19にLEGO Microgameの組み込みチュートリアルとUnity LearnのLEGO® Microgame - Unity Learnは完了。チュートリアルでは分からなかった実行時にブロックをくっつけたり離したりができるかと、プレイヤーやカメラの制御を追加で調査。

一通り把握できたところで、マウスでクリックした場所に歩かせたり、カメラの操作を試作しはじめました。

この時に作ったカメラのシステムをGet the Ship Back!に採用しています。操作の方は動くブロックに乗り降りする操作などが難しそうだったので、元のLEGO Microgameの操作で進めることにしました。

経験を積んでいるうちに良い設定を発見。Hierarchyは荒れますが細かく調整する場合はこの設定は重宝しました。あとブロックの色を変えるパネルが出たり出なかったりしたのはプレハブの解除が必要でした。チュートリアルでプレハブの解除をしていたのはあったのですがその時はピンと来ておらず、試行錯誤しているうちに再発見しました。

こんな問題も発生しました。そのため予定外のものもStudioで組み立てることになりましたが、これがまた楽しくなってしまって時間が溶けました。

ストーリーや設定を導入のムービーとかで伝えたいけど時間が・・・ということで、なんとなくそういう感じのタイトル画面を作って解決!したことにしました。

最後の最後にこんな不具合も。

1つだけWebGLだとエラーになるステージがあって、その原因がこれでした。staticで軽くできるかと思ったのが仇に・・・。

以下のも最終日に発生したやつ。

「エネルギークリスタルを全て取っていたら、レーザー砲に触れるとクリアできる」という条件を作りたいのだけど、トリガーのネストができないのです。追加の条件はVariableで与えられるのでそちらでやったら、なぜか別のステージに前のステージの条件が表示される。なんでだ!?となったやつでした。

以上で公開しました。LEGO Microgameの事前調査2日+企画&制作3週間ぐらいの楽しいLEGO生活でした^^

間に合わなかった要素

時間がものすごくギリギリになってしまったので、いくつか思いついていた要素を省きました。

  • クリアまでのタイムアタックができるようにしたかった
  • 目標物のミニレーダーが欲しかった
  • カメラは上も見られるように調整した方がよかったかも
  • Stage7の4つの黄色スイッチは、押すごとに敵の足場を一つ一つ爆発させたかった
  • Stage7の敵を喋らせたかった
  • 最終ステージの高速化をしたかった

コンテストが終って手を入れてよくなったら追加するかも知れません。

ステージ紹介

あまり遊ばれないならせめてステージ紹介だけでも・・・。これを見て楽しそうに感じたら遊んでいただければ嬉しいです!!

Stage1

チュートリアルステージ。ほぼ死ぬ要素がない練習ステージ。

f:id:am1tanaka:20210325112358p:plain
ゲームスタート!

奥に見える赤い仕掛けのところの爆発に巻き込まれて死ぬ、という想定外の仕様上の死因以外はほぼ死にどころはありません。スイッチを押しながらずんずん進んでください。

f:id:am1tanaka:20210325113533p:plain
マウスホイールでズームアウトしてステージ全体を見る

クリアするとこんな感じで宇宙船のパーツが組み立てられていきます。

f:id:am1tanaka:20210325113440p:plain
最初のパーツを回収!

Stage2

順番がある、と気付くステージ。細いところを渡るスリルなんかもちょこっと入れました。

f:id:am1tanaka:20210325130112p:plain
ここもショートステージ

f:id:am1tanaka:20210325113455p:plain
でも何も考えてないと詰みます

f:id:am1tanaka:20210325113515p:plain
尾翼を回収!

Stage3

ここからが本番。お気に入りの回る足場から、レーザーを避けたり、仕掛けを組み合わせたり。

f:id:am1tanaka:20210325113724p:plain
タイミングよく渡ろう

f:id:am1tanaka:20210325113609p:plain
レーザーを避ける!

f:id:am1tanaka:20210325113638p:plain
左奥に辿り着くための足場をどうやって作ろうか・・・

Stage4

高台からステージ全体を見渡してから飛び降りて、一番下から登っていく高さを意識したステージです。途中の階段や回転足場がお気に入り。

f:id:am1tanaka:20210325114134p:plain
ステージを一望

Stage5

基地にたどり着け!このステージは回収するものがなく、攻撃をかいくぐってゴールを目指します!

f:id:am1tanaka:20210325114254p:plain
いきなりの砲撃!物陰に隠れてタイミングよく飛び出そう

f:id:am1tanaka:20210325114324p:plain
敵の猛攻!あと少しでゴール!!

Stage6

敵基地に潜入。高さ方向にエレベーター中心に作ったステージです。

f:id:am1tanaka:20210325114422p:plain
スタート地点から仕掛けを観察

f:id:am1tanaka:20210325114511p:plain
エレベーターをうまく使って移動しよう

Stage7

敵アジトの本部へ!

f:id:am1tanaka:20210325114619p:plain
レーザーは扉を閉めて遮断!

f:id:am1tanaka:20210325114657p:plain
怪しげな二人組!こいつらが今回の元凶

Stage8

最終ステージ。塔を登りながらクリスタルを集めて、最後のパーツのレーザー砲で巨大砲台を壊そう!

f:id:am1tanaka:20210325114937p:plain
あのどでかいレーザーに撃ち落された。あれを壊さないと同じ事に...

f:id:am1tanaka:20210325115140p:plain
塔を登りつつ、エネルギークリスタルを回収

f:id:am1tanaka:20210325115205p:plain
エネルギーが充填されたレーザー砲に辿り着いた!ついに...

さいごに

開発は3週間程度と思ったよりかかりましたが、ずっと楽しく作れました。実在のレゴブロックのモデルで組み立てられるツールStudio2.0でオブジェクトを作るのは楽しいですし、実在するブロックなので注文すれば実物を作れる可能性があるのも魅力です。

f:id:am1tanaka:20210328211501p:plain
BrickLinkのLEGO組み立てツールSTUDIO2.0

複雑なことをやろうとするとハマりポイントがありますが、シンプルな仕掛けならBehaviourBrickが充実しているので色々できます。カメラはCinemachineなので簡単に調整可能ですし、プレイヤーも調整用のパラメーターが多いですし外部のスクリプトからある程度の制御も可能です。

ちょっと残念だったのは継承が想定されていないクラスが結構あることでした。もとの動作がハードコーディングされていることがあったりして、その部分を変えたい時に難儀しました。もう一つの残念ポイントはUnity Playでしか公開できないことです。これはかなり痛い。ブロックを複雑に組み合わせることができたり、くっつけたブロックが持っている全ての動作を実行するなど手軽に使えるように工夫されていますが、その分、処理が重くWebGLだとパフォーマンス的に結構厳しいです。ネイティブでビルドできれば・・・とか、VRで使ってみたい、とか、可能性が大きそうなだけに発表先の自由度が低いのは残念です。軽量化されるか、発表先の自由度が増すか、今後の展開に期待しています。

テンプレートからプロジェクトを作ればチュートリアルを通して簡単な使い方が分かります。LEGOや積み木が好きな人は楽しめるのではないかと思います。今回は以上です。後日、作り方なども書いていきたいと思います。

ideas.lego.com

おまけ

無事に応募した記念に買ってしまいました。グローグーを組み立ててみましたが、ブロックがぱっちりハマる手応えは楽しいですし、色々なくっつけ方ができることにも驚きました。楽しいですね、LEGO

f:id:am1tanaka:20210326202953j:plain
ご褒美

f:id:am1tanaka:20210329172032p:plain
LEGOグローグー

関連URL

Unity2017のプロジェクトを2020LTSにアップグレードする

Unity2017時代のUnityのプロジェクトをまとめて2020LTSにアップした時にやったことのメモです。

方針

いっきに2017から2020へアップすると問題が多くて手が追えなかったので、2017 > 2018LTS > 2019LTS > 2020LTSと段階を経てアップしました。アップする過程で起きたことです。公式のドキュメントのアップグレードガイドを読めばちゃんと対応が載っていると思いますが、1週間ゲームジャムの小さいプロジェクトなので起きた問題だけ対処すればいいやということで進めました。

2017から2018LTSへ

TextMesh ProがAsset StoreからPackage Managerに移行して互換性が無くなった時期です。

  • Unity Hubでバージョンを2018LTSとプラットフォームを設定して開く
  • Assetsフォルダー下のTextMesh Proフォルダーを削除
  • Standard Assetなどを使っているとエラーが出ているかも知れないので不要なものは削除
  • Package ManagerからTextMesh Proをインストール
  • TextMesh ProのEssential Resourcesと、必要に応じてExamples and Extrasをインポート
  • TextMesh Proメニューから Project Files GUID Remapping Tool を起動して、バージョンアップによる不具合を解消

また、PostProcessing StackがV1とV2で揺れていた時期です。V1ならバージョンアップ前にプロジェクトをコピーしておいて、古いプロジェクトを開きながらV2の設定をしました。

2018LTSから2019LTS

Post Processingがエラーになるのでバージョンアップしました。Post Processing Volumeの設定はバージョンアップ後も引き継がれたので、古いPost Processingのフォルダーを削除したあと、Package Managerからインストールし直しました。

また、不要な設定が多数残るようなので、Libraryフォルダーを消して再読み込みした方がよさそうです。

2019LTSから2020LTSへ

WebGLビルド時のエラー

WebGLビルド時に、FinalPathシェーダーでエラーが出る場合があります。これについては以下に書きました。

古いプロジェクトをUnity2020へアップデートした時のWebGLビルドのエラー - tanaka's Programming Memo

Player SettingsのWebGLのOther Settings内にあるAuto Grahpics APIのチェックを外して、Graphics APIを一度削除して再設定して解決しました。何もしなくても2回目のビルドで通ることもあったのでよく分かりません。

その他もろもろ

どこかの段階で出てきたやつです。

ProCore関連

PolyBrushやProBuilder、ProGridといったProCore系のアセットが大量にwarningを吐きます。放置していてもとりあえず動きいますが、直したい場合は Assets/ProCore フォルダーを削除して Package Manager から再インストールします。

PolyBrushでいじったProBuilderのオブジェクトにはz_AdditionalVertexStreamsスクリプトがアタッチされます。うっかりPolyBrushもういらない、と思ってインストールしなかったらwarningが大量発生しました。PolyBrushをインストールするか、missingになったスクリプトをRemoveすれば解決します。

Cinemachine

これもwarningが発生。気になる場合は、Assetsフォルダー内のCinemachineフォルダーを削除して、PackageManagerでインストールします。Player SettingsのOther SettingsにあるScripting Runtime Versionが.NET 4.x Equivalent以上になっていないとエラーがでます。

GUI Layerの削除

GUI Layerが不要になるので、Cameraにアタッチされている場合は削除されます。自動的に削除してくれるので、シーンを開いて変更が起きたら保存すればよさそうです。

Flare Layer

カメラにアタッチされていたFlare Layerが不要とwarningが出るのでRemoveします。

ユニティちゃんトゥーンシェーダー

SuriyunさんのCute Petがユニティちゃんシェーダーを使っていてエラーが出ました。古いシェーダーを削除して、新しいユニティちゃんトゥーンシェーダー(2.0.7を入れました)をインポートして、マテリアルのシェーダーを選択し直して、設定もし直しました。

また何か出てきたら書き足します。

古いプロジェクトをUnity2020へアップデートした時のWebGLビルドのエラー

古いプロジェクトを2020LTSにバージョンアップした後にWebGLでビルドしようとすると、Post ProcessingのFinalPass関連で以下のような2つのエラーに遭遇しました。

Shader error in 'Hidden/PostProcessing/FinalPass': Input signature parameter  (1-based Entry 3) type must be a scalar uint. at line 44 (on gles)

Compiling Vertex program with STEREO_INSTANCING_ENABLED
Platform defines: UNITY_ENABLE_REFLECTION_BUFFERS UNITY_USE_DITHER_MASK_FOR_ALPHABLENDED_SHADOWS UNITY_PBS_USE_BRDF1 UNITY_SPECCUBE_BOX_PROJECTION UNITY_SPECCUBE_BLENDING UNITY_ENABLE_DETAIL_NORMALMAP SHADER_API_DESKTOP UNITY_COLORSPACE_GAMMA UNITY_LIGHTMAP_FULL_HDR
Disabled keywords: FXAA FXAA_LOW FXAA_KEEP_ALPHA FXAA_NO_ALPHA STEREO_DOUBLEWIDE_TARGET UNITY_NO_DXT5nm UNITY_ENABLE_NATIVE_SHADOW_LOOKUPS UNITY_METAL_SHADOWS_USE_POINT_FILTERING UNITY_NO_SCREENSPACE_SHADOWS UNITY_PBS_USE_BRDF2 UNITY_PBS_USE_BRDF3 UNITY_NO_FULL_STANDARD_SHADER UNITY_HARDWARE_TIER1 UNITY_HARDWARE_TIER2 UNITY_HARDWARE_TIER3 UNITY_LIGHT_PROBE_PROXY_VOLUME UNITY_HALF_PRECISION_FRAGMENT_SHADER_REGISTERS UNITY_LIGHTMAP_DLDR_ENCODING UNITY_LIGHTMAP_RGBM_ENCODING UNITY_VIRTUAL_TEXTURING UNITY_PRETRANSFORM_TO_DISPLAY_ORIENTATION UNITY_ASTC_NORMALMAP_ENCODING SHADER_API_GLES30
Error building Player: Shader error in 'Hidden/PostProcessing/FinalPass': Input signature parameter  (1-based Entry 3) type must be a scalar uint. at line 44 (on gles)

Compiling Vertex program with STEREO_INSTANCING_ENABLED
Platform defines: UNITY_ENABLE_REFLECTION_BUFFERS UNITY_USE_DITHER_MASK_FOR_ALPHABLENDED_SHADOWS UNITY_PBS_USE_BRDF1 UNITY_SPECCUBE_BOX_PROJECTION UNITY_SPECCUBE_BLENDING UNITY_ENABLE_DETAIL_NORMALMAP SHADER_API_DESKTOP UNITY_COLORSPACE_GAMMA UNITY_LIGHTMAP_FULL_HDR
Disabled keywords: FXAA FXAA_LOW FXAA_KEEP_ALPHA FXAA_NO_ALPHA STEREO_DOUBLEWIDE_TARGET UNITY_NO_DXT5nm UNITY_ENABLE_NATIVE_SHADOW_LOOKUPS UNITY_METAL_SHADOWS_USE_POINT_FILTERING UNITY_NO_SCREENSPACE_SHADOWS UNITY_PBS_USE_BRDF2 UNITY_PBS_USE_BRDF3 UNITY_NO_FULL_STANDARD_SHADER UNITY_HARDWARE_TIER1 UNITY_HARDWARE_TIER2 UNITY_HARDWARE_TIER3 UNITY_LIGHT_PROBE_PROXY_VOLUME UNITY_HALF_PRECISION_FRAGMENT_SHADER_REGISTERS UNITY_LIGHTMAP_DLDR_ENCODING UNITY_LIGHTMAP_RGBM_ENCODING UNITY_VIRTUAL_TEXTURING UNITY_PRETRANSFORM_TO_DISPLAY_ORIENTATION UNITY_ASTC_NORMALMAP_ENCODING SHADER_API_GLES30

シェーダーコードを見るとpragmaのラベルで未定義のがあるような感じでした。

解決法

Player Settings の WebGL の Other Settings 欄にある Auto Graphics API のチェックを外して、WebGL 1.0やWeb2.0を一度削除して、また設定することで直りました。

ざっくり、以下手順の一例です。

  • UnityのEditorメニューから Project Settings を開いて Player を選択(Fileメニュー > Build Settings > Player Settingsでも可)
  • WebGL の Other Settings を開く
  • Auto Graphics APIのチェックを外す
  • Graphics APIs 欄にあるWebGLの設定を削除
  • Graphics APIs 欄の右下の + をクリックして設定を追加しなおす

以上です。

Unity Download Assistantとは

Unityをバッチやオフラインでインストールできるようにしようと公式ドキュメントを読むと、唐突にUnity Download Assistantというのが出てきました。

docs.unity3d.com

何のことかと思ったら、Winやmac用のインストーラーのことでした。以下のダウンロードページから、必要なバージョンのインストーラを入手したら、あとは公式ドキュメントに従えばよいということになります。

unity3d.com

f:id:am1tanaka:20210318213710p:plain
これでダウンロードするやつがDownload Assistant

インストーラーを起動したら、公式ドキュメントと同様にダウンロード先やインストール先のフォルダーを自前で作成したものにしておくのが吉です。

Unityのインストール先は2021/3/18現在だとC:\Program Files\Unity\Hub\Editor\2019.4.11f1のようなパスがよさそうです。

【Unity】WebGLでA scripted object (script unknown or not yet loaded) has a different serialization layout when loading.とかいうエラー

WebGLで実行する時に以下のようなエラーが出て、正常に動作しないことがありました。

A scripted object (script unknown or not yet loaded) has a different serialization layout when loading. (Read 52 bytes but expected 92 bytes)
Did you #ifdef UNITY_EDITOR a section of your serialized properties in any of your scripts? 

この時の原因はScriptableObjectの作成ミスでした。ScriptableObjectのクラスを他のクラスの中に含めていると、アセットからクラスが参照できずに地味に不具合が出ます。スクリプトファイルのところが正しく表示されていなければ多分これが原因です。

ScriptableObject用にスクリプトファイルを作り直したのはよかったのですが、ScriptableObjectのアセットを作り直さないといけないのを忘れていたのが今回のエラーの原因でした。アセットを作り直すことで解消しました。

1週間ゲームジャム"あける"に参加しました!

2020年最後のUnity1週間ゲームジャム"あける" に参加して、「光花(KOHKA)」という音ゲーを作りました!

f:id:am1tanaka:20201228120004g:plain

光花-KOHKA- | フリーゲーム投稿サイト unityroom

参加しましたブログです。

目次

参加の狙い

今回は専門学校の1年生の皆さんが挑戦できるタイミングだったので、講義の一環としての参加でした。ということで、以下のような狙いを持って参加しました。

  • これまでに講義で扱った技術の応用例を示す
  • 一緒に参加することで開発意欲を促す
  • 今後の講義の題材にできそうなプロジェクトの作成
  • Slackの練習

作業の流れ

ざっくりと作業の流れです。

開催前

開催の2週前から1週間ゲームジャムを想定して、以下のようなことに留意して企画を考え始めてもらいました。

  • 「よけとる」をどのように改造できそうか
  • 使ってみたい技術、アセットの調査
  • 1~2日で作り切れそう
  • 面白くないと感じてもまずは完成させられそうなもの

自分も12/12にこんなツイートして企画案から考え始めてます。

このタイミングでは、色を変えるとか、大きさを変えるとか、角度を変えるとかしてマップの見方が変わるようなタイプのパズルが気になってましたが、よけとると全然違うので没にしました。それはまたいずれ。

1週間前の週は、企画を進めるとともに1週間ゲームジャム用のプロジェクトを作成して、WebGLに切り替え、解像度設定、BGMやSE再生、簡単なシーン切り替え、ネットランキング実装、仮ゲームの実装を行いました。自分もこのタイミングで以下のところまで開発を進めました。この時はBGMは d-elf.com さんのダンス系のを使ってました。

音との同期は既存のアセットなどは使わず、AudioSourceのtimeSamplesを参照して自前で計算しています。講義でやっていない内容は使えないルールなので、計算方法を以下のブログにまとめて紹介しました。

am1tanaka.hatenablog.com

BPMが分かっていてテンポが一定の曲であれば、掛け算や割り算で対応できます。

お題発表

お題は"あける"。ちょっと考えていた方向性と違ったのですが、タイミングが合った時に内側の円が開いて光る → 沢山タイミングを合わせると夜が明けていく → 最終的に花が開くとかでいいか? → 開く演出を花にして開花でいいのでは...というように演出の方向性を連想していって、素振りプロジェクトをそのまま本プロジェクトにして進めることにしました。

なんとなくダンス系より和風かな?ということで、それならH/MIX GALLERYさんに良いのがあるに違いないと選曲をやり直して、今回のタイトルと本編の曲を探し出しました。結果も英語ではなく感じに変更。あとは出現パターンの調整です。

1,2日目

12/21(月)から作業開始。この2日間は学生さんが講義中は作業できないだろうということで、同じ条件にするために16時半過ぎから作業を始めました。

  • タイトルを光花(KOHKA)に変更
  • タイミング判定や画面跳ね返りの不具合修正など
  • 出現場所をランダムから種に変更
  • 種のオブジェクト作成

3,4日目

水木は講義なので、講義中と帰宅後の作業です。

  • 選曲
  • 種の移動データと移動処理
  • 種の円速度設定パターン作成
  • ステージデータ作成
  • タイトルからランキングを呼び出す
  • WebGLビルドとunityroomへの投稿確認

この段階で、一旦ゲームとしては完成しました。まだ開花の演出が円のままだったりで、演出は現状のものとは違ってました。

5日目

この日は卒業制作だったので日中は作業無し。帰宅後も他のことをしていて、作業開始は22時から。以下のみ進めました。

  • 正解時の花の演出作成

6, 7日目

締め切り前の土日。土曜日は数学の問題解いたり別のことをしていて15時過ぎから作業開始。日曜日も作業開始は14時ごろから。

以上で、日曜の17時半ごろに公開予約ができました。このぐらいのタイミングで完了できたのはYOKETORU改か秒速忍者以来?良いペースで完成までたどり着けました。

恋しかった技術

1年生の講義で扱った技術縛りのために使えなかった技術のうち、特に使いたかったものを挙げます。

継承 / ポリモーフィズム

なんといってもこれ。これらが使えないとコピペや分岐が増えて増えて...。switchで分岐させて呼び分ければ解決はできるものの、ポリモーフィズムですっきりさせたい、という欲求が強かったです。

この辺は使いどころが想像できるぐらいの開発経験がないと、ただ習うだけでは必要性が実感できない技術だという印象を持っています。「なるほどこれは便利!」と思える体験を積んでから教えるカリキュラムにしているので正に狙い通りなのですが、早く講義で扱いたいです!

今回のプロジェクトは、シーンの管理やチュートリアルとゲーム中での振る舞いの違いなどをきれいに解決してみせるよい教材にできそうです。

ScriptableObject

こちらもある程度まで経験を積まないと、使いどころが分かりづらい機能ではないかと思ってます。別の場面で使い回したり、修正するような開発経験がないと、インスペクターで設定すればいいじゃん、となってしまいがち。ステージデータの作成や色の設定を別オブジェクトに適用するなど、今回は手作業でちまちまと書き写したりコピペで対応しました。ポリモーフィズムと組み合わせればPluggableな仕組みも作れる本当に強力な機能です。

TextAsset

これは講義で扱っておくべきでした^^; これとSplit()による文字列分割を知っていれば、データ設定ではScriptableObjectの代用が可能でした。Paizaの対策にもなるので、来年度には反映させたいと考えてます。

Slackの利用

Slackは今回が初運用で、良さげな方法を手探りしつつ使いました。

最初は「#1週間ゲームジャム」チャンネルを作ってそこにみんなで報告を書いてもらいましたが、1日だけでも前の発言が埋もれてしまい、発表時に学生の書き込みをまとめて見ることができずに不便なので変更することにしました。

個人チャンネルを作ってそこに報告するというのをUnityゲーム開発者ギルドさんでやっているというのを読んでいたので、それを真似てみたところ情報が追いやすくなりました。

報告の仕方もあれこれ試してみて、今のところ以下のスタイルに落ち着きつつあります。

  • 作業開始時に「作業開始」という言葉に続けて、箇条書きでTODOリストを書く
  • TODOリストの作業が1つ完了したら、その時点で箇条書きで完了した作業項目を書いて日時を残す。ついで、作業開始時のTODOリストを編集して、完了した項目に「(完了)」など書き加える
  • その日の作業が終わったら「今日の作業終了」と書き込む
  • 作業内容をまとめたい時は、続けて箇条書きで残りの作業を書き出す

TODOリストはまとめて置いてあった方がいいのでTrelloに持って行って、Slackにはリンクを貼っておく方がよさそうかな?と思いつつ、今回くらいの規模ならこれでいけました。

まとめ

準備期間をしっかりとって、企画も欲を出さずにまとめやすい方向にしたので余裕をもって公開できました。講義内容でできることを示した上で、オブジェクト指向のあれこれやScriptableObject、SOLID原則なんかを知ることで、よりスッキリしたコードが作れることを示すための土台にもできそうで、今回も良い収穫がありました。

Slackでの作業経過もなんとなく雰囲気が掴めたので今後に活かせそうです。特に今は新型コロナの動向次第では、いつリモートになるか分からない状況です。これまでは卒業制作などの演習科目をどうするかを検討していましたが、Slackによる進捗管理ができるようになれば、あとはGoogle MeetやZoomなどの会議サービスと連携させればなんとかなりそうな手応えを得られました。

狙いのうち「開発意欲を促す」についてはアテが外れましたが、今後の課題として明確化ができました。

企画の面では、他の皆さんの作品を見るとストーリー性というかキャラクター性が出ているものが魅力的に見えました。一発アイディアで世界観を出した上で面白いものを企画し、間に合うように完成させる瞬発力は本当に凄いです。回を重ねるごとにそのような作品が増えていて、収穫が多く、いい勉強、刺激になるゲームジャムです。自分はなかなかそういう感じのものは作れないのですが、継続していたらいずれ何か得られるかも知れません。継続できるペースを保ちつつ、また次回を楽しみにしています。

次回に向けて

企画的に気になっている方向性など現時点での考えを。

  • 大きさ、色、角度、奥行などを変化させることで、ステージの見え方が変わる何か
  • モチーフはプリミティブで
  • 音楽はやっぱ使った方がよさげ
  • 少しストーリー性というか、物語性が出せないか
  • VoxelorerBirdを進めたいので重くならないように

こんなところでしょうか。最初のやつを実現するためにモチーフの研究を軽くでいいので継続したいところですが、他にもあれこれやりたいことが積み上がっているのでできたらいいなというぐらいで。

次回は時期的には春休み辺りになりそうでしょうか。講義が始まっていても6月ぐらいまでは落ち着かないので、Slackでの報告や質問は実施しますが、学生さんは任意参加として今回のように講義で進めることはないと思います。それぞれの考えのもとに参加する人は次回も頑張っていきましょう!

学生さん作品

今回参加した学生さんたちの作品です。公開先が確認でき次第、追加予定です。掲載は名簿順です。

unityroom.com

unityroom.com

unityroom.com

ホペ君は自主的に継続してゲーム開発に取り組んでまして今回が4作品目でした。素晴らしいペース!

最後に

2020年もあとわずか。今年一年お世話になりました。また来年もよろしくお願いいたします。

参考・関連URL

曲のビートのタイミングを計算する方法

f:id:am1tanaka:20201216204931g:plain

曲に合わせた動きは、気持ちよい演出が作りやすいです。

Unityでこれをやるものとして、geekdrumsさんのMusicEngineが有名です。

github.com

1週間ゲームジャムで公開したYOKETORU改2019を開発する時に利用しました。開発を進めるうちに、MusicEngineが提供してくれるデータ以外のものも欲しくなったため、結構自前であれこれ計算してました。

Unityは曲の再生位置を秒数やデータの進み具合で知ることができるので、BPMさえ分かっていれば自前でビートのタイミングは算出できます。ならば全部自前で計算しようということで、直近で作成したJUMP OR DIEで全て自前で実装しました。

unityroom.com

その時の知見を元に、ビートの算出方法を紹介します。

目次

曲のテンポを把握する

BPM

曲のテンポを表す値としてBPMがあります。Beat Per Minutesの略で、1分あたりのビート=拍子数です(ちなみに小節はBar)。1分間あたりの拍数が分かれば、60をBPMで割ってやれば、1拍の秒数が分かります。

JUMP OR DIEのBGMで利用した曲は、 D-elf.com さんのものを使いました。D-elf.comさんのサイトは、曲のBPMが書かれているので有難いです。

D-elf.com

BPMを推定する

BPMが分からない曲は、以下のおとわびさんのBPMタップテンポはかるくんのページに行けば自分で推定できます。

otowabi.com

曲を流して、テンポに合わせてクリックを続けると、クリックのタイミングの平均から推定のBPMを表示してくれます。数字が安定したら、切りのよい数字をBPMとして採用します。

曲の経過を表すtimeSamples

Unityでは曲の開始からの経過を、AudioSourceのtimeならfloatの秒数で、timeSamplesならintで録音データの位置で読み取ることができます。マニュアルを確認すると、より厳密なタイミングを処理したい場合はtimeSamplesを使いましょうとあります。

Use this to read current playback time or to seek to a new playback time in samples, if you want more precise timing than what time variable allows.

録音データは1秒の間に設定回数の音の変化を記録したものです。この回数は、AudioClipのfrequencyプロパティで確認できます。44,100Hzという値がよく利用されますが、これはCDで使われている値で「1秒間に音データを44,100回記録したデータである」ということです。timeSamplesは、今、再生している音データが何回目のものかを表すものです。44,100Hzなら、timeSamples44,100になったら、曲が開始してから1秒経過したことになります。

120BPMでの計算例

以下の図は、BPMを120とした場合のあれこれの値の例です。

f:id:am1tanaka:20201215150649p:plain
120BPMの時の値

  • 120BPMとは、1分(=60秒)に120ビートあるということ
  • 1ビートあたりの秒数は 60 [秒] / BPM で計算できます。120BPMなら、60 / 120 で、1ビート0.5秒です
  • 音データのサンプル数が 44,100 [Hz] だった場合、0.5秒では 0.5 [秒] * 44,100 [Hz] = 22,050 です。これが1ビートで進むtimeSamplesの値です

つまりtimeSamples22,050の倍数を跨ぐ時に何かをやれば、リズムに合わせた動きを作ることができます。

注:割り切れる場合は「22,050ごと」という考え方でよいですが、割り切れないような場合は誤差を防ぐため、検出したいビート数から該当するサンプル値を算出した方がよいでしょう。

もう一つの値として、1回のFixedUpdateごとにサンプル値がどれぐらい進むかも求めておくと判定や動き出すタイミングを計算する役に立ちます。AudioClipの周波数が44,100 [Hz]で、Time.fixedDeltaTimeの値がデフォルト値の0.02なら、 44,100 [Hz] * 0.02 [秒] なので、1回の更新でtimeSamples882進むことになります。

22,050から前後882以内なら、ぴったり。さらに882離れるとちょっとズレている。もう882ずれているとまあまあズレている。というような判定ができます。

実装例

以下のGitHubリポジトリーで、実装例のUnityプロジェクトを公開しました。プロジェクトの設定方法はリポジトリーの方のドキュメントを参照ください。

github.com

曲は、先に紹介した d-elf.com さんから「Love This Beat / Free BGM ver.1」を利用しました。曲データはプロジェクトには含まれないので、ご自身で以下のページからダウンロードして、プロジェクトに設定してください。BPMは130で、サンプルプロジェクトに設定済みです。

www.d-elf.com

勿論、他の曲でも構いません。設定した曲のBPMを、BeatDetectorBeat欄に設定してください。

その他のTips

音源の調整

曲データには、冒頭に空白部分が含まれているものがあります。その場合、timeSamplesをそのまま使うとタイミングがずれてしまいます。曲がどこから始まるかを調べたり、空白部分をトリミングしたりする時にAudacityというツールが便利です。

https://www.audacityteam.org/

日本語でダウンロードする場合はこのあたりからどうぞ。

forest.watch.impress.co.jp

効果音の不要な空白をトリミングしたりするのにも重宝します。

有料アセット

今回はBPMを自前で計って実装しましたが、お金を出せば音源データから自動的にリズムを取り出してくれたり色々してくれるアセットもあります。

Rhythmator

assetstore.unity.com

つい先日買ったので持ってはいるんですがまだ使ってません。いずれ紹介記事など書くかも知れません。

まとめ

BPMを使ってビートを計算する時の考え方とサンプルを紹介しました。1分間に何ビートかと、1秒間のサンプル数が分かれば、単純な計算でタイミングは求めることができます。これを応用すれば、オブジェクトをあるビートのタイミングで判定ライン上を通過させるとか、曲に合わせてジャンプさせるとか、弾を撃ったりといった演出ができます。

お金で解決することも可能ですが、計算方法を知っていれば欲しいタイミングを全て算出できます。いざという時に何かの役に立つのではないかと思います。

参考・関連URL