本文へスキップ

当たり判定ポリゴン生成 · スプライトの透明部分から

各フレームのアルファから、エンジンに合う頂点数に抑えた衝突ポリゴンを生成(フレーム・タグ・全体)。点をドラッグして仕上げます。

スプライトのアルファからなぞった衝突ポリゴンは、ボックスよりもシルエットに沿います。Nerulioはフレームごとに、アルファのしきい値(既定127、つまり半分以上不透明なピクセルが対象)でピクセルの境界に沿って輪郭をなぞり、輪郭が自己交差しないようにしながら頂点数の上限(既定12、3〜64)に収まるまで単純化し、フレームごとに最大8個のポリゴンをフレームキャンバスのピクセルで保存します。ポリゴンはGodotバンドルのメタデータと汎用JSONに書き出され、CollisionPolygon2DノードやUnityのコライダーは作りません。

スプライトシート、連番フレーム、GIF・APNG、.asepriteファイルをドロップ
空のStudioを開く
ブラウザ内で処理し、ファイルはアップロードされません。
Studio のスプライト作業画面:ピボット・ヒットボックス・ハートボックス付きのフレームと、アニメーションタグ付きタイムライン
CC0アセット(OpenGameArt)を開いた実際のStudio画面です。
書き出し先
  • Godot 4検証済み· Godot 4.7.2
  • Unity 6検証済み· Unity 6000.5.3f1
  • Phaser 3 / 4検証済み· Phaser 3.90 + 4.2
  • PixiJS 8検証済み· PixiJS 8.21
  • Aseprite JSON検証済み· Phaser load.aseprite · PixiJS 8.21
  • .aseprite検証済み· Aseprite 1.3.18
  • Spine / libGDX検証済み· spine-canvas 4.2
  • Starling / Sparrow XML検証済み· Phaser 4.2
  • LÖVE検証済み· LÖVE 11.5
  • Defoldビルド確認· Defold bob.jar 1.13.1
  • GameMaker未検証
  • CSS sprites検証済み· Chromium
  • GIF / APNGデコード確認· Pillow

なぞる、単純化する、エンジンに点を渡す

輪郭はピクセルの中心ではなく、不透明と透明のピクセルの境目をたどるので、どの頂点も整数ピクセルの角に乗ります。16 × 16の不透明な正方形は、ちょうど (0, 0)、(16, 0)、(16, 16)、(0, 16) になります。外側の輪郭は画面上で時計回り(yは下向き)になり、4px²未満の粒は捨てます。

単純化(Ramer–Douglas–Peucker)は直線に近い点を取り除きます。許容誤差は1pxから始まり、頂点数が上限以下になるまで引き上げられ、輪郭を自己交差させる誤差は採用しません。自己交差した輪郭は物理形状として使えないからです。誤差は段階的に上がるので、上限より少ない頂点数で止まることがあり、上限が低いと両脚のあいだのようなすき間がつぶれます。

エンジンはこうしたポリゴンを、オブジェクト基準の点のリストとして受け取ります。GodotのCollisionPolygon2Dは凹ポリゴンも受け付け、既定のソリッドモードでは自分で凸の部品に分けます。Area2Dか物理ボディの子である必要があります。UnityのPolygonCollider2Dはローカル空間の点を受け取り、スプライトのCustom Physics Shapeから独自の輪郭を作ることもできます。どちらもまずフレームのピボットを引き、Unityではさらにyを反転してPixels Per Unitで割ります。

アルファしきい値
透明とみなす最大のアルファ値。127なら半分以上不透明なピクセルが残る。
頂点数の上限
単純化後のポリゴンが持てる点の最大数。
許容誤差
単純化で輪郭を動かしてよい距離(ピクセル)。

例:32 × 48のキャラクター1フレーム、3つの設定

頭・胴・4pxのすき間をあけた両脚と、頭のまわりの淡い光(アルファ60)。Nerulioの輪郭追跡で計算した値:

なぞった輪郭(アルファ > 127)          頂点48、面積544px²
上限64   誤差1px      頂点16、面積540px²(−0.7%)、最大偏差1.0px、両脚は分かれたまま
上限12   誤差3.8px    頂点5、面積428px²(−21%)、最大偏差3.8px、脚のすき間が消える
しきい値40、上限12   光も含む:面積628px²、誤差2.0pxで頂点12

Godot、ピボット (16, 48)  ポリゴンの点 (22, 48) → ノード空間 (22 − 16, 48 − 48) = (6, 0)

この例では上限12でも頂点は12になりませんでした。次の誤差の段階で一気に5まで減ったからです。形が大事なら上限を上げ、アルファから自動生成したあとにStudioが示す頂点数を比べてください。

ポリゴンの行き先

書き出し先書き出しに入るポリゴンエンジンで作るもの
Godot 4metadata/nerulio のフレームごとの collision。ポリゴンごとに x0, y0, x1, y1 … の平らなリストArea2Dかボディの下のCollisionPolygon2D。スクリプトでフレームごとに、リストからピボットを引いた値を polygon に設定
汎用JSONframes[key].collision:ポリゴンごとに [[x, y], …]点のリストを受け取るどのエンジンでも
Unity 6なし。書き出しの注記が汎用JSONを案内する汎用JSONの点でPolygonCollider2D、またはUnity独自のCustom Physics Shape
Aseprite、Phaser、PixiJS、LÖVE、Spine、Starling、Defold、GameMaker、CSSなしアトラスの隣に汎用JSONも読み込む

できること

  • アルファから自動:アルファのしきい値でピクセル格子上の輪郭をトレース。
  • ポリゴンごとの最大頂点数(簡単な物理形状なら8など)。
  • このフレーム・選択・タグ・全フレームに1回の取り消し単位で実行。
  • ポリゴンはフレームキャンバスのピクセル基準でフレームごとに保存され、フレームデータと一緒に書き出し。

使い方

  1. スプライトを入れて読み込みを適用。
  2. フレームパネルで最大頂点数とアルファのしきい値を設定。
  3. 範囲を選び「アルファから自動」を押す。
  4. 点を選んで動かすか、消して描き直してから書き出し。

結果の確認

  • アルファから自動生成すると、通知に作ったフレーム数と頂点数が出ます。タグをコマ送りしてフレームごとの輪郭を見ます。
  • 光や煙のあるフレームで、しきい値を127と低い値のあいだで切り替えて輪郭を比べます。
  • GodotでArea2Dの下に変換した点でCollisionPolygon2Dを追加し、Debug › Visible Collision Shapesをオンにしてスプライトに重ねて確認します。

トラブルシューティング

症状考えられる原因確認方法対処
ポリゴンが両脚のあいだなどのすき間を埋める頂点数の上限のせいで、すき間より大きな誤差が使われた自動生成後の頂点数が上限よりかなり少ない、または輪郭がすき間をまたぐ上限を上げて(例:24)自動生成し直す
光や煙が衝突形状に入るそのピクセルのアルファがしきい値より高いしきい値を上げ下げして比べるしきい値を上げて、淡いピクセルを透明扱いにする
エンジンで形状がずれる点はピボットではなくフレームキャンバスの左上を基準にしたピクセル例と点を1つ比べるピボットを引く。Unityではさらにyを反転しPixels Per Unitで割る
一部の部位にしかポリゴンがない離れた形状はフレームごとに8個まで、4px²未満の粒は捨てる自動生成のメッセージに捨てた粒や超過した形状が出る絵の上で部位をつなぐか、足りないポリゴンを手で描く

ほかの方法

方法こんなときに向いています
UnityのSprite EditorのCustom Physics ShapeUnity専用。Unityが輪郭を作って編集し、Polygon Collider 2Dがスプライトの新しいインスタンスでそれを使います。
フレームごとにボックスか円を1つ多くのプラットフォーマーの体。細かいポリゴンより軽く安定します。ヒットボックスエディターで描くか、従来のスプライトラボの凸包・矩形・円の選択肢を使ってください。

エンジン別の書き出しと検証方法

「検証済み」は、実際のCC0アセットから書き出したファイルを本物のエンジン・ツールで読み込み、元データと比較したという意味です。読み込んでいない形式はそのように表示します。

書き出し先ファイル検証
Godot 4.tres SpriteFrames · .tscn AnimatedSprite2D · .png.import検証済み Godot 4.7.2Godotで読み込み、全アニメーションフレームを描画して元ファイルと比較。シーンはNearestフィルターで、回転は使いません。
Unity 6.unity.json · Editor/NerulioSpriteImporter.cs · AnimationClip検証済み Unity 6000.5.3f1バッチモードでスプライト範囲・ピボット・ピクセル・クリップのキーと長さを確認。
Phaser 3 / 4atlas JSON (multiatlas) · .anims.json検証済み Phaser 3.90 + 4.2両バージョンでフレームとアニメーションを描画。
PixiJS 8spritesheet JSON · animations · anchor · meta.scale検証済み PixiJS 8.21回転・複数ページのアトラスも確認。
Aseprite JSONhash / array · frameTags · slices検証済み Phaser load.aseprite · PixiJS 8.21タグの方向と繰り返し回数を保持。
.asepritelayers · tags · durations · slices検証済み Aseprite 1.3.18Asepriteのコマンドラインで開いて描画。
Spine / libGDX.atlas検証済み spine-canvas 4.2Spineランタイムで回転・トリム領域をすべて描画。libGDX本体は未実行。
Starling / Sparrow XMLXML per page検証済み Phaser 4.2Phaser 3.90はトリムされたXMLフレームを誤って描画します(Phaser側の不具合)。「Sparrow XML (Phaser 3)」プリセットはトリムを切り、3.90・4.2とも合格。
LÖVELua quads · nerulio_atlas.lua · main.lua検証済み LÖVE 11.5同梱ヘルパーで全フレームを描画し、全アニメーションを再生。
Defold.atlas · .tilesourceビルド確認 Defold bob.jar 1.13.1Defoldのコマンドラインビルダーでビルドし、生成テクスチャのUVを読み戻して確認。
GameMakerspr_<name>_stripN.png · gamemaker.json未検証GameMakerでは読み込んでいません(ヘッドレス実行不可)。ストリップはGameMakerの取り込み方式どおりに切ります。
CSS sprites.css · preview .html検証済み Chromium同梱スタイルシートで全クラスを描画。
GIF / APNGone file per animationデコード確認 Pillow書き出し後に全フレームと遅延を再デコード。APNGは完全一致。

検証の根拠

GIFデコーダー:実在のGIF 29本で408/408フレームがPillowと一致、APNG 16本で132/132。.aseprite:コーパス231ファイルを読み込み・書き直し、Aseprite 1.3.18で開いてタグ・長さ・ピクセルが231/231一致。書き出し:実在のCC0アセットで実際のエンジンを49回実行し47回合格。失敗2回はPhaser 3.90のトリムXMLの不具合で、Phaser 3プリセットで回避できます。

制限

  • ポリゴンは書き出しにデータとして入るだけで、CollisionPolygon2DノードやUnityのコライダーは作りません。
  • 衝突ポリゴンはUnity、Aseprite、アトラス形式には入りません。汎用JSONを使ってください。
  • 形状の中の穴はStudioのポリゴンに含まれません。
  • グリッド・島の推定は信頼度つきのプレビューで、「適用」を押すまで何も切りません。すべての選択に代替案があり、ワンクリックで切り替えられます。
  • レイヤーが正確に合成できない.asepriteファイル(グループの不透明度など)は統合して読み込み、理由を読み込みパネルに表示します。
  • 読み込んだアトラス内の回転フレームは回転したままで、その書き出しは未検証です。
  • 画像は一辺32,768px(2億6,800万ピクセル)まで。ブラウザのメモリにも依存します。

バージョンと出典

輪郭の追跡と例の数値はNerulio自身のモジュール(src/game/contour.js)によるものです。メタデータ入りのGodotバンドルはGodot 4.7.2で読み込みましたが、その実行で衝突ポリゴンを物理形状として使ったわけではありません。エンジンの動作はGodot 4.7とUnity 6のドキュメントに従います。

参照した公式ドキュメント

従来のツール

フレームごとの凸包・矩形・円のフォールバックは従来のスプライトラボにあります。

従来のツールを開く →

よくある質問

光のにじみのような薄いピクセルも含まれますか?

しきい値を超えるピクセルだけが対象です。薄い光を除くなら上げ、含めるなら下げてください。

ポリゴンは簡略化されますか?

はい。指定した頂点数まで減らし、すべての点はフレームキャンバス内に収まります。

無料ですか?アカウントは必要ですか?

このページの機能はすべて無料で、アカウントなしで使えます。透かしや制限された書き出しはありません。

スプライトはアップロードされますか?

いいえ。Studioはこのブラウザのタブ内でデコード・パック・書き出しを行います。プロジェクトはブラウザ(IndexedDB)に自動保存され、.nerulioファイルとして保存できます。

Asepriteやエンジンのプラグインは必要ですか?

いいえ。.asepriteファイルはブラウザで読み書きします。エンジン別のバンドルには必要なものが入っています(Godotはインポート設定とシーン、UnityとGodotのタイルセットは小さなエディタースクリプト)。