AI 비전 모델로 Unity 스프라이트 시트 슬라이싱과 피벗 계산 자동화하기

AI 비전 모델의 영역·마스크·기준점 후보를 검증해 Unity Sprite 슬라이싱과 피벗 계산에 연결하는 설계안을 설명합니다. 좌표 변환·검증 함수와 임포트 시 확인할 조건을 정리합니다.

✓ 복사 완료!
챕터아트 에셋 제작 워크플로
난이도중급
상태● 검토 완료
대상 엔진
Unity
최종 업데이트
AI 비전 모델로 Unity 스프라이트 시트 슬라이싱과 피벗 계산 자동화하기

핵심 요약

AI 비전 모델에 스프라이트 시트 이미지를 입력하고 각 프레임의 바운딩 박스와 마스크를 반환받으면 수동 Slice 작업을 자동화할 수 있습니다. 검출된 마스크의 중심이나 발 부분을 기준으로 정규화 좌표를 계산해 Unity의 Sprite Pivot에도 자동으로 반영할 수 있습니다.

이 설계안은 bbox, mask, anchor를 분리해 검토합니다. bbox는 잘라낼 사각형 후보, mask는 유효 픽셀 판정에 사용할 데이터, anchor는 발이나 무기 손잡이 같은 기준점 후보입니다. 마스크를 반환받는 것만으로 투명 여백이 제거되지는 않으므로 마스크의 경계와 잘라낼 사각형을 후처리에서 계산합니다.

왜 스프라이트 시트 슬라이싱과 피벗 계산을 자동화해야 하는가?

이 글은 여러 애니메이션 프레임이 하나의 PNG에 저장된 스프라이트 시트를 가정합니다. Unity Sprite Editor에서 수동으로 Slice하고 Pivot을 지정하는 기준 작업과 다음 상황의 자동화 후보를 비교할 수 있습니다. 작업 시간과 재검수 비용은 실제 에셋으로 측정합니다.

  • 캐릭터와 이펙트 프레임이 수백 장 이상인 경우
  • 프레임마다 투명 여백과 크기가 다른 경우
  • 캐릭터의 발 위치를 기준으로 정렬해야 하는 경우
  • 외주나 생성형 이미지 도구로 만든 리소스의 규칙이 일정하지 않은 경우
  • 원본 이미지를 교체할 때 같은 설정을 반복 적용해야 하는 경우

같은 Transform에서 재생할 때 발 위치가 각 사각형의 중심을 기준으로 달라지는 시트라면 Center Pivot에서 발이 흔들릴 수 있습니다. 크기가 다르다는 이유만으로 반드시 흔들리는 것은 아닙니다. 하단 중앙도 공중 이펙트나 무기 손잡이의 원하는 기준점과 일치하는지 확인해야 합니다.

스프라이트 사각형·마스크·기준점과 자동화 패널 구상을 표현한 설명용 이미지

이미지의 검증 건수와 코드 패널은 실제 Unity 도구의 실행 결과나 공식 API 예제가 아니다.

AI 비전 모델은 스프라이트 시트를 어떻게 분석하는가?

자동화 파이프라인은 크게 이미지 분석 단계와 Unity 임포트 단계로 나눕니다.

단계입력출력주요 책임
이미지 분석PNG 또는 RGBA 이미지객체별 bbox, mask, anchor프레임과 의미 있는 기준점 검출
후처리모델 결과정렬된 SpriteRegion 목록중복 제거, 작은 영역 제거, 순서 정렬
Unity 임포트SpriteRegion 목록Sprite rect와 pivotTextureImporter 또는 Sprite Editor 데이터 갱신
검증원본과 임포트 결과오류 목록누락 프레임, 겹침, 잘못된 Pivot 확인

모델에는 단순히 스프라이트를 찾아줘라고 요청하기보다 결과 형식을 명확히 지정하는 편이 좋습니다. 예를 들어 반환 데이터는 다음처럼 고정할 수 있습니다.

{
  "imageWidth": 2048,
  "imageHeight": 2048,
  "sprites": [
    {
      "id": "player_run_00",
      "bbox": { "x": 32, "y": 180, "width": 176, "height": 292 },
      "mask": "base64-or-rle-data",
      "anchor": { "x": 119, "y": 468 },
      "confidence": 0.98
    }
  ]
}

이 예제의 모델 좌표는 좌측 상단 원점이며 Unity Sprite 사각형은 좌측 하단 원점으로 변환합니다. 원점뿐 아니라 픽셀의 경계 좌표인지 중심 좌표인지도 기록해야 합니다. 여기서는 이미지 바깥 경계가 0과 너비·높이가 되는 연속 좌표를 사용합니다. 정수 픽셀 인덱스를 변환하는 규약에서는 Y 반전이 imageHeight - 1 - y가 되므로 혼용하지 않습니다.

바운딩 박스와 알파 마스크 중 무엇을 사용해야 하는가?

두 방법은 서로 대체 관계라기보다 함께 사용하는 것이 좋습니다.

방식장점단점적합한 용도
바운딩 박스사각형 좌표만으로 잘라낼 영역을 지정투명 여백이 남을 수 있음규칙적인 캐릭터 시트의 후보
알파 마스크실제 픽셀 영역에 가깝게 자름작은 노이즈 제거가 필요함생성형 이미지, 이펙트
세그멘테이션 마스크객체별 유효 픽셀 후보를 제공실제 모델 호출·후처리 비용과 분리 정확도를 측정해야 함겹친 객체, 복잡한 시트의 후보

이 글에서는 비전 모델의 후보 영역과 마스크의 유효 픽셀을 함께 검사합니다. 8비트 알파에서 alpha >= alphaThreshold를 유효 픽셀로 정의하면 임계값을 높일수록 유지되는 픽셀이 줄어듭니다. alphaThreshold = 8은 실험값이며 0~7인 픽셀은 제외됩니다. 반투명 외곽선·그림자·안티앨리어싱이 잘리지 않는지 실제 원본과 비교합니다.

Unity에서 Sprite 영역과 Pivot을 어떻게 계산할까?

Unity의 Sprite.Create API는 Pivot을 사각형에 대한 정규화 좌표로 받습니다. 이 글은 사각형 내부 기준점을 사용해 0~1 범위를 검증하는 설계안입니다. 기준점과 사각형을 같은 좌측 하단 좌표계로 맞춘 뒤 너비·높이가 양수인 경우 다음처럼 계산합니다.

pivotX=(anchorX−rectX)/rectWidth pivotX = (anchorX - rectX) / rectWidth pivotY=(anchorY−rectY)/rectHeight pivotY = (anchorY - rectY) / rectHeight

단, 모델 좌표의 Y축이 위에서 아래로 증가한다면 Unity 좌표로 변환해야 합니다.

anchorYUnity=imageHeight−anchorYModel anchorY_Unity = imageHeight - anchorY_Model

영역 밖의 기준점을 무조건 clamp하면 잘못된 모델 결과가 숨겨질 수 있습니다. 아래 함수는 입력이 유한하고 계산한 Pivot이 0~1인지 확인하며 범위를 벗어나면 오류로 돌려보냅니다. spriteRect는 이미 Unity 좌표이고 modelOriginIsTopLeft는 기준점에만 적용합니다. 이미지 경계 안의 사각형인지는 별도 Region 검증으로 확인합니다.

using UnityEngine;

public static class SpritePivotCalculator
{
    public static Vector2 CalculatePivot(
        Rect spriteRect,
        Vector2 anchorInImage,
        int imageHeight,
        bool modelOriginIsTopLeft)
    {
        if (imageHeight <= 0 || !IsFinite(spriteRect.x) || !IsFinite(spriteRect.y)
            || !IsFinite(spriteRect.width) || !IsFinite(spriteRect.height)
            || spriteRect.width <= 0f || spriteRect.height <= 0f
            || !IsFinite(anchorInImage.x) || !IsFinite(anchorInImage.y))
            throw new System.ArgumentException("Invalid rectangle or anchor.");

        var anchor = anchorInImage;

        if (modelOriginIsTopLeft)
        {
            anchor.y = imageHeight - anchor.y;
        }

        var pivot = new Vector2(
            (anchor.x - spriteRect.x) / spriteRect.width,
            (anchor.y - spriteRect.y) / spriteRect.height);

        if (!IsFinite(pivot.x) || !IsFinite(pivot.y)
            || pivot.x < 0f || pivot.x > 1f || pivot.y < 0f || pivot.y > 1f)
            throw new System.ArgumentException("Anchor lies outside the sprite rectangle.");
        return pivot;
    }

    private static bool IsFinite(float value) =>
        !float.IsNaN(value) && !float.IsInfinity(value);
}

캐릭터의 발 위치를 Pivot으로 사용한다면 모델이 foot_anchor를 직접 반환하도록 만들 수 있습니다. 모델이 의미 기반 Anchor를 안정적으로 찾지 못하는 경우에는 마스크의 하단 중앙을 대체값으로 사용할 수 있습니다.

public static Vector2 CalculateBottomCenterPivot(Rect spriteRect)
{
    return new Vector2(0.5f, 0f);
}

이펙트는 중심점이 더 적합할 수 있고 투사체는 진행 방향에 따라 좌우 기준점이 필요할 수 있습니다. 따라서 프로젝트에서는 pivotMode를 데이터에 저장하는 편이 안전합니다.

public enum PivotMode
{
    Center,
    BottomCenter,
    ModelAnchor,
    Custom
}

스프라이트 프레임 순서는 어떻게 보정하는가?

반환된 배열을 애니메이션 순서로 사용할지는 별도로 검증해야 합니다. 이 예제에서는 바운딩 박스 위치로 행과 열을 추정하는 후보안을 사용합니다.

  1. y 좌표가 비슷한 영역을 같은 행으로 묶습니다.
  2. 행 내부에서는 x 좌표 오름차순으로 정렬합니다.
  3. 위에서 아래 또는 아래에서 위 중 프로젝트 규칙에 맞는 방향을 선택합니다.
  4. 파일명에 run_00, run_01처럼 연속 번호를 부여합니다.

행 판정 허용 오차를 이미지 높이의 비율로 두는 후보안은 다음과 같습니다. 0.03은 실험값이며 실제 행 간격보다 커서 서로 다른 행을 합치지 않는지 확인합니다. 고정 픽셀값과 비교해 적절한 방식을 선택합니다.

rowTolerance=imageHeight∗0.03 rowTolerance = imageHeight * 0.03

여러 애니메이션이 한 시트에 있다면 animationGroup과 frameIndex를 요청하고 수동 정답과 비교할 수 있습니다. 값을 요청하는 것만으로 순서 정확성이 보장되지는 않으며 중복·누락·연속 번호를 검증합니다.

AI 비전 모델과 Unity 에디터를 어떻게 연결할까?

이 설계안은 Unity Editor 도구에서 분석한 결과 JSON을 저장해 임포트 때 재사용합니다. 해당 분석 단계의 네트워크 호출을 빌드에서 생략할 수 있지만 프로젝트 전체의 네트워크 의존성이 사라지는 것은 아닙니다. 같은 결과 JSON, 원본, 후처리·임포트 버전을 사용했을 때 Sprite 메타데이터가 재현되는지 확인합니다.

flowchart LR
    A[Sprite Sheet PNG] --> B[Editor 분석 요청]
    B --> C[AI Vision Model]
    C --> D[bbox mask anchor JSON]
    D --> E[좌표 변환 및 정렬]
    E --> F[Sprite rect pivot 적용]
    F --> G[검증 리포트]

권장 디렉터리 구조는 다음과 같습니다.

Assets/
  Art/
    Characters/player_run.png
  ArtMeta/
    Characters/player_run.json
  Editor/
    SpriteSheetAutomation/
      SpriteSheetAnalyzer.cs
      SpriteSheetImporter.cs

ArtMeta에 분석 결과를 캐시하고 이미지 SHA-256, 모델·프롬프트 버전, 전처리 설정을 키에 포함합니다. 모델이나 설정이 바뀌면 이미지가 같아도 캐시 갱신이 필요할 수 있습니다. 후처리·임포트 버전과 수동 수정값은 별도로 기록해 최종 메타데이터의 변경을 추적합니다.

Step 1. 모델 결과를 검증한다

모델 결과를 Unity에 적용하기 전에 다음 조건을 확인합니다.

아래 confidence는 모델이 제공한 점수라고 가정하며 보정된 정확도 확률로 해석하지 않습니다. 0.7과 최소 2픽셀은 초기 실험 조건입니다. 함수는 단일 사각형의 크기·경계·점수만 검사하므로 마스크, 기준점, ID 중복과 프레임 간 겹침은 추가로 검증해야 합니다.

  • width와 height가 0보다 큰가
  • 바운딩 박스가 이미지 경계를 벗어나지 않는가
  • 신뢰도가 최소 기준 이상인가
  • 서로 다른 프레임의 겹침 비율이 지나치게 높지 않은가
  • 지나치게 작은 영역이 노이즈로 포함되지 않았는가
public static bool IsValidRegion(SpriteRegion region, int imageWidth, int imageHeight)
{
    if (region == null || imageWidth <= 0 || imageHeight <= 0)
        return false;
    bool IsFinite(float value) => !float.IsNaN(value) && !float.IsInfinity(value);
    if (!IsFinite(region.confidence) || region.confidence < 0.7f || region.confidence > 1f)
    {
        return false;
    }

    if (!IsFinite(region.rect.x) || !IsFinite(region.rect.y)
        || !IsFinite(region.rect.width) || !IsFinite(region.rect.height)
        || region.rect.width < 2f || region.rect.height < 2f)
    {
        return false;
    }

    return region.rect.xMin >= 0f &&
           region.rect.yMin >= 0f &&
           region.rect.xMax <= imageWidth &&
           region.rect.yMax <= imageHeight;
}

Step 2. Unity 좌표계로 변환한다

모델이 좌측 상단 원점을 사용한다면 Unity의 하단 원점에 맞게 Y 좌표를 변환합니다.

public static Rect ToUnityRect(
    Rect modelRect,
    int imageHeight,
    bool modelOriginIsTopLeft)
{
    if (!modelOriginIsTopLeft)
    {
        return modelRect;
    }

    var unityY = imageHeight - modelRect.y - modelRect.height;

    return new Rect(
        modelRect.x,
        unityY,
        modelRect.width,
        modelRect.height);
}

사각형과 기준점은 서로 다른 데이터이므로 각각 한 번씩 변환해야 합니다. 위 ToUnityRect는 사각형을 변환하고 앞의 CalculatePivot은 전달받은 기준점만 변환합니다. 파싱 단계에서 둘 다 Unity 좌표로 바꿨다면 이후 호출의 modelOriginIsTopLeft는 false로 둡니다. 변환 전에는 유한한 좌표·양수 너비·높이와 이미지 경계를 검증합니다.

Step 3. Sprite Editor 데이터에 적용한다

Unity 2D Sprite 패키지의 Sprite Editor Data Provider 문서를 기준으로 ISpriteEditorDataProvider에서 Sprite 사각형과 Pivot을 갱신할 수 있습니다. 아래 예제는 계산·검증 함수 조각이며 전체 임포터 구현은 포함하지 않습니다. 실제 프로젝트의 엔진·패키지 버전에 맞춰 프로바이더 초기화와 적용 절차를 구현합니다.

개념적으로 필요한 데이터는 다음과 같습니다.

[System.Serializable]
public class SpriteRegion
{
    public string id;
    public Rect rect;
    public Vector2 anchor;
    public float confidence;
    public Vector2 pivot;
}

에디터 적용 단계에서는 SpriteRect의 이름·사각형·Pivot과 함께 alignment를 SpriteAlignment.Custom으로 설정합니다. 기존 Sprite의 ID를 보존하고 새 Sprite에는 ID를 발급해 참조가 바뀌지 않는지 확인합니다. Unity 2021.2 이상에서 이름·파일 ID 매핑을 관리하는 ISpriteNameFileIdDataProvider 절차도 문서와 대조합니다. 프로바이더의 Apply()를 호출한 뒤 TextureImporter.SaveAndReimport() 등으로 다시 임포트해 결과를 검증합니다.

자동 계산된 Pivot은 어떻게 검증해야 하는가?

Pivot 계산의 성공 여부는 숫자만 확인해서는 알기 어렵습니다. 반드시 시각적 오버레이와 실제 애니메이션 재생을 함께 검증해야 합니다.

캐릭터 프레임의 사각형·기준점과 정렬선을 겹쳐 표현한 설명용 이미지

검증 도구에는 다음 정보를 표시하면 좋습니다.

검증 항목확인 방법실패 시 대응
프레임 누락예상 프레임 수와 결과 수 비교낮은 신뢰도 결과 재분석
잘림원본 위에 rect 표시padding 추가 또는 bbox 확장
발 미끄러짐동일한 Transform에서 애니메이션 재생foot anchor 재계산
이펙트 중심 불일치중앙 기준선과 pivot 표시pivotMode를 Center로 변경
순서 오류프레임 번호와 미리보기 비교행·열 정렬 규칙 수정

같은 발 지지점을 고정하려는 애니메이션은 같은 Transform에서 재생해 해당 지점이 유지되는지 확인합니다. 걷기나 점프처럼 의도된 발 움직임까지 없애려 하지 않습니다. 기준점이 어긋나면 모델 검출, 마스크의 그림자·이펙트, 좌표 변환과 사각형 경계를 함께 조사합니다.

정확도와 처리 비용을 함께 관리하는 방법은?

모델 호출 수와 입력 크기, 처리 시간·과금 조건을 측정하고 다음 캐시·검수 규칙을 시험합니다.

  • 이미지와 모델·프롬프트·전처리 설정의 캐시 키가 같으면 이전 JSON 결과를 재사용합니다.
  • 분석 전에 PNG의 빈 여백을 제거하지 말고 원본 크기를 유지합니다.
  • 낮은 해상도로 1차 검출한 뒤 원본 해상도에서 좌표를 보정합니다.
  • 모델 결과를 confidence 기준으로 필터링하되 실패한 파일은 별도 목록에 남깁니다.
  • 사람이 수정한 Pivot은 manualOverride로 저장해 다음 분석에서 보존합니다.
  • 모델 프롬프트와 후처리 버전을 함께 기록합니다.

이 설계안에서는 분석을 에디터 또는 배치 도구에서 끝내고 런타임에는 완성된 Sprite 에셋을 포함합니다. 런타임 분석 모델을 제거한 경우 해당 모델의 메모리·네트워크 요구를 생략할 수 있으며 실제 전체 사용량은 빌드에서 측정합니다.

자주 묻는 질문 (FAQ)

AI가 프레임을 하나로 합쳐서 반환하면 어떻게 하나요?

객체를 개별 인스턴스로 반환하도록 요청하되 실제 객체의 사각형은 겹칠 수도 있음을 고려합니다. 프레임마다 분리된 타일이라는 규칙이 있는 시트에만 비겹침 조건을 적용합니다. 알파 연결 요소가 곧 프레임 하나인 것도 아니므로 분리된 무기·이펙트의 묶음 규칙을 정하거나 수동 분할 가이드를 추가합니다.

Pivot은 항상 캐릭터 발에 두어야 하나요?

아닙니다. 캐릭터는 발, UI 아이콘은 중앙, 투사체는 진행 방향의 후방처럼 게임플레이 기준에 따라 달라집니다. pivotMode를 에셋 종류별로 설정하는 것이 안전합니다.

생성형 이미지의 투명 여백 때문에 Sprite가 흔들리면 어떻게 하나요?

bbox만 사용하지 말고 알파 마스크의 유효 픽셀 영역을 함께 계산합니다. 이후 발 Anchor나 중앙 기준점을 Sprite rect 내부 좌표로 다시 정규화하면 프레임별 투명 여백의 영향을 줄일 수 있습니다.

정리

모델에서 영역·마스크·기준점 후보를 받고 에디터 도구에서 좌표 변환, 프레임 정렬, Pivot 검증을 수행하는 설계안입니다. 단계를 나누어 각 입력과 결과를 기록하고 오류 위치를 추적합니다.

분석 결과와 수동 수정값을 보존하고 실제 애니메이션에서 의도하지 않은 발 흔들림과 잘림을 검사합니다. 수동 작업과 비교해 시간·재검수량을 측정한 뒤 자동 적용 범위를 정합니다.