![見出し画像](https://assets.st-note.com/production/uploads/images/168221385/rectangle_large_type_2_60858620fb0202999ce9ebf5dbf81c87.png?width=1200)
UnityでFC風ゲームを作ってみた
■はじめに
新年あけましておめでとうございます!
自称ソロデベロッパーのKannoです。
さて。新年のあいさつもほどほどに、本題に入ります。
今回は表題にもあるように、UnityでFC風のゲームを作って
コチラに公開しました。
こちらのサイト「unityroom」さんはUnityで作ったゲームをWebGL形式で公開できる神サイト。今回はちょうど期間イベントであるunity1weekの開催時期だったので、そちらのタイトルとして投稿したのでした。
■What’s FC風?
さて、このゲームはFC風を謳っている通り、なるべくファミコンの仕様に合わせて機能を作成しました。仕様とはこんな感じです。
【全体の大まかな仕様】
・画面解像度は256x240
・仮想的にBG面とスプライト面の2つの面で描画を行なう
・BG面とスプライト面のリソースにそれぞれ128x128サイズの2bit(4パターン)インデックスカラー画像を仮想的に持つ
・BGとスプライトそれぞれに4つパレットが存在し、全52色の中から選べる
・画像データは8x8単位で使用できる(この1単位をキャラクターと呼ぶ)
【BG面の仕様】
・32x30の領域にBG画像の1キャラクターずつ指定できる。
・ただしパレットの指定は1キャラクターずつできず、2x2単位で行なう。
・BGスクロールは可能(ただし実際のFCとは一部の挙動が違う)
![](https://assets.st-note.com/img/1735726896-bwEBts4Y1AqpnKFix7rDOafh.png?width=1200)
【スプライト面の仕様】
・全部で64キャラクターまで描画可能
・横には8キャラクターまで描画可能。9キャラ目以降は描画できない。
・パレットの指定は1キャラクターずつ可能
・1キャラクター毎に上下左右の反転描画が可能
![](https://assets.st-note.com/img/1735709846-1vClJrN3c5Ld0StUYyH2FjWu.png?width=1200)
また、ファミコン仕様に合わせて以下の制限も付けています。
・float型の禁止
・Colliderの禁止
・ScriptableObjectの禁止
・その他、数学関数の禁止など…
…さて、ここまで見てこう思われた方がいるかもしれません。
「なぜわざわざunityを使ってこんなまどろっこしいことを?」と…
単にレトロライクのゲームが作りたいのなら、見た目だけそれっぽくすればいいのではないのか…と。しかしこのゲームを作る狙いは別の所にあるのです。
■FC再現の真の目的とは?
このプロジェクトの最終目標…それはファミコン実機で動かせるゲームを作る事です。しかし私はこれまでファミコンの開発などやった事もなく、どんな問題が起こるのかまったく想像できないのですね…😑
…ので、まずはプロトタイプとしてファミコン仕様に似せた環境でゲームを作り、問題点や留意点を洗い出す…というのが今回の狙いです。
まあ、ファミコンはアセンブラ(Cも使えるようです)、UnityはC#と言語が違うのでその辺は目をつぶらなくてはならないのですが…一応のちにC言語に移植する事を想定して一部のUnity機能を制限した、という次第です。
■留意点① 描画の制限について
前述の通り、ファミコンにはBG面とスプライト面しかありません。この仕様で特に苦労したのがUIを作る時でした。今時のゲームみたいにレイヤーのような感じでUIを上に乗せるみたいな事がほとんど出来ないですからね。
例えば以下のような画面で、上部にON/OFFできるメッセージウィンドウがあったとします。
![](https://assets.st-note.com/img/1735720467-JgdLODxQCI2kVU5Bq7om1bhG.png?width=1200)
このメッセージウィンドウはフィールドマップと同じBG面に書かれているので、メッセージウィンドウを表示する時はいいんですけど消す時は元のフィールドマップに書き直す必要があるんですね。
まあ、これがフィールドとウィンドウだけだったらまだ分かりやすいんですけど、ウィンドウが3重、4重とか重なった場合、1つ前の画面に戻すのはなかなか大変な事になるんですね…。
またBG面よりもスプライトが必ず前面に表示されるので、ウィンドウの下にスプライトを隠したい場合、座標の判定を行なって手動でスプライトを消してやるといった制御が必要だったりします。(今回はやってない😓)
今時のゲーム制作だったら描画優先度を設定すればいいだけの話なんですが、こういう場面はちょくちょく出てくるのでしっかり設計を行ないたいところですね。
■留意点② テキストについて
ファミコンには文字コードという概念がありません。ではどうやって文字を認識して描画するのかと言えば、画像に文字を用意してスプライト面かBG面に描画する事になります。そして今回はBG用の画像に文字を用意しました。
![](https://assets.st-note.com/img/1735715152-XKlzDFp8jec4uCJdyYP7VQNS.png?width=1200)
これらのキャラクターコードは左上から右に0x00, 0x01, 00x02 …と増えていき、一段下がって0x10, 0x11, 0x12…となります。その場合「ア」は0x10, 「イ」は0x11となるわけです。
このルールに従って意味のあるテキストを書いていきます。
「いつか ぜってーシメるからな!
おぼえとけよ!」
というメッセージは、以下の8bitデータの配列になります。
0xC1,0x00, 0xD2,0x00, 0xC5,0x00, 0x00,0x00, 0xCD,0x1F, 0xF3,0x00, 0xD3,0x00, 0x44,0x00, 0x1B,0x00, 0x33,0x00, 0xED,0x00, 0xC5,0x00, 0xEB,0x00, 0xD5,0x00, 0x04,0x00, 0x00,0x00, 0xC4,0x00, 0xDE,0x1F, 0xC3,0x00, 0xD4,0x00, 0xC8,0x00, 0xEA,0x00, 0x04,0x00
…さすがにこのデータを手打ちするのは厳しすぎますね😓
なので今回はエクセルで変換するマクロを組みました。
![](https://assets.st-note.com/img/1735722444-hEl9QcBJ5ja1orFADkmuNPHv.png)
しかし、ファミコン実機の場合だとテキスト配列をベタで持つなんて事はしないはずです。何かしら圧縮しないとROMに入りきらないと思います。
そしてもう一つ、BG用の画像が平仮名とカタカナだけで半分近く埋まっていたと思いますが、これだと他の背景を書く余裕がまったくなくなってしまいます。
なのでテキストは必要な時に必要な分だけ書き出すみたいな事をやってるんじゃないかと思うんですけど…まあこれはFC実機かエミュで作ってみないと分からないですね…😑
■留意点③ トライ&エラーが面倒そう
Unityのデータ設計はScriptableObjectにお世話になる事が多いんじゃないかと思います。ゲーム実行中でも編集できたりするのでバランス調整とかに便利なんですよね。
ですが今回は後々FCに移植する事を考慮しScriptableObjectは封印し、データは構造体か仮想的な8bit変数の配列のみ扱う事にしました。(アセンブラに構造体はないですが、C言語にはあるので…)
そしてそれらのデータは今回エクセルで作りました。
エクセルはマジで万能ですからね😃
エクセルで作ったデータはVBAマクロを通してListに変換する仕組みを今回は採用。Listであればゲーム実行中に動的に生成できるので、HotReloadというプラグインを使う事でトライ&エラーしやすくしています。
ただ実際にFC用のゲームを作る時はデータ更新のたびにビルドをする必要があると思うのでかなり手間は増えそうです。何か手は考えておきたいです。
■留意点④ FCの限界超えてね?問題
…まあこれは最初から思っていたんですけど、今回のプロジェクトではFCのCPUやPPU(FCのグラフィックを司るチップの事)の限界を推し量る事は出来ません。なのでこれもまた実際にエミュとかで試すしかないんですね。
それとメモリの問題もです。FCでは拡張なしでプログラム領域は32KBしか使えないんですよ。
例えばフィールドマップは今回192x72のサイズになりましたが、1マスにつき1byteなので、13824byte = 13.5KBも使っている事になります。
![](https://assets.st-note.com/img/1735726249-ZMwpxKETLi1yd0Ju6NIWkBsH.png?width=1200)
それに前述のテキストデータなども含めると…32KBなんてあっという間になくなってしまいそうですね。やはりFC開発においては圧縮は必須なのです。
ただ、圧縮の工程が含まれると手順が増えてトライ&エラーの効率が落ちてしまうので、どうやって問題を解決していくか…対策を考えて適切な開発環境を作っていくのが大事だなーと思いました。
■その他
今回サウンドに関してはサンプリングされたデータをそのまま再生する事にしました。UnityでFCの再現は難しそうでしたので…😓
実際にファミコン開発を行なう時は、FamiStudioなどの8bit向け音楽ツールを使う事になると思います。このツールにはC言語用のサウンドドライバも付属しているので、こちらを組み込む事になるでしょう。
■最後に
という事でUnityでFC風ゲームを作ってみた訳ですが、FC開発における問題や懸念がいろいろと分かり、次に繋がるいい開発となりました😃
次はFCエミュレータで動くゲームを作ってみたいですね。
それでは今日はこの辺で…バイバイ!
・
・
・
・
・
・
・
・
・
・
・
・
・
・
・
・
・
・
(追記)
【無敵コマンド】
この画面で「↑→↓←↑→↓←XX」の順番にキーボード入力すると
「てってれてってって♪」という音が鳴り、主人公が無敵になります。
![](https://assets.st-note.com/img/1735754413-J8R3Dpyb9nQ4arB17Fj6sYdW.png?width=1200)