asset-pipeline について
生成したアートを、ゲーム用のスプライト、3Dレンダー、テクスチャ、エンジン固有のファイルに整えるスキルです。対象形式の調査から変換、ゲーム内での検証までを扱います。
主な機能
- 01ゲーム素材形式の調査
- 022Dスプライトの変換と調整
- 033Dモデルからスプライトを生成
- 04テクスチャとマテリアルの準備
- 05ゲーム内で素材を検証
活用シーン
- 01生成アートをゲームのサイズに調整
- 023Dモデルから多方向のアニメーションシートを作成
- 03エンジンの規則に合わせてテクスチャを変換
- 04変換素材を元のアートと比較
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ rehan-remade/ universal-modder --skill asset-pipelineインストール後、Claude Code で/asset-pipelineを入力して読み込まれたか確認します。
詳細
アセットパイプライン:アートからゲームで使えるファイルへ
fal-assets スキルは画像を作成します。このスキルはゲームで受け入れられるファイルを作成します。適切なサイズ、フレームレイアウト、向き、アルファ、パレット、フォーマットを整えます。コマンドはすべて um sprite ... と um render3d ... です。それぞれの --help に使用例があります。
1. ゲーム自体から対象フォーマットを確認する
変換を始める前に、ゲーム本来のアセットを2、3個開き、次の内容を MODLOG.md に書き留めます。
- 寸法: フレームサイズ、シートあたりのフレーム数、レイアウト(縦ストリップ/グリッド/フレームごとに1ファイル)。
- 向き: アートが向いている方向(Terraria:アイテムは右向き、NPC は左向きで、エンジンが反転します)、およびピボットやホットスポットの位置(AoE2:ユニットの接地点がキャンバスの中央)。
- アルファ: ハードな1ビットのエッジ(BC1 のパンチスルー、ピクセルアート)か、ソフトなエッジか。
- スタイル: パレットの色数とアウトライン(多くのピクセルアートゲームでは、暗色の1~2 px のアウトライン)。
- フォーマット: PNG、DDS BC1/BC3/BC7、XNB、SLD、アトラス + JSON など。
最終的な基準となるのは描画コードです。Terraria では、NPC のフレームの高さはテクスチャの高さ / Main.npcFrameCount で決まるため、フレームサイズが一貫していれば問題ありません。
2. 2D パイプライン
um sprite info raw.png # size, alpha coverage, corner colour
um sprite cutout raw.png cut.png # flat bg → transparent (border flood fill keeps interior whites)
um sprite cutout raw.png cut.png --grey 150 --keep-top 0.8 # also remove a soft grey shadow / the floor under it
um sprite fit cut.png item.png --size 64x26 --hard-alpha # trim + ONE nearest-neighbour scale into the frame
um sprite fit cut.png npc.png --size 38x34 --anchor bottom # standing sprites sit on the frame's bottom edge
um sprite pixelate cut.png px.png --size 32x32 --colors 16 --outline # true pixel art from painterly art
um sprite palette px.png px2.png --from stock_sprite.png # snap to the game's own colours
um sprite frames npc.png frames/ --n 3 --kind bob # cheap idle animation (bob/squash/wobble/flash)
um sprite sheet sheet.png frames/*.png --vertical # Terraria-style strip (or --cols N grid)
um sprite slice sheet.png out/ --frame 32x32 # the other direction
um sprite team-mask unit.png unit_grey.png --hue blue # player-colour mask (+ desaturated sprite)
um sprite preview item.png look.png --scale 6 # checkerboard + zoom: LOOK at it before shipping
- ピクセルアート: ニアレストネイバー方式で最終サイズまで一度だけ拡大します。ピクセルアートを二度拡大してはいけません。
- ペイント調/HD アート:
fit --smoothを使用します。 - 実際のフレーム: ボブやスクワッシュを超えるアニメーションフレームは、fal edit エンドポイントを使い、ベーススプライトを参照画像として各フレームを生成します(「同じドローン、ローターを傾ける、4フレーム中の2フレーム目」など)。次に切り抜き、各フレームを同じ方法でフィットさせます。または、3D を使います(下記)。
3. 3D → スプライト(角度とアニメーションを統一)
um fal model3d concept.png --name unit # textured GLB (Trellis 2 by default)
um render3d assets/gen/unit.glb frames/ --preset aoe2 --length 80 --forward-yaw -90 \
--anims idle:10:bob,walk:12:walk,attack:16:lunge,death:20:die --shadows --samples 40
um render3d assets/gen/unit.glb side/ --preset side --canvas 128 --length 110 --engine eevee # platformer facing R + L
プリセット:
| プリセット | 投影方式 | カメラ | 向き |
|---|---|---|---|
aoe2 | 正投影 | 30° | 東から時計回りに16方向 |
iso8 | 正投影 | 30° | 8方向 |
trueiso | 正投影 | 35.264° | 8方向 |
topdown | 正投影 | — | 8方向 |
side | 正投影 | — | 2方向(右、左) |
turntable | 透視投影 | — | 24方向(プロモーション/アイコンの回転) |
--lengthは、1x でのモデルの最長水平辺をピクセル単位で設定するため、既存ユニットのサイズに合わせます。--forward-yawは、モデルの正面が +X を向くように回転させます。最初のフレームで確認してください。--shadowsは、影を独立したレイヤーに保持するエンジン向けに、影のみのパス(*_s.png)を追加します。- モーション:ボブ、歩行、突進、死亡、残骸、回転。
- その後、
um sprite sheetまたはエンジン用ライター(例:examples/aoe2-de-civ/sld.py)でパックします。 - Blender が必要です(PATH 上の
blenderまたはBLENDER=...)。Cycles は利用可能な場合、GPU を使用します。 - 生成されたテクスチャが暗い場合は、
--sun/--ambientを上げるか、後処理で明るくします。 - ゲーム用の3Dアセット(スプライトではないもの)には、
um fal run tripo3d/tripo/remesh [email protected] face_limit:=8000でリメッシュし、エンジンのスケールと軸の規約に合わせて Blender で変換します(GLB → FBX/OBJ)。Unity は Y-up のメートル単位、Unreal は Z-up のセンチメートル単位、Bethesda NIF は PyNifly を使用します。
4. テクスチャとマテリアル
- タイリング:
um fal textureはタイリング済みのテクスチャを生成します。um sprite tile-preview t.png t3.pngで確認します。他の画像の継ぎ目はum sprite seamlessで修正します。 - PBR セット:
um fal pbrを使用します。エンジンのパッキング形式に変換します。Unreal ORM(RGB にオクルージョン/粗さ/メタルネス)、Unity メタリック・スムースネス(スムースネス = 1 - 粗さをアルファに格納)。 - DDS: texconv(DirectXTex)または DXT 設定の
magickを使用します。高品質には BC7、カットアウトスプライトには BC1、アルファがソフトな場合は BC3 を使います。
5. ゲーム内で確認する
変換したアセットを1つゲームに入れ、既存のアートの隣に並べてスクリーンショットを撮ります(um win shot)。スケール、向き、ピボット、アウトライン、パレットを確認します。レシピを修正したら、同じコマンドで残りを一括変換します(小さなスクリプトまたは Makefile を用意し、assets/gen/ から再現可能なパイプラインにします)。
6. ゲストゲームのUnityアセットを変換する(マッシュアップ)
ユーザー自身が所有するインストールをUnityPyで読み込み、ローカル限定の非公開リソースパックを書き出します。出力をMOD、そのリポジトリ、リリースに含めてはいけません。各ユーザーが自分のコピーでコンバーターを実行します。
- メモリ:
UnityPy.load()はバンドル全体を展開します(865 MBのバンドルでRAMを8.7 GB使用した例があります)。シリアライズされたファイルのみを展開し、.resS/.resourceはブロックごとに遅延読み込みします。各コンバーターモジュールは独立したプロセスで実行します。 - 環境:
UnityPy.Environment(path="")を使用し、相互参照されるバンドルはまとめて読み込みます。そうしないと、UnityPyは不足している依存関係を探すために作業ディレクトリを検索します。 - アセットの特定: Addressablesのバンドル名はアップデートごとにハッシュ化されます(プレフィックスで探します)。Addressables 2.xにはバイナリの
catalog.binがあります。ゲームオブジェクトとプレハブの対応付けには、名前を推測するのではなくGUIDキーを使用します。低品質版がある場合はそれを優先します(メッシュは同じで、テクスチャが小さくなっています)。 - スキンメッシュはバインドポーズ(多くの場合Tポーズ)で保存されています。 ゲーム内の見た目を再現するには、アイドルクリップをt = 0で自分で評価します(UnityPyはAnimationClipオブジェクトを読み込みますが、サンプリングは行いません。GenericクリップはパスのCRC32でTransformをバインドします)。ワールド行列を再構築してから、スキニングします。
- コンテナルートから階層をたどり、非アクティブなGameObjectとその子をスキップし、補助メッシュ(まぶた、地面の影、ステンシル/アウトライン用マテリアル)を除外します。
- 軸: Unityは左手座標系、Minecraftは右手座標系です。位置と法線の軸を1つ反転し、頂点の順序を逆にします。Vを反転し、UVをクランプします。名前付きボーンで確認します(右手が右側に来ること)。
- 共有アトラス: 各パーツのテクスチャをUVのバウンディングボックスに合わせて切り抜き、UVを再マッピングします。
- オーディオ:
AudioClip.samplesにはFMOD(fmod_toolkit)が必要です。ffmpegでモノラルOGGにエンコードします。 - Minecraft側: パックには
pack.mcmeta(1.20.1ではpack_format15)が必要です。ResourceLocationsで使用できる文字は[a-z0-9_./-]のみです。ポーズ付きメッシュには、forge:obj(ブロックアトラステクスチャ、usemtl)よりも、RenderType.entityCutoutNoCullで描画するカスタムメッシュファイルのほうが堅牢です。 - 検証: 書き出したファイルを再読み込みしてプレビューシートをレンダリングし、目で確認します。