AIゲーム制作ラボ
Unity×AI6分で読めます

ゲームの見た目を機械で検査する(人が見る工程を減らす)

「動く・落ちない・速い」は自動で確かめていたのに、「見た目がひどい」は人に言われるまで気づけませんでした。公開したページを自動で撮って、明るさ・要素の量・色の数・HUDの読みやすさ・動き・音の回数を数で判定する検査を作った話です。自分の検査に足をすくわれた失敗も含めて残します。

Libra

公開 2026年9月19日

この記事の要点4 points

  1. テストは「壊れていないか」しか見ていなかった。 見た目は誰も見ていなかった
  2. 公開したページを自動で開き、6つの数(明るさ・要素の量・色の数・HUDの明暗差・動き・音の回数)で判定する。
  3. 音は WebAudio の再生回数を数えて確かめる(耳を使わずに「鳴っているか」は分かる)。
  4. 🔴 検査がボタンの位置を決め打ちしていたせいで誤判定した。 ?autostart=1 を足して直した。
目次7
検証した環境最終確認 2026年9月19日
  • Windows 11
  • Node.js 22 / puppeteer-core 24 / pngjs 7
  • Unity 6.6(6000.6.0f1)・WebGL ビルド
  • Claude Code(Opus 5 / 思考レベル 高)

書いてあるのは、この環境で実際に試した結果です。ツールの仕様や料金は変わるので、重要な判断の前には公式の情報も確認してください。

4本目のゲームは、テストが通っていました。60fps も出ていました。1フレームの確保も0バイトでした。それでも公開した画面は「単色の図形が並ぶだけ」で、人に言われるまで気づけませんでした

理由ははっきりしています。自動で見ていたのは「壊れていないか」だけで、見た目を見る仕組みが無かったからです。

6つ

機械で見る数

明るさ・量・色・HUD・動き・音

1回

検査の実行

公開したページを開くだけ

345回

鳴りすぎていた音

12秒で(検査が気づいた)

1件

検査自身のバグ

ボタンの位置を決め打ち

何を数えるか

公開したページを自動で開き、遊ばせて、連続3コマ撮って判定します。

#見るもの落ちるとき
1平均の明るさ真っ黒/白飛び
2背景以外の画素の割合何も出ていない(始まっていない)
3はっきり違う色の数単色(自機・敵・弾を色で区別できない)
4画面上部の明暗差文字が下敷き無しで置かれ、読めない
5コマ間で変わった画素止まって見える
6音の再生回数鳴っていない
Git BashOK
npm run check:look -- https://aigame.game-union-libra.com/play/mureuchi/ --seconds 12

見た目の検査: https://aigame.game-union-libra.com/play/mureuchi/
○ 明るさ(真っ黒でない): 平均 0.0644(0.015 以上)
○ 明るさ(白飛びしない): 平均 0.0644(0.45 以下)
○ 要素の量: 背景以外 4.15%(1% 以上)
○ 色の数: 4 種類(3 以上)
○ HUD の読みやすさ: 明暗差 0.907(0.35 以上)
○ 動き: 変わった画素 6.43%(0.2% 以上)
○ 音: 338 回鳴った(3 回以上)
○ コンソールのエラー: なし

作り直す前の画面で同じ検査をかけると、色の数が1種類で落ちます。つまり、あの状態は自動で見つけられました。

色の数え方

難しいことはしていません。明るくて色味のある画素だけを拾い、色相を12個の箱に分けて、全体の4%以上を占める箱を数えます。

if (l > 0.18 && sat > 0.25) {
  hueBuckets[Math.floor(hue / 30)]++
  bright++
}
const hues = hueBuckets.filter((c) => c / bright > 0.04).length

背景の明るさは「画面の下10%の中央値」を使いました。ゲームの絵が少ない場所なので、背景の明るさに近い値が取れます。そこから 0.06 以上明るい画素を「何かが出ている画素」として数えます。

音は WebAudio の再生回数で見る

耳を使わずに「鳴っているか」を確かめる方法です。ページを開く前に、音を出す呼び出しへ印を付けておきます。

await page.evaluateOnNewDocument(() => {
  window.__sounds = 0
  const start = AudioBufferSourceNode.prototype.start
  AudioBufferSourceNode.prototype.start = function (...args) {
    window.__sounds++
    return start.apply(this, args)
  }
})

これで「鳴っていない」は確実に見つかります。おまけに、鳴りすぎも見つかりました。12秒345回1秒29回です。発射音を「同じフレームに何発撃っても1回」に制限していたのに、この数でした。種類ごとに最短の間隔(発射 0.22秒・命中 0.07秒・撃破 0.08秒)を入れ直しています。

⚠️ 音量や音色は判定していない

これで分かるのは回数だけです。「うるさい」「耳障り」は人にしか分かりません。そこは 👤 の確認として残しました。

検査自身が誤判定した

作ったその日に踏みました。タイトル画面に「SOUND ON/OFF」のボタンを足したところ、START ボタンの位置が下にずれました。検査はボタンの座標を決め打ちしてタップしていたので、ゲームが始まらないままタイトル画面を撮り、こう言いました。

Git BashERROR
  ✗ 色の数: 1 種類(3 以上)

失敗 1 件

画面は正常です。検査が壊れていました。

01

自動の検査がボタンの位置を決め打ちしている

この形にしてから、UI を変えても検査は落ちていない
症状
UI を少し変えただけで、見た目の検査が落ちる
原因
座標でタップしているので、ボタンが動くと別のものを押す(または何も押さない)
対処
ゲーム側に 検査用の入口を作る。URL に ?autostart=1 が付いていたら、すぐ始める
// 🔴 検査用の入口:`?autostart=1` ですぐ始める。
//    ⚠️ 自動の検査がボタンの位置を決め打ちしていると、UI を変えるたびに壊れる
if (UrlHas("autostart=1")) StartBattle();

同じ考えで、計測用の入口も2つ用意しています(?nopool=1=絵を使い回さない、?stress=1=数を上限まで)。測るための入口は、ゲーム側に作るほうが安上がりでした。

検査が撮った画面

検査が撮ったムレウチの画面。敵の群れ・撃破の輪と破片・HUD が写っている
検査が撮る画面はそのまま保存できる(--out を付ける)。記事に使う画面も、これで撮っている

私は最初、見た目の確認を「人が見る作業」として 👤 で残すつもりでした。やめた理由は、自分が見落としたからです。見れば分かることを人に頼むと、忙しいときに飛ばされます。数にしておけば、飛ばされません。

何を人に残したか

機械に任せた

真っ黒・単色・文字が読めない
何も出ていない(始まっていない)
止まって見える
音が鳴っていない・鳴りすぎ
コンソールのエラー

人に残した(👤)

面白いか
音のバランス(うるさくないか)
手触り(1プレイの長さ・理不尽さ)
外部に出すかどうか

まとめ

  • テストが通っていても、見た目は誰も見ていないことがある
  • 公開したページを撮って、明るさ・量・色・HUD・動き・音を数で見る
  • 音は WebAudio の再生回数で「鳴っているか」を確かめられる(音量は人)
  • 検査はゲーム側に入口(?autostart=1)を作って、UI の位置に依存させない

FAQ

よくある質問

ゲームの見た目を自動で検査できますか?

「きれいか」は測れませんが、「見せる形になっているか」は測れます。公開したページを自動で開いて画面を撮り、明るさ・背景以外の画素の割合・色の数・HUD 帯の明暗差・コマ間の変化・音の再生回数を数えれば、真っ黒・単色・文字が読めない・音が鳴っていない、といった状態は自動で落とせます。

音が鳴っているかは、どう自動で確かめますか?

ページを開く前に WebAudio の再生(AudioBufferSourceNode.start)を数えるようにしておき、遊んだあとで回数を読みます。音量や音色までは分かりませんが、「鳴っていない」は確実に見つかります。

検査が誤判定したらどうしますか?

検査の作りを疑ってください。私は「START ボタンの位置」を決め打ちしていて、UI にボタンを1つ足したら座標がずれ、タイトル画面を撮って「色が1種類しかない」と判定しました。URL に ?autostart=1 を足して、座標に依存しない入口を作って直しました。

人の確認は無くせますか?

無くせません。面白いか、音がうるさくないか、外部に出すかは人が決めます。減らせるのは「見れば分かること」で、そこは機械に任せます。

この記事は役に立ちましたか?

NEXT