Communitygithub.com

pipeline-de-animación-de-sprites

Importa hojas de sprites o fotogramas ordenados existentes y ajusta el cortado, las referencias de atlas, los pivotes o la temporización en Godot 4, Unity 6 o Phaser 3; no está destinado a generar arte ni montajes esqueléticos.

¿Qué es pipeline-de-animación-de-sprites?

Esta habilidad especializada para agentes de IA permite importar y refinar animaciones 2D a partir de hojas de sprites o fotogramas ordenados en los motores Godot 4, Unity 6 y Phaser 3, sin generar arte nuevo ni manipulaciones esqueléticas. Se basa en el arte existente, por lo que resulta especialmente útil cuando se dispone de activos generados previamente (por ejemplo, con `pixo media generate`) y se desea corregir la temporización, los pivotes, las referencias de atlas o el cortado sin alterar la animación original. El agente realiza análisis iniciales con `pixo asset info` y `pixo asset frames check`, decide si repicar o usar la hoja directamente, y luego integra el resultado en el sistema de animación del motor respetando las convenciones del proyecto y las elecciones explícitas del usuario. Soporta formatos como `godot-tres` y `texturepacker-json`, y verifica la calidad final mediante `pixo game verify`. Incluye fragmentos de código específicos para cada motor, tablas de decisión para la conversión de formatos y advertencias sobre problemas comunes como orden lexicográfico incorrecto o unidades de duración inconsistentes entre motores.

Compatible con~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/OpenPixo/OpenPixo/tree/HEAD/skills/sprite-animation-pipeline

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

Pipeline de animación de sprites

Importa fotogramas ordenados o hojas en Godot 4, Unity 6 o Phaser 3. Corrige la temporización de la animación, las referencias de atlas y los pivotes. Tienen prioridad las convenciones del proyecto, las versiones instaladas, la arquitectura, el estilo artístico y las elecciones explícitas del usuario. Conserva una hoja y un formato funcionales cuando la tarea solo cambia la temporización; el cortado y el reempaquetado son opcionales. Este flujo de trabajo utiliza arte existente en lugar de generar nuevas animaciones; los nuevos fotogramas provienen de pixo media generate --sheet <C>x<R> --frames (la sección de medios del prompt), que los escribe ya en un mismo lienzo.

Ruta rápida

  1. Inspecciona la hoja o los fotogramas seleccionados con pixo asset info <ruta> --json; lee las definiciones de clips actuales.
  2. Confirma el tamaño y orden de las celdas, los rangos de clips, la línea de base, el pivote y la temporización para bucles o de una sola toma. pixo asset frames check <fotogramas...> --json mide la línea de base y la deriva por ti.
  3. Elige la rama directa de hoja o de empaquetado a continuación; lee las rutas de salida reales de la operación.
  4. Integra mediante el propietario de animación existente del motor sin mover la colisión de gameplay.
  5. Ejecuta pixo game verify --steps check,build,run --screenshot --json, inspecciona los registros y los fotogramas, y luego observa un bucle completo y una toma única de forma interactiva.

Los comandos asumen PIXO_PROJECT_ID; en caso contrario, añade --project <id>. Las rutas y los recuentos de fotogramas que aparecen a continuación son ejemplos; las hojas sin metadatos no identifican sus propios clips. Unity no tiene paso run ni captura de pantalla aquí: usa --steps check,build y mira los clips en el Editor.

Elige el cambio de formato más pequeño

Entrada o solicitudEligeConserva
Hoja regular funcional, cambio solo de temporizaciónSpriteFrames existentes, clip de Unity o hoja de PhaserRangos de fotogramas, clave de textura, línea de base compartida
Cuadrícula regular necesita fotogramas separadospixo asset slice --cell AnxAl o --grid CxR con una ruta de entradaMargen, espaciado y cobertura esperada
Los fotogramas tiemblan, se deslizan o difieren en tamañopixo asset frames check, luego frames alignOrden de entrada, una escala para cada fotograma
PNGs ordenados para Godotpack --format godot-tresOrden de entrada; mantener PNG y TRES juntos
PNGs ordenados para Phaserpack --format texturepacker-jsonOrden de entrada, claves de descriptor reales
Hoja o fotogramas para UnityImportar como Sprite y cortar en Unity; pack no tiene salida UnityPivote, Píxeles por Unidad, .meta existente
Fotogramas recortados con pivotes personalizadosPipeline existente con metadatosDesplazamientos de recorte y pivotes; el empaquetado solo de imágenes no puede recuperarlos

Registra solo los campos contractuales relevantes: tamaño del lienzo y de la celda, orden por filas, rangos de clips, FPS, retenciones de fotogramas, bucle y la línea de base para los pies. Los lienzos del mismo tamaño con un anclaje compartido evitan el bamboleo entre fotogramas; los límites opacos no son el pivote.

Anclajes de cortado y empaquetado

pixo asset slice assets/public/player.png --cell 32x32 --out derived/player-frames --dry-run --json
pixo asset slice assets/public/player.png --cell 32x32 --out derived/player-frames --json
pixo asset pack sprites/run/frame-0000.png sprites/run/frame-0001.png --format godot-tres --padding 1 --out derived/run-godot --json
pixo asset pack sprites/public/run/frame-0000.png sprites/public/run/frame-0001.png --format texturepacker-json --padding 1 --out public/atlases/run --json

Usa las rutas PNG devueltas en el informe de cortado; los comandos de empaquetado de dos fotogramas solo ilustran el orden. --grid requiere división exacta después del margen y el espaciado; --cell puede dejar sin usar celdas de borde incompletas. Comprueba la cobertura total y el recuento de fotogramas. Excluye deliberadamente celdas vacías y fotogramas de otros clips. Lee results, extraOutputs, reportPath, los fallos y originalsPreserved; los destinos existentes se omiten.

Datos del empaquetador:

  • La raíz deriva de la primera entrada y conserva sus directorios relativos por debajo de --out; lee las rutas en lugar de adivinarlas.
  • Las salidas son <raíz>.atlas.png más .atlas.tres o .atlas.json.
  • El empaquetado puede reorganizar la colocación espacial, pero los descriptores conservan el orden de entrada.
  • No se generan rotación, recorte, extrusión de bordes, nombres de clips ni pivotes personalizados.
  • El relleno es separación transparente, no píxeles de borde duplicados.

Comprobar y alinear fotogramas

pixo asset frames check public/assets/hero/hero-run-1.png public/assets/hero/hero-run-2.png public/assets/hero/hero-run-3.png --json
pixo asset frames align public/assets/hero/hero-run-*.png --canvas 64x64 --padding 1 --out derived/hero-run --json

Pasa los fotogramas en orden de reproducción (un glob del shell ordena -10 antes que -2; enuméralos cuando haya diez o más). frames check no escribe imágenes. Por fotograma, results[].detail tiene los bounds dibujados, bottomGap (filas debajo de los pies), feetX (centro de las filas más bajas, que un arma balanceada no mueve), empty y touchesEdge. summary juzga el conjunto: baselineSpreadPx (bamboleo de pies), feetXSpreadPx (deslizamiento), heightDriftPercent, emptyFrames, edgeFrames y una frase simple por problema en issues; ok es verdadero cuando no hay ninguno. Una cuclilla, un aplastamiento o un salto cambian la altura a propósito; la misma pose a diferentes alturas es deriva del modelo.

frames align escribe cada fotograma en <out>/<ruta de entrada>.png sobre un lienzo: los pies en una línea padding por encima del borde inferior, feetX en la línea central, una escala para todos para que una cuclilla siga siendo más baja que una postura erguida. --canvas AnxAl escala cada fotograma por el mismo factor para que quepa; sin él, el lienzo es el más pequeño que los contiene a todos. --match-height primero escala cada dibujo a la altura mediana, solo para la deriva. --filter nearest mantiene el arte de píxel nítido. Su summary vuelve a comprobar los fotogramas alineados. Las salidas existentes se omiten, como en toda operación de activos.

Godot 4: temporización de SpriteFrames

godot-tres emite SpriteFrames formato=3 con un clip default en bucle a 5 FPS. Mantén PNG y TRES juntos; la referencia de textura es relativa. Importa nuevas imágenes mediante pixo game verify --steps check --json.

Después de sustituir la ruta notificada, esto adapta un clip real de cuatro fotogramas:

func configure_run(sprite: AnimatedSprite2D) -> void:
    var packed := load("res://sprites/run/run.atlas.tres") as SpriteFrames
    if packed == null or packed.get_frame_count(&"default") != 4:
        push_error("Se esperaban cuatro fotogramas de carrera")
        return
    var frames := packed.duplicate() as SpriteFrames
    frames.rename_animation(&"default", &"run")
    frames.set_animation_speed(&"run", 10.0)
    frames.set_animation_loop(&"run", true)
    frames.set_frame(&"run", 0, frames.get_frame_texture(&"run", 0), 2.0)
    sprite.sprite_frames = frames
    sprite.centered = true
    sprite.offset = Vector2(0, -16) # Ejemplo: anclaje centro-inferior en un lienzo de 32px.
    sprite.play(&"run")

La duración del fotograma 2.0 significa el doble de la duración normal del fotograma, no dos segundos. Usa la línea de base acordada para el desplazamiento; mantén estables CharacterBody2D y CollisionShape2D. Los clips de una sola toma necesitan loop=false; conecta animation_finished una vez y controla la transición mediante la animación activa. Referencia: Godot 4.3 SpriteFrames.

Phaser 3: temporización de hoja o atlas

// preload(), para una hoja real de 32px:
this.load.spritesheet('player', 'assets/player.png', { frameWidth: 32, frameHeight: 32 });
// create(), con el rango de carrera real del proyecto:
if (!this.anims.exists('player-run')) {
  this.anims.create({ key: 'player-run',
    frames: this.anims.generateFrameNumbers('player', { start: 2, end: 5 }),
    frameRate: 10, repeat: -1 });
}
player.setOrigin(0.5, 1).play('player-run', true);

Los activos públicos de Vite se cargan sin public/ en la URL. Para atlas, this.load.atlas(key, pngUrl, jsonUrl) carga el par devuelto. Las claves hash de TexturePacker son las rutas relativas al proyecto de entrada; léelas o usa getFrameNames(). Usa una lista ordenada explícita cuando los nombres no codifiquen el orden.

// orderedNames proviene de la lista de descriptores/clips revisada.
this.anims.create({ key: 'hero-run', frameRate: 10, repeat: -1,
  frames: orderedNames.map((frame, index) => ({
    key: 'hero-atlas', frame, duration: index === 0 ? 100 : 0,
  })),
}); // A 10 FPS, 100 ms extra mantienen el primer fotograma durante 200 ms en total.

Protege la creación de animaciones globales con this.anims.exists como arriba; las claves sobreviven a los reinicios de Escena. repeat: 0 se reproduce una vez; usa un listener de finalización de toma única propio. Cambiar el origen afecta la colocación del cuerpo; inspecciona el tamaño y el desplazamiento en lugar de mover la colisión para ocultar un pivote malo. Referencia: Tipos de animación de Phaser 3.90.

Unity 6: importador, clip y Animator

Unity no lee ni godot-tres ni JSON de TexturePacker sin un paquete adicional. Coloca la hoja en Assets/, luego establece Texture Type Sprite, Sprite Mode Multiple y los Pixels Per Unit reales. Para arte de píxel, añade filtro Point y sin compresión. Corta por tamaño de celda en el Sprite Editor, con un pivote compartido como Bottom. El cortado mediante script pasa por ISpriteEditorDataProvider de SpriteDataProviderFactories; TextureImporter.spritesheet es la ruta antigua. com.unity.2d.aseprite importa archivos .aseprite directamente, con clips, cuando el arte comienza allí.

Los clips se pueden hacer seleccionando sprites y soltándolos en la ventana Animation, o desde un script cuando hay muchos. Este ejemplo solo para Editor construye un clip en bucle de cuatro fotogramas y mantiene el primer fotograma:

using System;
using System.Linq;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEngine;

public static class HeroClips
{
    [MenuItem("Tools/Create Hero Run Clip")]
    public static void CreateRun()
    {
        const float frame = 0.1f; // 10 FPS.
        // LoadAllAssetsAtPath no tiene orden prometido, y hero_10 se ordena antes que hero_2 como texto.
        var sprites = AssetDatabase.LoadAllAssetsAtPath("Assets/Art/hero.png").OfType<Sprite>()
            .OrderBy(sprite => int.Parse(Regex.Match(sprite.name, @"\d+$").Value))
            .Skip(2).Take(4).ToArray();
        if (sprites.Length != 4) throw new InvalidOperationException("Se esperaban cuatro fotogramas de carrera");
        var keys = sprites.Select((sprite, index) => new ObjectReferenceKeyframe {
            time = index == 0 ? 0f : (index + 1) * frame, value = sprite,
        }).ToArray();
        var clip = new AnimationClip { frameRate = 1f / frame };
        AnimationUtility.SetObjectReferenceCurve(clip,
            EditorCurveBinding.PPtrCurve("", typeof(SpriteRenderer), "m_Sprite"), keys);
        var settings = AnimationUtility.GetAnimationClipSettings(clip);
        settings.loopTime = true;
        settings.stopTime = (sprites.Length + 1) * frame;
        AnimationUtility.SetAnimationClipSettings(clip, settings);
        AssetDatabase.CreateAsset(clip, "Assets/Animations/hero_run.anim");
    }
}

Los tiempos clave están en segundos, por lo que una retención es un espacio mayor entre claves. Establece stopTime para que el último fotograma tenga su duración completa.

  • En el Animator, las transiciones de sprite generalmente quieren Has Exit Time desactivado y Transition Duration 0, o la pose siguiente llega tarde.
  • animator.Play(hash) deja un estado que ya se está reproduciendo solo, por lo que llamarlo cada actualización es seguro. Volver a reproducir una toma única necesita Play(hash, 0, 0f). Hashea los nombres una vez con Animator.StringToHash.
  • Detecta el final de una toma única con un Animation Event, o comprueba normalizedTime >= 1 mientras IsInTransition(0) es falso y el hash del estado coincide. Una transición puede, de lo contrario, informar del estado anterior.
  • Coloca el Animator y el SpriteRenderer en un hijo, con el Rigidbody2D y el collider en la raíz, y desactiva Apply Root Motion. flipX no voltea colliders ni objetos hijo, y refleja alrededor del pivote, por lo que un pivote descentrado salta.
  • Las mallas de sprites ajustadas pueden recortar efectos dibujados sobre el fotograma; usa Full Rect cuando un sombreador muestree más allá del contorno.
  • Un Sprite Atlas agrupa por lotes fotogramas importados por separado. Dale relleno y desactiva Tight Packing y Allow Rotation para arte de píxel.

Errores comunes: incorrecto → correcto

IncorrectoCorrecto, y por qué
Ordenar nombres de archivo sin relleno lexicográficamenteOrden explícito; frame-10 precede a frame-2 en caso contrario
Recortar cada fotograma independientementeMantener el lienzo o los desplazamientos válidos para que los pies permanezcan plantados
Adivinar nombres base empaquetadosLeer las claves del descriptor y las rutas de salida devueltas
Usar la misma unidad de duración en cada motorGodot usa multiplicadores relativos, Phaser duración de fotograma añade milisegundos, las claves de Unity están en segundos
Llamar a play(key) cada actualizaciónplay(key, true) evita reiniciar un clip ya activo
Dejar que la velocidad visual del clip cambie el daño o la física implícitamenteMantener la temporización del juego como autoridad a menos que esté acoplada explícitamente

Hecho cuando

  • El recuento real de fotogramas, el orden de los fotogramas, la temporización del clip, el bucle y el comportamiento de una sola toma coinciden con la solicitud.
  • Los pies y los pivotes permanecen estables a través de transiciones entre reposo y carrera, reflejo y reinicio; pixo asset frames check informa ok para cada estado, o sus problemas restantes son deliberados.
  • Las referencias de atlas y las rutas de carga son reales; los cambios visuales preservan el comportamiento de colisión.
  • Usa pixo game run <projectId> --json, o el Editor en Unity, para ver bucles completos y la finalización de una sola toma; una imagen fija no puede probar la temporización. Informa las temporizaciones probadas y los problemas no resueltos.
  • Inspecciona pixo game verify --steps check,build,run --screenshot --json, incluidos los errores de recursos y los pasos omitidos.

Individual skills in this repo

This repo contains 3 individual skills — each has its own dedicated page.

Skills relacionados