scenario-blender-2d-animation について
scenario-blender-2d-animationは、Scenarioで生成したアートから、Blenderでレイヤー式の2Dプラットフォームアニメーションを作るスキルです。画像生成、素材処理、視差、キャラクターのループ、シーンのレンダリングを扱います。
主な機能
- 01統一感のあるシーン画像の生成
- 02走行アニメーションのループ作成
- 03素材の切り出し、キーイング、タイル化、計測
- 04Blenderでレイヤー式視差シーンを構築
- 05確認用静止画と完成映像のレンダリング
活用シーン
- 01新しいビジュアルスタイルの2Dプラットフォームシーン制作
- 02生成アートからレイヤー式Blender素材を作成
- 03キャラクターの走行ループシーケンス制作
- 04シーンをレンダリングして.blendファイルを納品
MCP 対応
このスキルはScenarioのモデル検索、スキーマ、料金見積もり、生成、ジョブ待機ツールを使って画像や動画素材を作成します。Blender MCP接続などを通じて、シーン構築スクリプトを実行できます。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ scenario-labs/ skills --skill scenario-blender-2d-animationインストール後、Claude Code で/scenario-blender-2d-animationを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
README.mdexamples/config.jsonreferences/checks.mdpipeline.mdprompts.mdscripts/build_scene.pymeasure_set.pyprep_assets.pyreframe_stills.pyrun_loop.pytrace_hulls.py詳細
シナリオ:Blender 2Dアニメーション
概要
各ルックのアートは一度だけ生成し、Blenderで一度だけアニメーション化します。コンセプトフレーム(ゲーム内のスクリーンショットを想定したもの)でスタイルを決め、ほかの8枚の画像(空、遠景と中景のレイヤー、地面の帯、前景の植物、小道具シート、木、2つのポーズの主人公)はそれを参考にするため、全体に統一感が生まれます。マゼンタ背景の上で主人公がその場で走る画像から動画へのクリップは、ループする画像シーケンスになります。1つのBlenderスクリプトで画像を奥行きのある平面カードとして配置し、主人公を追う正投影カメラに合わせて視差を動かし、ジャンプにキーフレームを設定し、小道具に剛体物理演算を適用します。新しいルックに必要なのは、新たに10個生成して、いくつかの数値を調整するだけです。参照結果は、3つのルックからなる7.7秒、1080p、24 fpsのショットです。納品物は映像とその.blendファイルです。このファイルは相対パスでSET_DIR/game/から画像を読み込むため、そのフォルダーも一緒に納品してください。ゲームエンジンで再生するスプライトシートには、scenario-side-view-game-kitまたはscenario-sprite-animationを使用してください。
recommendを使い、ユーザーの言葉をpromptとして、両方の処理系を見つけます。画像には、参照画像入力、透明な背景、正確な幅と高さが必要なため、画像にはcapability: "txt2img"を指定します(選んだ候補にこれらがない場合、またはペイント調のアニメーションに対するピクセルアートのように、ルックとは異なるスタイル向けの専用機能である場合は、次の順位の候補を選んでください)。走行クリップには最初のフレームが必要なため、capability: "img2video"を指定します。それぞれの候補に対してmodel_schema_getを実行します。以下に示すペイロード名(referenceImages、background、numOutputs)は例です。選んだ候補のスキーマに記載されたフィールドを使用してください。生成する前に、9枚の画像とクリップの合計費用をユーザーに伝えてください。コンセプトフレームに対してdry_runを実行し、残りの費用はrecommendの結果から見積もってください。まだ存在しないアセットを指定したdry_runは404を返すためです。その後、入力がそろった各ペイロードに対して、実行前に一度ずつdry_runを実行してください。
接続、アップロード、基本的な処理の流れについては、scenarioスキルを参照してください。ここで名前を挙げた関連スキルが利用可能なスキルにない場合は、ユーザーにインストールを依頼してください(npx skills add scenario-labs/skills --skill <name>)。無人で処理する場合は、ツールのスキーマに従って続行し、不足しているスキルを明記してください。
スクリプトはローカルで実行し、Scenarioへの呼び出しは行いません。Blender 5.xでシーンスクリプトを実行します。ヘッドレスでも、開いたセッション内でも実行できます(たとえば、Blender MCP接続経由)。セッション内で実行する場合は、File > Newから開始してください。--liveは開いているファイルを空にするうえ、新規ファイルまたは自身の出力ファイル以外では処理を拒否するためです。Python 3とPillow、NumPy、SciPyでヘルパーを実行し、ffmpegでクリップを読み込みます。どのヘルパーも引数なしで実行すると使い方を表示し、--forceを指定しない限り、既存の出力(または入力)を上書きしません。
クイックリファレンス
| 手順 | 方法 |
|---|---|
| モデルを選ぶ | recommend(txt2img、img2video)、model_schema_getを使い、異なるペイロードごとにdry_run: trueを指定してmodel_runを実行します |
| コンセプトフレーム | テキストから画像を生成します。16:9、不透明、2パターン:ゲーム内のスクリーンショット、厳密な側面図、レイヤー名は順番どおりです(プロンプト) |
| レイヤー | コンセプトを参照画像として、レイヤーごとに1回呼び出します。空以外は透明にします。タイル状のレイヤーは横長(3072 x 1152)にします |
| シート | 小道具、木、前景は透明な背景に配置し、十分な間隔を空けて、読み取り順に番号を付けます |
| 主人公 | 2つのポーズ(休止、ジャンプ)を平坦なマゼンタ背景に並べます。reframe_stills.pyで最初のフレームを正方形にします |
| 走行クリップ | 休止ポーズから動画に変換します。「トレッドミルのように」、カメラを固定し、マゼンタを変化させないようにします。5秒で十分です |
| 走行ループ | run_loop.py:キーを使い、1周期分の最もきれいなループを見つけて、hero_run/run_001.png...に書き込みます |
| 切り抜きとキーイング | prep_assets.pyのcut(シート)、key(マゼンタの静止画)、tile(継ぎ目のない横長レイヤー)を使います |
| 輪郭 | trace_hulls.py:各小道具のアルファチャンネルから凸包を求め、shapes.jsonに保存します |
| 測定 | measure_set.py:地平線、地面の線、島、台座の上端を測定します(設定例) |
| ビルド | build_scene.pyの後に-- --set SET_DIR --reviewを実行し、続けて--finalを実行します |
| 新しい見た目 | 新しいコンセプトフレーム、同じ8枚の画像とクリップ、同じファイル名、新しいconfig.jsonを用意します。それ以外は変更しません |
| 待機 | 最大32個のjob_idsを指定してjobs_waitを実行します。タイムアウトした場合は、返されたpending_job_idsを指定して再度呼び出します |
実例:ジャングルを走ってから、雪の日へ
すべての呼び出しでteam_idとproject_idを渡します(選び方についてはscenarioスキルを参照してください)。
- コンセプトフレーム。
recommend { "capability": "txt2img", "prompt": "<the user's request>; needs reference image input, transparent background, exact width and height" }、model_schema_getで候補を選び、references/prompts.mdのセクション1にあるスクリーンショット用プロンプトを使って、model_run { "model_id": "<pick>", "dry_run": true, "parameters": { "prompt": "...", "width": 1536, "height": 864, "background": "opaque", "numOutputs": 2 } }で2枚分の料金を見積もります。実行し、job_idが返された場合はjobs_waitで待ち、asset_displayで両方の候補を表示して、レイヤーを一つずつ名前で指定できるほうを残します。そのアセットIDを以降のすべてで参照します。 - レイヤー。1回につき1呼び出し。 同じ候補を
referenceImages: ["<concept id>"]とともに使い、空(2560 x 1440、不透明)、遠景レイヤーと中景レイヤー(3072 x 1152、透明)、地面の帯(2048 x 768、透明。上端から約30パーセントの位置に平らな歩行可能面があり、端のキャップなし)、植物のまとまり5つを並べた前景シート(3072 x 1024、透明)を生成します。料金を見積もってから、チームの並列実行上限内でwait: falseを使い、数回に分けて実行します(scenarioスキルのparallel-custom-jobs行にあるとおり、429で起動を拒否された場合はジョブが作成されていないため、次の波で再度起動します)。各波の終了時にjobs_waitで待ちます。 - 小道具と木。 小道具シート(2048 x 1536、透明)は、間隔を広く取ったゆるいグリッドに番号付きの小道具を配置します(植木鉢、背の高い器、ふた付きの壺、重厚な像、落ちてくる果物、コイン、浮島、平らな台座)。木は単体で生成し(1024 x 1536)、樹冠に果物がないようにします。ステップ6で
cutが付ける名前は、どんな新しい見た目になっても役割を表します。jarは台座の上に置き、そのふたには最も重いidolを載せ、隣にpot_roundを置きます。着地点の先の草地にはamphoraを置き、果物はcoconutとします。 - 主人公。 平らなマゼンタ背景に2つのポーズを並べます(1536 x 1024、不透明、2枚)。左は休息、右はジャンプ。どちらも同じサイズで、真横を向き、右向きにします。残す候補を
asset_downloadし、python3 scripts/reframe_stills.py hero.png --name hero --out framesを実行すると、hero_rest.pngとhero_action.pngが書き出されます(尻尾が長い場合は--figureを小さくします)。休息フレームをupload_assetとupload_asset_completeでアップロードします。 - 走るクリップ。
recommend { "capability": "img2video", "prompt": "<the user's request>; first frame input, 5 seconds" }、model_schema_getを実行し、スキーマの最初のフレーム用フィールドに休息フレームのアセットIDを指定して、prompts.mdのセクション5にあるトレッドミル用プロンプトで5秒のクリップの料金を見積もります。音声はオフにし、スキーマに該当フィールドがある場合はアスペクト比を1:1にします(ループに使うのは無音のフレームだけで、ジャンプの静止画のスケールは、クリップが正方形の最初のフレームをリサイズしたものだと想定しています)。実行し、jobs_waitで待ちます(数分かかります。必要に応じて再度呼び出します)。その後、asset_downloadします。 - 処理。
jungle/game/に配置します(空は横長のカード1枚のままにし、sky.pngとしてコピーします)。python3 scripts/prep_assets.py tile raw/sea.png jungle/game/sea_tile.png 384を実行します。同様に、中景レイヤーはjungle_tile.png(幅の8分の1のフェード)、地面はground_tile.png(2048 pxの場合は256)にします。python3 scripts/prep_assets.py cut raw/props.png jungle/game pot_round,amphora,jar,idol,coconut,coin,island,pedestalを実行します。CUT_GROW=2 python3 scripts/prep_assets.py cut raw/foreground.png jungle/game fg_bush,fg_fern,fg_hibiscus,fg_boulder,fg_curlを実行します。python3 scripts/prep_assets.py key frames/hero_action.png jungle/game/hero_jump.pngを実行します。python3 scripts/run_loop.py clips/hero_run.mp4 jungle/game/hero_runを実行します(クリップの高さであるrun_n、run_fig_px、run_pad_px、run_canvas_pxが出力されます)。python3 scripts/trace_hulls.py jungle/gameを実行します。木はキー処理したもの、またはすでに透明なものをpalm.pngとしてコピーします。 - 計測。
python3 scripts/measure_set.py jungle/game --ground-h 4.3を実行します(地面カードの高さ。メートル単位で、設定のground_hに指定します)。地平線、歩行可能ライン(草の縁に足が沈むよう、すでに10 cm下げてあります)、浮島と台座の上端、ジャンプ静止画の足元の行が出力されます。走行クリップの数値とともに、これらをjungle/game/config.jsonに記入します。レイヤーの高さ、果物の位置、主人公のメートル単位の高さは、レビュー用静止画を見ながら目視で設定します。examples/config.jsonを参考にしてください(references/pipeline.mdにすべてのキーが記載されています)。 - ビルドとレビュー。
blender -b --factory-startup --python-exit-code 1 -P scripts/build_scene.py -- --set jungle --reviewを実行します。 出力先はjungle/を含むフォルダー(または--out DIR)です。platformer_scene<tag>.blend、review<tag>/、および--finalを指定した場合はplatformer<tag>.mp4が出力されます。これらに上書きして再ビルドするには--forceが必要です。 11枚のレビュー用静止画を確認します。足が地面に接していること、木が地面に立っていること、継ぎ目がないこと、主人公が塔に到達するまで塔が立っていること、すべてのパーツがフレーム内に収まっていることを確認します。その後、--finalを付けて動画をレンダリングします。納品前にreferences/checks.mdを確認してください。 - 新しい見た目。 新しいコンセプトフレーム(白い冬の谷、赤い帽子をかぶったユキヒョウの子)を生成し、それを参照画像として同じ8枚の画像とクリップを生成します。同じ名前で
snow/game/に処理し、新しいconfig.json("tag": "_snow"を指定)を計測して、--set snowを付けて同じビルドを実行します。2つの見た目はフレーム単位で揃います。雪のクリップでは背景がずれていたため、ループは次のコマンドで作成しました。run_loop.py clip.mp4 snow/game/hero_run --key border --from 60 --to 124 --skip 0 --periods 8:16 --clean - 台帳。 Scenarioのジョブごとに1行記録します。モデル、パラメーター、入力、出力、ジョブID、費用、採用したかどうか、その理由を記載します。
よくある間違い
- 草の先端を地面のラインだと信じること:すべてのルックで、キャラクターはラン時の上下動に加えて3〜8cm浮いていました。ラインが縁に約10cm食い込むようになるまで調整していましたが、現在は
measure_set.pyがこの調整を適用します。 - ドリフトするクリップを固定のマゼンタでキーイングすること:あるランのクリップは、マゼンタから赤、黄色を経て緑に変化しました。
--key borderを使い、キャラクターの赤やピンクから離れた区間からループを作成してください。 - デフォルトの拡張設定で葉のシートを切り抜くこと:5つの前景の植物が4つのパーツになってしまいましたが、
CUT_GROW=2を指定して切り抜くことで解決しました。表示された数を名前と照合してください。 - キーイング後に、囲まれたピンク部分を確認しないこと:
prep_assets.py keyはシルエットに囲まれたピンク(猫の耳の内側など)を残しますが、耳、舌、花を確認してください。 - ランの長さをハードコードすること:猫とユキヒョウのループは12フレーム、レッサーパンダは9フレームでした。
run_loop.pyの出力からrun_nをコピーしてください。 - 幅の広いレイヤーの端に目印を置くこと:
tileは、違いが最も少ない箇所で経路の両端をつなぎ、木をそのまま残すか、削除します。ただし、重なり部分と同じくらい幅のある目印は切れてしまいます。コンテンツが幅全体に広がるようにしてください。 - ローカルパスやURLを
model_runに渡すこと:先にファイルをアップロードし、アセット ID を渡してください。 - モデル ID や価格をハードコードすること、または
jobs_waitを再実行せずにjob_getをポーリングすること。
build_scene.py自体(深度、パララックス係数、物理特性)を変更する場合は、まずreferences/pipeline.mdを読んでください。リファレンスショットで検討された決定事項が記録されています。