Unity Slice Sprite Scripting

Changhoony·2023년 1월 31일
0

Unity

목록 보기
3/4

들어가며...

  • 코드 내용 - GitHub

  • 2D텍스처를 많이 작업해야 하고, border 값을 일괄 처리하고 싶을 때 스크립트로 하는 방식을 알아두면 좋다.

  • 기존의 방식대로라면, textureImporter.spritesheet = SpriteMetaData 배열을 집어 넣으면 잘라졌지만, 2022 버전에서는 작동하지 않았다.

    오류도 발생하고, 튕기고 텍스처가 엉망이 되는 현상이 있었다.

내용

private void Slice(Texture2D obj)
{
				// 데이터 초기화
              var factory = new SpriteDataProviderFactories();
              factory.Init();
              var dataProvider = factory.GetSpriteEditorDataProviderFromObject(obj);
              dataProvider.InitSpriteEditorDataProvider();
              var textureImporter = (dataProvider.targetObject as TextureImporter);

				//텍스쳐 세팅
              textureImporter.textureType = TextureImporterType.Sprite;
              textureImporter.spritePixelsPerUnit = 100;
              textureImporter.spriteImportMode = SpriteImportMode.Single;
              textureImporter.SaveAndReimport();
              
              var textureProvider = dataProvider.GetDataProvider<ITextureDataProvider>();
              if (textureProvider != null)
              {
              	// 텍스처 데이터 가져와 자르기
                  int width = 0, height = 0;
                  textureProvider.GetTextureActualWidthAndHeight(out width, out height);
                  // 그리드 방식( 직접 지정 )
                  //var rects = InternalSpriteUtility.GenerateGridSpriteRectangles(obj as Texture2D, Vector2.zero, new Vector2(64,64), Vector2.zero, true); 
                  
                  // 자동 방식
                  var rects = InternalSpriteUtility.GenerateAutomaticSpriteRectangles(obj as Texture2D, width,0);
                  
                  // 자른 데이터를 SpriteRect에 할당 해 줘야 한다.
                  List<SpriteRect> rectangles = new List<SpriteRect>();
                  for (int i = 0; i < rects.Length; i++)
                  {
                      SpriteRect rectangle = new SpriteRect();

                      rectangle.rect = rects[i];
                      rectangle.alignment = SpriteAlignment.Center;
                      
                      // left , bottom, right, top 순서대로 자른다.
                      rectangle.border = new Vector4(width / 3, height / 3, width / 3,height / 3);
                      rectangle.name = $"{obj.name}_{i}";
                      rectangle.pivot = new Vector2(0.5f, 0.5f);
                      // 필수
                      rectangle.spriteID = GUID.Generate();
                      rectangles.Add(rectangle);
                  }
                  // 제어한 데이터 내용을 적용한다.
                  dataProvider.SetSpriteRects(rectangles.ToArray());
                  dataProvider.Apply();
              }

              textureImporter.SaveAndReimport();
}

기존의 방식을 버리고 새로운 방식을 도입한 유니티의 설명에 따라

TextureImporter, SpriteDataProviderFactories ,ITextureDataProvider 그리고 InternalSpriteUtility 를 활용해야 한다.

  • 뭐가 조금 많아 졌지만, 다른 클래스 중에는 본을 스크립트로 제어하는 부분도 있으니 추후에 게시해 할 예정이다.

주의

  1. InternalSpriteUtility.GenerateAutomaticSpriteRectangles 는 minRectSize라는 파라미터를 가진다. 가령 128 x 128 사이즈의 텍스쳐를 아무렇게나 자르면 먹히지 않을 때가 있다. 그럴 때는 , minRectSize를 그냥 텍스처 한 변의 길이를 넣어주면 된다.

  2. 애니메이션 스프라이트의 경우 자동 자르기 방식을 적용하면 편리하게 이용할 수 있는데, 최소 사이즈를 2의 배수로 넣어서 체크하면 좋다.

profile
Unity 개발

2개의 댓글

comment-user-thumbnail
2023년 4월 14일

에디터에선 상관없는데 빌드만 하면 InternalSpriteUtility 참조에러가 뜹니다. 찾아보니 InternalSpriteUtility는 내부용으로 빌드에는 사용할 수 없고 다른 방법을 사용해야 한다는데 해결 방법을 알고 계신가요?

1개의 답글