自作マスコットを動かしたら3回ハマった——EMが「仕組みで」PNGTuberの揺れを直した話

自作マスコットを動かしたら3回ハマった——EMが「仕組みで」PNGTuberの揺れを直した話 コラム

私はふだん、EM(エンジニアリングマネージャー)の1on1や評価の話を「仕組みで解決する」という切り口で書いています。アイコンに使っている自作のクマのマスコット「アニクマ」を、ふと動かしたくなりました。喋ると口が動いて、たまにまばたきする、いわゆるPNGTuberです。

外注すれば早い。でも自分で作る過程が一番おもしろい。やってみたら、案の定3回ハマりました。そして結局、毎回気合ではなく仕組みで抜けることになった——という、業務外でもEMの地が出てしまった話です。

全体構成

  • 画像生成: gpt-image-2(表情差分を作る)
  • アバターソフト: veadotube mini(無料・マイク連動で口パク)
  • 必要な差分は4枚: 通常(口閉じ)/ 会話(口開き)/ まばたき(目閉じ)/ 会話中まばたき
アニクマの4状態

PNGTuberは「複数の静止画を音や瞬きで切り替えるだけ」のシンプルな仕組みです。だからこそ、画像の作り方の甘さがそのまま破綻として出ます

つまずき1: 喋ると目が「死ぬ」

最初は素直に、4状態をそれぞれ別々に生成しました。これが失敗。

差分を1枚ずつ独立に生成すると、キャラが微妙に別人になるんです。とくに口を開いた「会話」の絵で、目のハイライト(白い点)が消えてしまい、切り替わるたびに目が死んで見える。かわいいはずのクマが、喋ると一瞬ホラーになる。

原因は明確で、AIは毎回ゼロから描くので、指定していない細部(目のハイライトなど)は揺れます。

対策: 別々に作るのをやめ、通常の1枚(idle)を元に「口だけ開ける」「目だけ閉じる」と編集する方式に変更(images.edit)。


# idleを入力に、口だけ変える。目・眼鏡・体は「完全に同じ」と強く指示する
client.images.edit(
    model="gpt-image-2",
    image=open("anikuma_idle_green.png", "rb"),
    prompt="Open the mouth into a small oval. Keep the eyes (with the same "
           "highlight), glasses, fur and sweater EXACTLY the same.",
)

これで目は通常の絵から引き継がれ、ハイライトも保たれました。

余談: gpt-image-2は透過背景に非対応だったので、グリーンバックで生成して後から色キーで抜いています。

つまずき2: それでも輪郭が「ブレる」

目は直った。でも動かすと、体の輪郭が小刻みに震えて見える。

編集ベースにしても、AIは結局毎回絵を描き直すので、変えていないはずの体や輪郭まで1pxレベルでズレる。静止しているべき部分がチラチラ振動するわけです。

ここで「もっと強くプロンプトで固定すれば…」と粘るのは、たぶん筋が悪い。1on1の議事録を毎回気合で思い出すのをやめて記録の構造に寄せたのと同じで、気合をやめて仕組みに寄せます

対策: idleを土台にして、口・目の「変化があった領域だけ」を上書き合成する。体・輪郭・眼鏡は全フレームでidleと完全に同じピクセルを共有させる。


# idleとtalkの差分が大きい画素=口の領域、だけをマスクにして合成
mask = (abs(idle_rgb - talk_rgb).sum(axis=2) > 38)  # 口の領域だけTrue
out = idle.copy()
out.paste(talk, (0, 0), feather(mask))  # 体はidleのまま、口だけtalkに差し替え

こうすると、動くのは口と目だけ。体は1ピクセルも動かないので、振動は理屈上ゼロになります。

つまずき3: まだ「ブルブル」する(犯人は画像じゃなかった)

ここまでで画像は完璧なはず。なのに、まだ全体が小刻みに揺れる。

ここで効いたのは、EMが障害対応でやるのと同じ切り分けでした。「画像が悪いのか、ツールが悪いのか」を分ける。

  • 4枚すべてを同じidle画像にして完全な静止画にしても → 揺れる
  • マイクをミュートすると → 止まる

つまり犯人は画像ではなく、音に反応してveadotube側が動かしている。最終的に、エフェクト設定の中にあった 「random move」 という揺らしエフェクトの amount0 にしたら、ピタッと止まりました。

最初に「画像のせいだ」と思い込んでプロンプトをいじり続けていたら、永遠に直らなかった。症状から原因を決め打ちせず、切り分ける。これも完全に本業の手癖でした。

できたもの・かかったもの

  • アニクマが、待機→喋ると口パク→たまにまばたき、揺れなしで動くように。
  • 使ったのは gpt-image-2(数枚ぶんの生成コスト)と veadotube mini(無料)だけ。
  • 山は3つとも「気合で押し切る」ではなく「仕組みに寄せる/切り分ける」で抜けました。

絵が描けなくても、EMの“デバッグの手癖”があれば、マスコットは動かせます。次はもっと表情を増やして、Live2D(ぬるぬる動くやつ)にも手を出す予定です。

私はEMの1on1・評価まわりを「仕組みで解決する」視点で書いています。今回みたいな寄り道も含めて、よかったら他の記事もどうぞ。

👉 1on1管理Notionテンプレート(無料Lite版あり)

コメント