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
를 활용해야 한다.
InternalSpriteUtility.GenerateAutomaticSpriteRectangles
는 minRectSize라는 파라미터를 가진다. 가령 128 x 128 사이즈의 텍스쳐를 아무렇게나 자르면 먹히지 않을 때가 있다. 그럴 때는 , minRectSize를 그냥 텍스처 한 변의 길이를 넣어주면 된다.
애니메이션 스프라이트의 경우 자동 자르기 방식을 적용하면 편리하게 이용할 수 있는데, 최소 사이즈를 2의 배수로 넣어서 체크하면 좋다.
에디터에선 상관없는데 빌드만 하면 InternalSpriteUtility 참조에러가 뜹니다. 찾아보니 InternalSpriteUtility는 내부용으로 빌드에는 사용할 수 없고 다른 방법을 사용해야 한다는데 해결 방법을 알고 계신가요?