글 작성자: Doublsb

이번 프로젝트에서는 텍스트 사이에 아이콘을 넣어야 하는 경우가 있었다.

TextMesh Pro가 Sprite Importer를 제공하므로, 쉬울 것이라고 생각했다.

실제로, 통합되어 있는 Sprite를 Multiple로 자르고 SpriteAsset을 생성하기만 하면 제대로 작동했다.

 

스프라이트를 TextMeshPro의 Sprite Asset으로 변환

 

실제 적용된 화면

 

그러나, 내 프로젝트의 경우 번들이나 인터넷에서 다운받은 이미지를 아이콘으로 만드는 작업이 필요했다.

TextMeshPro의 Sprite Asset을 만들기 위해서는 에디터를 통해서만 생성, 업데이트 할 수 있었기 때문에 고민이 깊었다.

 

이를 해결하기 위해 찾아보던 중, 아래의 게시글에서 다운로드한 이미지로 Sprite Asset을 만드는 절차에 대한 공식 답변을 찾아냈다.

 

https://forum.unity.com/threads/how-could-i-create-tmp_spriteasset-programmatically-from-unity-sprite-asset.628720/

 

This has been done by some TMP users previously.

Since Sprite Assets contains sprite characters and sprite glyphs which ultimately defines the position of a sprite in some texture, you can fill / write these downloaded images into a texture at runtime. Assuming these downloaded images were of the same size, you could create the sprite asset ahead of time where the sprite characters / glyphs are already defined but simply point to an empty texture.

If the size of the downloaded images isn't known ahead of time then it is trickier as you would need to also modified the sprite data to include the correct metrics for layout and glyphrect to point to the right pixels in the texture.

답변에 따르면, TMPro의 Sprite Asset은 Multiple 스프라이트 글라이프의 위치/크기를 가지고 만들어지는 것이므로,

소스가 되는 스프라이트의 픽셀을 변경하면 Sprite Asset도 변경할 수 있다는 것이다.

 

이를 이용해, 아무것도 그려져 있지 않은 빈 스프라이트를 Multiple로 쪼개 놓고, 런타임에 다운받은 이미지를 잘라놓은 위치에 맞게 리사이징하여 빈 스프라이트에 그리면, 아이콘을 변경할 수 있다.

 

위의 절차를 자세히 서술해보겠다.


1. 빈 이미지 만들기

아무것도 그려져있지 않은 투명 이미지를 만들면 된다. 이 때, 나눠지는 영역이 균등한 정사각형이 되도록 사이즈를 설정한다.

이 때, 아이콘의 크기와 최대 아이콘 개수를 생각하여 만들면 된다.

 

나는 128 x 128(px)의 아이콘을 16개 만들 것이기 때문에, 512 x 512(px)의 이미지를 만들었다.

 


2. 빈 이미지를 multiple 스프라이트로 만들기

다음의 네가지 옵션을 수정하면 된다.

 

- Sprite Mode : Multiple

스프라이트를 Multiple로 만들어야 Sprite Asset이 아이콘용 리소스로 인식한다.

 

- Alpha Source : None

투명한 이미지의 판단 기준을 설정할 수 있는 옵션이다.

 

임시로, 스프라이트 에디터에서 Slice를 수행하기 위해 설정한다.

투명한 상태 그대로 Slice 버튼을 눌렀을 경우, 유니티 에디터에서 자를 영역을 판단하지 못하기 때문에 간단하게 이미지를 자를 수 없게 된다.

 

- Read/Write Enabled : Checked

해당 이미지의 픽셀을 코드를 통해 수정할 수 있게 만든다.

이걸 체크하지 않으면 빈 이미지에 다운로드했던 이미지를 덮어씌울 수 없으므로 주의해야 한다.

 

- Format : RGBA 32 bit

이미지의 픽셀에 접근하는 Texture2D.SetPixel, Texture2D.GetPixel 메서드를 사용하기 위해, 지원하는 텍스쳐 포맷을 사용할 필요가 있다.

지원하는 텍스쳐는 RGBA32, R8, Alpha8 등인데, 화질이 떨어지는 R8이나 Alpha8을 굳이 사용하고 싶지는 않을 것이다. 

꼭 바꿔주도록 하자. 이 때, 가져오는 텍스쳐의 포맷 변경도 잊지 말자.

 

 

네가지 옵션을 수정한 뒤, Sprite Editor를 열어 Slice 작업을 수행했다. 이렇게 16개의 영역을 나눌 수 있었다.

 

그 후, 반드시 Alpha Source 옵션을 Input Texture Alpha로 바꾸어야만 다시 투명 이미지가 된다. 잊지 말고 변경하자.


3. Sprite Asset 생성

이후 해당 스프라이트에 우클릭 > Create > TextMeshPro > Sprite Asset 메뉴를 선택하면, 16개의 아이콘이 생성된 것을 확인할 수 있다. 비록 지금은 모든 게 투명일지라도 말이다.


4. 외부 이미지를 스프라이트에 그리기

다운로드를 받았거나 독립된 이미지로 존재하는 텍스쳐 파일을 리사이징 후, 빈 이미지 위에 올리는 과정이다.

텍스쳐를 리사이징하는 방법을 모른다면, 링크를 통해 확인하자.

public void Initialize_SpriteAsset(int Num)
    {
        //텍스쳐 가져오기 및 리사이징은 이미 수행했다고 가정
        Textures = Get_Textures(Num);
        Resize();

        //한 칸의 픽셀 사이즈 입력
        int size = 128;

        //행, 열의 나눠진 칸수 입력
        int rawCount = 4;
        int columnCount = 4;

        //각 구역에 SetPixel 수행
        for (int idx = 0; idx < Textures.Length; idx++)
        {
            for (int x = 0; x < size; x++)
            {
                for (int y = 0; y < size; y++)
                {
                    int column = idx % columnCount;
                    int raw = idx / rawCount;

                    int posX = x + (size * column);
                    int posY = ((rawCount - raw - 1) * size) + y;

                    TransparentSprite.SetPixel(posX, posY, Textures[idx].GetPixel(x, y));
                }
            }
        }

        //빈 스프라이트에 업데이트
        TransparentSprite.Apply();
    }

위의 코드와 같이, Texture2D.SetPixel을 이용하여 받아온 이미지의 픽셀을 지정한 위치에 그리기만 하면 된다.


5. TMpro Text 컴포넌트에 Sprite Asset 연결하기

이제 TMPro Text에 스프라이트를 불러오는 구문을 입력하고, Extra Settings의 Sprite Asset을 설정하기만 하면 된다.

예시로, <sprite=5>를 입력한다면 만들어진 Sprite Asset의 6번째 이미지가 텍스트 내에 표시될 것이다.

 


6. 결과

 

반응형