はじプロとUnityの対応

# はじめに
　はじプロを遊び始めて１年半が経ちましたが、リソース制限が厳しくやりたい事に対してツールがアンマッチな事が増え始めました。
　ひとつ前の記事[^前の記事]ではショートコーダーの愉しみ方があるよと紹介していますが、規模的に無理なものは無理。無理を通すパズルも楽しいですが、別の手段(遊び)も模索しようかしらとUnityの勉強を始めました。
　この記事はUnityを始めたばかりの初心者(私)が自分の理解を整理したものです。同じように別のゲームエンジンを模索してる人の足掛かりになれば幸いです。
[^前の記事]:色んな事情があってアドベントカレンダー上では翌日の記事です

# 初期費用
|項目|はじプロ|Unity|
|:--|:--|:--|
|ハードウエア|Switch(33,000)|PC(100,000)|
|ソフトウエア|はじプロ(3,000)|基本フリー|
|金額合計|36,000|100,000|

　PCは最初3万円位のノートPCにUnityを入れて試してましたが、動作が重くて無理。PCが遅いとモチベも一緒に削がれていくので速いPCを用意しましょう。私はMINISFORUM EliteMini HX90[^HX90]というミニPCを買いましたが、今のところ充分に快適です。
[^HX90]:HX90は3.3GHz-8C16T, 32GB-RAM, 500GB-SSD位の性能。お勧めポイントは2.1GHz相当の無名GPUを内蔵している事です

# 開発環境
　私のやりたい事はレトロSTG風のゲーム制作です。Unityをゲームエンジンに採用する事を前提に開発環境に必要な機能とUnityでの対応状況を確認します。ネットのチュートリアルを一通りやってみて、だいたいこんな感じの対応状況だとわかりました。

|機能|はじプロ|Unity|説明|
|:--|:--:|:--:|:--|
|デバイス入力|〇|〇|レバーやボタン操作の検出|
|プログラミング|〇|〇|演算、算術関数、比較等|
|オブジェクト描画|〇|〇|物体(モノ)の画面表示|
|物理エンジン|〇|〇|物体にかかる重力や衝突判定等の演算機能|
|テキスト表示|〇|〇|スコアや文字情報をゲーム内に表示|
|画像表示|〇|〇|テクスチャの表示や物体への貼り付け|
|画像編集|〇|×|テクスチャを編集するエディタの存在|
|サウンド再生|〇|〇|音を鳴らす機能|
|サウンド編集|〇|×|単音をプログラムした通りに鳴らす指示が可能か|
|組込音源|〇|×|プロダクトに予め準備されたプリセット音源|
|音源編集|×|×|音源自体を編集する機能|

　Unityでのテクスチャ描画は外部ファイルを取り込んで表示する為、追加でペイントツールが必要です。同様にBGMやSEも外部ファィルを取り込み再生するので音楽制作ツール[^DAW]が必要です。レーザー音や爆発音も自前で用意するとなると音源も作成する必要があります。
[^DAW]:DTMは「PCで音楽制作する行為」DAWは「PCで音楽制作する道具」との事。ややこしいね！

　諸々検討して以下のソフトウエアを選びました。始めたばかりの初心者が高い買い物をする必要はないので無料版で揃えます。
**Unity**
　Unity!
　とりあえず最新版(2021.3.7f1)
**C#エディタ**
　VisualStudio
　VsCodeもありますがどちらもマイクロソフト製ですし、単に慣れてるので
**ペイントソフト**
　[EDGE](https://takabosoft.com/edge)
　最初はペイント3Dでも良いかなと思ったのですが、専用に作られたツールは作業効率が抜群。
　透過pngを作れるし、自分用パレットを作れるのが使いやすいです。
**DAW**
　[Cakewalk by BandLab](https://www.bandlab.com/products/cakewalk)
　家族からFL Studio無料版を勧められたのですが、無料版はプロジェクトの保存が出来ません。素人が保存せずに完成に至るのはほぼ不可能なので、販売終了してフリーになった高機能なDAWをチョイスしました。
　全機能を使いこなせる訳もありませんが、何かあった時に調べれば逃げ道あるだろう、つまり頓挫するリスクが低いです。DAWによっては最初からプリセットで入っている音源もあるのでBGMだけならこれで充分でしょう。

はじプロとDAWの関係をイメージし易く図で示すと、以下のような対応になります。

個々のトラック再生開始位置をコントロールする部分。
画面中央あたりにある2Dマーカーでトラック再生タイミングを制御してます。(省ノードンの為リズムトラックも配置してますが、それは別の話)
<img width="200" alt="トラック" src="https://pbs.twimg.com/media/FiEiYNnaMAAtCD0?format=jpg&name=large"> <img width="200" alt="track" src="https://pbs.twimg.com/media/FiEmm-vaMAA8Pko?format=jpg&name=large">

トラック内部のピアノロールを編集する部分。
一つの音色で音階を打ち込む箇所です。
<img width="200" alt="ピアノロール" src="https://pbs.twimg.com/media/FiEiYNnaUAA7avD?format=jpg&name=large"> <img width="200" alt="piano-roll" src="https://pbs.twimg.com/media/FiEmn4LacAAbRHl?format=jpg&name=large">


**シンセサイザー音源**
　[Magical 8bit plug](https://ymck.net/app/magical-8bit-plug)
　[VOPMex](https://plugins4free.com/plugin/1066/)
　レーザー発射や爆発音はDAWのプリセット音源では難しいので、自分で音を作ります[^SE]。Magical 8bit plugはPSG音源(ファミコン音源)、VOPMexはFM音源(80年代のゲーム機音源)のシンセサイザー・プラグインです。基本波形を選んで適当にパラメータを弄るだけでもそれっぽい音が出来るでしょう。
[^SE]:シンセサイザーで音を作らなくとも自然界にある音を録音して音源にする事も出来ます。お皿を落として割った音や、ザルの中で小豆を転がす音とか。

　[Bfxr](https://www.bfxr.net/)
　2,3時間ほどPSG音源を弄って効果音作りを試してましたがピンとくる音が作れませんでした。パラメータ調整方法を調べてるうちに素晴らしいアプリを発見。
　ランダムに効果音を生成して気に入った音が出たら即wavファィルに出力できます。矩形波、三角波、ノイズを指定出来るので、もうこれで良いんじゃないのっていう位Unity向きです。



はじプロでは以下の図のようにプリセット音源から音色を選択します。個々の音色が異なるシンセサイザー・プラグインで作られた音色と対応する、と考えるとイメージしやすいです。
<img width="400" alt="プリセット音源" src="https://pbs.twimg.com/media/FiEiYNbaAAAFlzk?format=jpg&name=large">

シンセサイザープラグインは開発元が違えばUIもまったく異なります。以下はPSG音源とFM音源のパラメータ変更に使うUIです。
<img width="200" alt="magical8bit PCM-synthesizer" src="https://pbs.twimg.com/media/FiEmpulagAAKEMW?format=jpg&name=900x900"> <img width="200" alt="VOPMex FM-synthesizer" src="https://pbs.twimg.com/media/FiEmq2UagAAx7Z7?format=jpg&name=900x900">


# モノとGameObjectの対応
　はじプロのモノとUnityのGameObjectは同じ概念です。具体的には白い直方体(トウフ)の事です。私も最初は良くわからず混乱してましたが、整理したらすっきりしました。最初にこんなナビゲーションがあったら良かったのに…が、この記事を書く動機だったりします。
　**はじプロのモノは最初から「全部入り」、対してUnityのGameObjectは「必要な要素(コンポーネント)を後から追加」するコンセプトです。**

はじプロのトウフ設定項目
<img width="800" alt="gbgcomponent" src="https://pbs.twimg.com/media/Fh_SIxIakAAdyVi?format=jpg&name=large">

Unityのトウフ構造図
<img width="400" alt="unitycomponent" src="https://pbs.twimg.com/media/Fh_SJ2LaAAAROND?format=jpg&name=large">

　とても荒っぽいので突っ込まれると困るのですが、モデル理解の為には良い図じゃないかなー、と自負しています。
　Materialには外部ファィル(画像ファイル)を指定する事が出来ますし、(この図には登場していませんが)音楽再生用のコンポーネントも外部ファィル(音声ファィル)を指定します。細かいところで若干の相違はありますが、物理エンジン内でのトウフの在り方は何処でも一緒という事ですね。
　ここではトウフの対応しか書いてませんが、UnityのGameObjectはアタッチするコンポーネントを変える事でカメラになったり、音源再生オブジェクトになったりします。

# ノードン毎のUnity対応
　ここから先はかなり無理があるので話半分に。
　はじプロユーザーがUnityへ移行する時の概念理解に資す為の対応表なので、一般的には意味不明情報です。「多分これでイケるんじゃないかしら」レベルの適当な事も書いてますので、そこは「？」と明記してます。


|ノードン|Unity側|説明|
|:--|:--|:--|
|定数|C#|1(整数型)とか1f(浮動小数型)とか|
|ボタン|C#|Input.GetKey(KeyCode.Space)<br>引数に検査するボタンを与えて戻り値がtrueなら押されてる|
|スティック|C#|Input.GetKey(KeyCode.LeftArrow)<br> Input.GetAxis("Vertical")|
|その他入力デバイス|?|[Input](https://docs.unity3d.com/ja/2019.4/ScriptReference/Input.html)<br>[JoyconLib](https://github.com/Looking-Glass/JoyconLib)という有志制作Packageも...|
|モノが壊れた瞬間|?|Unityでは能動的にGameObjectを壊すコードをC#Scrpitの何処かに書く筈なので、はじプロのように受動的に壊れたかどうかの検査はしないコンセプトだと思う<br>一応[ユーザーコールバック](https://docs.unity3d.com/ja/2019.4/Manual/ExecutionOrder.html)にOnDestroy()も定義されてるけど...|
|スタートした瞬間|C#|C#ScriptでオーバーライドするMonoBehaviour.Start()が相当する|
|けいさん|C#|演算子。剰余もあるよ！|
|くらべる|C#|比較演算子|
|論理演算|C#|論理演算子|
|その他算術関数|C#|UnityEngine.MathfパッケージやSystem.Math<br>Mathfは浮動小数用の算術関数|
|0から変わった瞬間|C#|Collider.OnCollision**Enter**() 衝突した瞬間<br>~~Collider.OnCollisionStay()~~ 衝突中<br>Collider.OnCollision**Exit**() 衝突解除した瞬間<br>のEnter,Exitが相当する|
|タイマー|C#|MonoBehaviour.Invoke()|
|スポイト||無し。はじプロ固有の機能|
|ワイヤーワープ||無し。はじプロ固有の機能|
|自分メモ||無し。敢えて言えば C#Scriptの//コメント|
|音を鳴らす|Unity|GameObject.Audio Sourceに対して<br>C#からaudioSource.PlayOneShot()|
|BGM|Unity|GameObject.Audio Source|
|しんどう|?|Gamepad.SetMotorSpeeds()<br>追加パッケージらしいので[InputSystem](https://docs.unity3d.com/Packages/com.unity.inputsystem@1.0/api/UnityEngine.InputSystem.Gamepad.html)を追加|
|重力を減らす|C#|Rigidbody.useGravityをON/OFF|
|時間を止める|?||
|リトライ|?||
|ゲーム終わる|?|UnityEditor.EditorApplication.isPlaying = false<br>Application.Quit()<br>テスト実行中とリリースしたバイナリの終了で命令が違う|
|ゲーム切り替え||無し。そもそも別ファィルに切り替える必要が無い<br>敢えて言うとシーンの切り替えが相当する|
|マーカー||無し。はじプロ固有の機能|
|赤外線ライトを光らせる|?||
|キャラクター|Unity|無し。自分で作るかアセットストアで購入<br>自分で作るならBlenderで人形作ってインポート|
|モノ|Unity|GameObject|
|おしゃれなモノ||衝突判定の識別にGameObject**の名前**を使えるので、対象識別としての用途は不要<br>単に出来合いの置物が欲しいなら自分で作るか買う|
|動かせるモノ|C#|Rigidbody.AddForce()|
|回せるモノ|C#|Transform.Rotate()|
|伸ばせるモノ|C#|Transform.localScale|
|エフェクト|Unity|Component-Effectsが相当|
|ことばつき|Unity|Canvasの子オブジェクトにTextコンポーネントを追加する|
|数つき|Unity|Canvasの子オブジェクトにTextコンポーネントを追加する<br>C#で数値を文字列に変換する|
|テクスチャ|Unity|GameObject.MaterialかGameObject.Sprite Rendererに画像ファイルをアタッチする|
|さわってるセンサー|Unity|ColliderとRigidbodyを追加すると利用可能になるOnCollisionEnter()等のイベントハンドラが相当|
|こわした瞬間センサー|?||
|こわれてるセンサー|?||
|つかまれてるセンサー|?||
|その他センサー|C#|GameObject.TransformのpositionやRotateを毎フレームチェックして差分から算出|
|スライド連結|Unity|空のGameObjectを親にして子オブジェクトを複数配置すると、親に対する相対位置が保持されます<br>親を動かせば全体が動き、子のPositionを変更すれば一部だけ移動するのでスライド相当になります|
|フリースライド連結|Unity|同上|
|ヒンジ連結|Unity|同上。ただしPositionではなくRotateを変更|
|ひも連結|?||
|モノを発射|Unity|GameObjectをプレハブ化してオブジェクトの大量生産|
|モノを壊す|C#|対象のGameObjectを引数にDestroy()|
|モノワープ|C#|GameObject.Transformのposition変更<br>座標指定なので実質ワープになります|
|引力|?|Colliderで接触判定しつつ、接触中に引力方向への移動ベクトルを与える感じかな|
|ワールド|Unity|機能範囲が広すぎて直接の対応は無し<br>CameraのClear flagsとか、MeshFilterのplane(床的なGameObject)とか…|
|ゲーム画面|Unity|Cameraコンポーネント|
|カメラ|Unity|Cameraコンポーネント|
|カメラ詳しく|Unity|Cameraコンポーネント|
|頭|Unity|HUDを表示する目的が主なのでUIのCanvasが相当|
|手|?||

　0から変わった瞬間(1フレームだけ1を出力する)ノードンとは、毎フレーム値を出し続けてしまうはじプロの基本動作に対して、変化した瞬間を捉るニーズに対して導入されたはじプロ固有の機能と考えられます。UnityではOnCollision**Enter**(), OnCollision**Stay**(), OnCollision**Exit**()のように接触した瞬間、接触中、接触解除した瞬間に呼び出される専用のイベントハンドラがあります。

　例えば空のGameObjectを作りこれにC#Scriptをアタッチして、メンバ変数にn次元配列を持たせれば、パズルゲームのように配列を扱うゲームの状態を一元管理できます。全てのC#ScriptのUpdate()が毎フレーム呼び出されるので、そこでゲーム座標系の操作を行います[^行います]。
[^行います]:とはいえC#ScriptをアタッチしたGameObject全てのUpdateを呼び出す訳ですから、重たい処理を書いたら当然重くなります。

　はじプロではモノの配置と中間ノードンの変更を一つのUndoで巻き戻せますが、UnityとVisualStudioは別のツールなのでUndo機能は各ツール内で閉じています。はじプロのようにUnityとVisualStudioを行き来しながら開発するとUndoの同期が取れなくなります。モノの配置がしっかり完了するまでC#Scriptの編集はしないように注意すれば、何処を変えたか分からなくなる事故は減るでしょう。(ネットのチュートリアルやってる最中、これで嵌りました)


# はじプロからUnityへ
　Unityははじプロに近いので、はじプロ制作者が移行しやすいゲームエンジン[^ゲームエンジン]です。テクスチャや音源、ヒトノードン的なものが無いのはどうしようもないですが、無料のアセットを探せば良さげなものが見つかるでしょう。
　オブジェクト指向言語(≒C#)を理解していればコーディング量を格段に減らせますが、知らなくてもWebの記事を丸写しで動くゲームを作れます。この記事を読む人は物理演算を搭載したゲームエンジンの感覚が掴めている人が多数でしょう。
[^ゲームエンジン]:むしろUnityを凄く意識して単純化したのがはじプロじゃないかしら、と今では確信しています

　最初の学習時間は必要ですが、慣れてしまえばはじプロと同程度の作業時間でアウトプット出来る手応えがあります。Unityを選択する一番の理由がノードン制限による「これ以上実装出来ないフラストレーション」なので、とりあえず2倍(1024ノードン)位の作業時間を見込んでおけば、はじプロと同程度に扱えるでしょう。

# 最後に
　個人製作の落とし穴は開発期間が長すぎてモチベーションが続かない事だと経験的に理解しています。はじプロはこの落とし穴を**システム面で解決**してくれる素晴らしいソリューションです。「もっとアレコレ盛り込みたい」欲求をシステム的に禁じてくれる、PMのような存在です。

　プログラマー、絵師、音屋、そしてゲームのアイデアを考える人。
　私の場合は趣味なので適当に絵や音を作ればいいんですが、仕事だとそれぞれに専門性が必要な技能なのでやっぱり分業って大事。