画像も音も素材ファイルを1つも使わない方針で4本目を作りました。動いて、テストも通って、公開しました。そして言われました。
「デザインひど過ぎだろ 演出も」
そのとおりでした。下が、言われたときの画面(左)と、作り直したあと(右)です。形はほとんど同じです。


足りなかったのは形ではなく「光り方」
最初の実装は、白い四角と三角に色を付けて置いただけでした。そこに足したのはこれだけです。
足したもの(形は変えていない)
いちばん効いたのは加算合成です。ふつうの半透明で光を重ねても、暗い背景では白っぽくかすむだけで、光って見えません。足し込みにすると、重なったところが明るくなります。
自作シェーダーで踏んだ3つの穴(原因と対処)
URP 2D にはそのまま使える加算のスプライトシェーダーが無いので、20行ほどのシェーダーを書きました。ここで3回つまずきました。
真っ白な四角が出る
- 症状
- グローを出したはずの場所に、のっぺりした四角が出る
- 原因
- 自作のマテリアルに替えると、SpriteRenderer は絵のテクスチャを渡してくれない。`_MainTex` が既定の白のままになる
- 対処
- 絵ごとにマテリアルを作り、`mainTexture` に自分で入れる(このゲームでは6枚ぶん・辞書に持って使い回す)
色を変えても白いまま
- 症状
- 敵は赤、弾は青のはずが、光だけ全部白い
- 原因
SpriteRenderer.colorは頂点色ではなく `_RendererColor` に入って来る- 対処
- シェーダーで `_RendererColor` を掛ける(`[PerRendererData]` として宣言する)
エディターでは光るのに、Web ビルドでは光らない
気づかないと「本番だけ見た目が違う」になる- 症状
- ビルドしたページだけ、加算の絵が出ない
- 原因
Shader.Findでしか参照していないシェーダーは、ビルドに含まれない- 対処
- Project Settings の Always Included Shaders に登録する(ProjectSettings に記録され、git にも入る)
Blend SrcAlpha One // 足し込み // ⚠️ SpriteRenderer.color はここに来る(頂点色ではない) float4 _RendererColor; OUT.color = IN.color * _Color * _RendererColor;
演出はゲームの中身に触らせない
演出を足すときに怖いのは、当たり判定や点が変わってしまうことです。分け方はこうしました。
手順 01
Core:起きたことを置く
撃破・被弾・発射(固定配列)
手順 02
演出:それを読む
破片・輪・揺れ・音
手順 03
描画:一覧にして出す
使い回した絵に流し込む
演出を追加したあとも、ルール側のテストでは回収後の保持メモリが増えないことを確認しました。ただし、その前後差だけで1フレーム中の割り当てが0バイトとは証明できません。描画側も含む割り当ての検査とは分けて扱います。
ついでに直した:終わったあとも時間を進める
ゲームオーバー後に Tick を呼ぶのをやめていたら、「被弾した」という出来事が片づかずに残り、画面が赤いままになりました。終わっていても呼ぶ(中では何もしない)ようにして解決しています。
数字で見た変化
作り直しの前後で、公開したページを自動で撮って数えました(この検査自体の作り方は別の記事に書きました)。
前
- はっきり違う色:1種類
- 撃破・被弾の反応:無し
- 背景:真っ黒
後
- はっきり違う色:4〜5種類
- 撃破:破片+輪+揺れ/被弾:赤い明滅
- 背景:グラデーション+流れる星
ビルドは 6,944,159 バイト(作り直し後)。サイズはほとんど変わりません(図形を計算で作っているので、増えたのはコードだけ)。
まとめ
- 素材を使わないゲームで足りないのは、形ではなく光り方
- 加算合成の自作シェーダーは、テクスチャ・色・ビルド収録の3か所でつまずく
- 演出はゲームの中身に触らせない(起きたことを読むだけにする)
- 🔴 見た目を最後に回さない。あとから足すと描画まわりを書き直すことになる