当記事は若干のnsfw要素を含みます。
- 記事内で直接的表現は極力避けますが、閲覧に際しては周囲の目、Webブラウザ監視ツール、閲覧履歴などに十分ご注意ください
はじめに Qiitaに投稿してどうするの
- Unity初心者がゲームを作って公開するまでの記録、発生した問題とその解決法の防備録として運用します。インターネットに多数転がっているブロック崩しのハウツーは簡単な部分で完成にしてあったり、そもそも月兌衣ブロック崩しを作るにあたりあまり役に立たなかったりしたので、ここに書き留めていく次第です
- 解決済みの問題を個別記事にします
- 未解決の問題はきっと誰かがなんとかしてくれる!(他力本願寺)
技術畑に飛び込む姿勢の第一歩
事の発端
Flashが使えなくなって久しいが、どうしてもB2ブロック崩しがやりたくなった。無いなら作ってしまおう。
目指す先
- ゲームとして遊べるレベルの完成度にし、出来上がったものを販売する
- 最終的にはエディタ側を頒布し、月兌衣ブロック崩しの復権を狙う
筆者の前提
- Unity、C#未経験。オブジェクト指向is何
- プログラミングに関しては学校でCとProcessingを少し囓る。クソ不真面目だったのでいずれも評定は可で抜けている
- コンピューター工学は受動喫煙した雑学としてちょっと知っているくらい。ちゃんと本を読んで勉強してたりはしないです
24/3/7までにやったこと
- 当Qiitaアカウント、新規名義の作成(nsfwコンテンツを扱うため)
- Unityの導入、Platformerのチュートリアルを完了
- ともあれ手探りなりに教本( https://amzn.asia/d/5k6as3M ) でC#の勉強
- 一枚剥いたイラスト、その上に重ねる着衣イラストの用意
ゲームのメインとなるScene作成
一応最低限ブロック崩しとしての遊びを成立させた
基本仕様
- 画面サイズ 1152:* 864(環境はPC,Webブラウザでのプレイを想定)
- プレイエリアサイズ:576 * 864
- ブロック:正方形ブロック24 * 24,差分となる画像の上にのみ配置
壁
- 上下左右に配置、下の壁はミス扱い。
ブロック
- 着衣イラストの服、表情の部分のレイヤーをSprite Rendererで分割
- バラバラにした差分画像をPrehab化したブロックに一枚ずつ割り当て。24*24のグリッドのどこにブロックが有るか、配置場所の情報をjsonファイルで記述。配置情報を読み込み背景画像に重なるように配置した
ボール
- ボールからRigidBody2Dを剥奪し、ボールに接触するオブジェクト側にRigidBody2Dをアタッチして衝突検知するようにした。これは、 2D物理によりボールが水平に反射し続ける 、ボールが垂直に反射してゲームにならないといった悲しき事例を見てきた為、これの回避の為に行った
- 「何かにボールが衝突し、反射する挙動」は全てボールに割り付いているスクリプトで行う。ぶつかり得るものにtagを設定しておき、衝突した相手の情報を読んで挙動を決定している
- 移動はVector2型の変数
BallVelocity
により行う。BallVelocity
は正規化された方向だけを持つBallDir
とスカラー量の速度BallSpeed
をFixedUpdate()関数の中で掛け合わせている。
これにより、ブロック崩しのゲーム性の要素であるボールの加速の管理を容易にしている。 - バーにボールが接触した時、
BallDir
の値からその場で法線ベクトルを計算しVector2.Reflect();
メソッドで反射。両端のエッジ部分でボールの反射角を変えるにようにしている(ランダム反射はしない)
バー
- マウスのX軸の座標に追従して移動する。
解決済みの問題
ブロック配置について
(前項で少し触れた内容であるが)
- 通常のブロック崩しの常識(配置が複雑かつブロックのスプライトが全て異なる)が通用しなくなり、役に立つ文献が見つけにくい
- ブロックに手作業でスプライトを設定するのはあまりに嫌だったので、ブロック生成用のスクリプトを用意した。これをStart関数で呼び出し、分割された画像を割り付けることで解決した。
バーでの反射時、俯角(床)に向かってボールが飛んでいくことがある
- 飛んできたボールに突っ込ませるようにエッジ部分で反射を行ったとき、一度反射したボールが再度バーの判定に衝突し、あらぬ方向へ飛んでいた
- また、反射時の角度が急になりすぎたり、水平になりすぎることがあった
- そのため、バーを反射したときに取り得る角度の範囲を水平から左回りに15°~75°,105°~165°の範囲に限定するようにした。これにより、下向きの反射(180~360°の範囲)を抑え、同時に極端な角度にならないようにした。
未解決の問題
- ゲーム開始前に座標(0,0)上にあるブロックが破壊されることがある。残機対応に向けてボールをPrefab化したはいいものの、どうやら一瞬だけ座標(0,0)に生成→初期位置に移動している可能性がある。
- 壁を貫通して画面外に行ってしまうことがある(rigidbody2Dのcollision detection周りな気がする)
- ブロック崩しとしてあまり気持ちよくない反射の仕方をすることがある(rigidbody2Dのcollision detection周りな気がする。ついでに)
- オブジェクト指向をよく分かっていない。とりあえずおまじないとしてやたらめったらMonoBehaviourを継承させている。おそらくボールやブロックなんかはきちんとクラスを持ち出してくれば使えばコードを整頓できる気はするが……
これからやる予定
ゲーム内の実装予定(上に有るものほど優先度高)
- ゲームオーバー
- 残機
- 2枚以上の差分
- アイテム
- バー中心で反射したときの加速貫通弾
- タイトル画面
- セーブ
- ギャラリー
- 設定(ブロックのグリッド表示オンオフ、など)
- 複数のキャラクター
ゲーム外
- 公開場所の算定
おわりに
エタらせないようにしよう!