유니티 게임의 한글화와 패치 제작 – Unity Asset Bundle Extractor(UABE) 사용법

Unity Asset Bundle Extractor(UABE)는 유니티 게임의 assets을 분석하고, 추출하고, 수정된 에셋을 불러올 수 있는 강력한 도구이다. 최초로 게임 내의 에셋을 분석할 때는 UABE를 사용하고 분석이 완료된 후 자동화된 툴을 제작할 때는 UABE API를 사용하여 에셋을 수정하게된다.

유니티 게임 우리말화 도구 베타 버전을 공개하였습니다. 이에 관한 설명은 GitHub의 wiki에서 서술합니다. https://github.com/dmc31a42/UnityL10nTool/wiki

유니티 게임의 한글화와 패치 제작 – 서론 으로 돌아가기

본 강좌는 70~80% 완성되면 바로 공개되며, 잘못된 부분이 있으면 그때 그때 수정하는 것으로 하겠습니다. 아래의 강좌 내용은 언제든지 수정될 수 있습니다. 질문은 댓글로 달아주시거나 GitHub(https://github.com/dmc31a42/UnityGameL10nTools/)의 issue를 활용하여주시면 감사하겠습니다.

설치 및 실행

UABE는 ‘7 Days to Die’ 커뮤니티의 ‘DerPopo’가 제작하였고 https://7daystodie.com/forums/showthread.php?22675-Unity-Assets-Bundle-Extractor 에서 배포된다.
본 글에는 안내, 패치노트, 라이센스, UABE API 다운로드, UABE 다운로드순으로 구성되어있다.  글(스레드)안의 첫번째 post 최하단에 ‘Releases’ 단락에 UABE를 받을 수 있는 링크가 버전별로 나타나있다. 그 중 32bit 최신 버전을 다운받는다. 32bit, 64bit 버전간 차이는 크지 않다. assets의 크기 또는 에셋의 갯수가 매우 클 경우에는 64bit 버전을 사용해야겠지만 그럴 경우는 거의 없다. 버전안에서 두 링크는 다운받는 곳(MEGA.nz, Dropbox)의 차이이다. 편한 곳으로 받으면 된다. 본 강좌에서는 2.2beta2가 최신버전이며, 이 버전을 기준으로 설명한다.

At bottom of first post in thread, in 'Releases' section, UABE download link is.

다운 받은 압축 파일을 압축해제하면 설치는 끝이다. AssetBundleExtractor.exe 파일로 실행한다.

Unzip ressult of UABE 2.2beta2

AssetBundle 열기(압축해제하기)

인터넷을 통해 스트리밍으로 받아기 용이하도록 압축된 Assets인 AssetBundle은 별도의 압축 해제 절차를 통해 압축을 해제한 후 Assets를 편집할 수 있다.

UABE를 실행한 후 상단 메뉴에 있는 ‘File’->’Open’을 클릭한다.

Click 'File' and 'Open' In menu of UABE

열고자하는 AssetBundle을 선택하고 열기(‘Open’)을 클릭한다.

Select AssetBundle what you want to open in FileOpenDialog.

번들이 압축이 되어있기에 압축을 풀것인지 물어본다. ‘예(Y)’를 클릭한다.

UABE ask that you wish to unpack this bundle because it is compressed.

어느 위치에 압축 해제된 AssetBundle을 저장할 것인지 물어본다. 본래 열고자 했던 압축된 AssetBundle과 다른 이름으로 지정하고 ‘저장(S)’를 클릭한다.

UABE ask where you save unpacked bundle by FileSaveDialog, I set file name as 'unpack' unlike compressed AssetBundle('__data').

‘No file opened.’가 방금 열었던 압축된 AssetBundle의 파일 이름(예제에서는 ‘__data’)으로 바뀌었고 ComboBox 컨트롤(윈도우 GUI에서는 버튼, 체크박스, 라벨, 텍스트박스 들을 컨트롤이라 부른다)에 항목들이 들어있고, ComboBox, 체크박스, 버튼이 클릭할 수 있게 바뀌었다.  (UABE가 연 파일이 압축된 AssetBundle인 것 처럼 보이지만, 실제로는 압축해제한 AssetBundle을 열고 있음을 주의한다. 실제로 압축 해제한 AssetBundle을 삭제하려하면 UABE가 열고 있어서 지울 수 없다고 뜬다.)

After open uncompressed AssetBundle, 'No file opened.' is changed to '_data'(compressed AssetBundle name); Combobox control has item('CAB-570e7~'); and Combobox, CheckBox('Remove the TypeTree ~'), Buttons('Export', 'Import', 'Info') can be able to click

AssetBundle에 있는 Assets 열기

에셋 목록을 보거나, import, export할 때는 위에서 압축해제된 AssetBundle을 연 후 ‘Info’ 버튼을 클릭해서 ‘Assets Info’ 창을 띄운다. ‘Assets Info’ 창에서 할 수 있는 나머지 작업은 하단의 Asset 분석하기, export, import, plugins를 참고하면 된다.

AssetBundle에 있는 Assets을 저장하기

아래에 소개할 Asset import 를 통해 수정된 Assets을 AssetBundle로 저장하는 방법이다. 수정된 assets는 목록에 있는 에셋 중에 Modified 열이 ‘*’ 표시되어 있는 것으로 확인할 수 있다.

'Localization_en' asset is modified, 'Modified' column of this show '*'

assets을 수정하고 ‘X’ 버튼 또는 ‘OK’ 버튼으로 창을 닫으려 하면 변경사항을 저장할 것인가 물어본다. ‘예(Y)’를 선택한다.

After modifying assets, UABE ask save the changes

‘예(Y)’를 클릭해도 지금 당장은 변화가 없고, 처음의 UABE 창으로 돌아갈 것이다. 상단 메뉴의 ‘File->Save’를 클릭한다.

Click 'File-Save' in menu bar of first UABE window

수정된 AssetBundle을 저장할 이름을 지정한다. 여기서 주의할 것은 우리가 수정하고 있는 AssetBundle은 압축이 해제된 AssetBundle이고(예제에서는 __data를 압축해제하여 unpacked으로 저장하였다) 열고있는 AssetBundle은 덮어씌우기가 되지 않기 때문에 압축해제한 AssetBundle과 다른 이름으로 지정해야한다.)

Set save file name of modified AssetBundle in FileSaveDialog, example I set name as unpacked_mod

그리고 마지막으로 수정된 AssetBundle을 압축하여 게임에서 불러올 수 있게 한다. 처음의 UABE 창에서 상단 메뉴에 있는 ‘File-Compress’를 클릭한다.

Click File-Compress in menu bar of first UABE window

압축할 압축 해제된 AssetBundle을 선택한다.

Select uncompressed AssetBundle what you want to compress in FileOpenDialog. In this example, I select unpacked_mod

그리고 압축한 AssetBundle을 저장할 이름을 지정한다.

Set AssetBundle name what you want to compress and save as. I set '__data' as same as original compressed AssetBundle name, because I want to overwrite it

AssetBundle안에 있는 assets, resS 파일 추출하기

assets을 추출하여 수정한다던지, resS를 추출하여 각 에셋의 원본 파일(음악, 동영상 등)을 얻어내고 싶을 때 assets, resS를 추출하여야한다.

ComboBox 컨트롤에서 추출하고 싶은 항목을 선택한다. *.assets의 경우 확장자가 붙어있지 않고, *.assets.resS의 경우 확장자가 .resource로 붙어있다. 그리고 ‘Export’ 버튼을 클릭한다.

select assets(no extension) or resource(.resS) which you want in ComboBox control. I select 'resS'

그리고 저장하고싶은 이름을 정한다. UABE는 파일을 확장자로 구분하는 것이 아니라 헤더를 가지고 판단하기 때문에 이름은 아무렇게 지어줘도 상관은 없다. 본인이 편한 방식대로 짓자.

Set saved name what you want to export(extract). I set saved name as cab.assets.resS

AssetBundle으로 수정한 assets, resS 파일 가져오기

외부에서 수정한 assets, resS 파일을 AssetBundle로 가져와보자. 가져와서 저장할 항목을 ComboBox에서 선택한 다음(.assets 파일을 가져와서 반영할 것이냐, .resS 파일을 가져와서 반영할 것이냐), ‘Import’를 클릭한다.

Select kind whether assets or resS what you want to import. I select resource

수정한 항목을 파일 열기 창에서 선택한다. 만약 파일이 안보인다면 ‘Assets file (*.assets)’로 지정되어있는 유형을 ‘All types (*.*)’으로 바꾸면 보일것이다.

Select what you want to import. I select 'cab.assets.resS'. if you cannot see files, change 'Assets file (*.assets)' to 'All types (*.*)'. I set like that

가져오고 난 후 압축된 AssetBundle 파일로 저장하려면 위의 단락에서 방법을 찾아서 따라하면 된다.

Assets 열기

첫 UABE 창의 상단 메뉴에서 ‘File-Open’을 클릭한다.

Click File-Open in menu bar of UABE first window

열고자하는 assets 파일을 선택한 후 ‘열기(O)’를 클릭한다.

Select assets what you want to open, then click 'Open(O)'. I select 'resources.assets'

그러면 아래의 ‘Assets Info’ 창이 뜬다.

Assets 살펴보기

Assets Info

Assets Info window. Above, Menu bar is. There are 'File', 'View', 'Tools'. Left, TreeView including many asset. Columns are 'Name', 'Container', 'Type', 'File ID', 'Path ID', 'Size (bytes)', 'Modified'. Right above, Asset Info is. 'Name', 'Path ID', 'File ID', and 'Type' show in label. Right bottom, Action buttons is. 'View Data', 'Export Raw', 'Export Dump', 'Plugins', 'Import Raw', 'Import Dump', and 'Remove'.

TreeView에는 불러온 assets에 있는 asset들의 목록이 들어있다. Assets Info 에서 assets을 불러올 때는 불러온 assets 뿐만 아니라 종속성이 설정된 assets들을 전부 불러와 File ID->Path ID 순으로 정렬한다. TreeView 에서 선택한 에셋이 무엇인지 Asset Info에 나타난다. Asset Info에는 복사할 수 있는 label controll에 ‘Name’, ‘Path ID’, ‘File ID’, and ‘Type’ 가 표시된다.

TreeView에서 선택한 에셋을 자세히 보거나(‘View Data’), 내보내거나 불러오거나(‘Export Raw’, ‘Export Dump’, ‘Import Raw’, ‘Import Dump’), 플러그인을 사용하여 해당 에셋을 조작할 때(‘Plugins’) Action 버튼들을 사용한다.

View Data

In 'Asset Data' window, asset information is shown as tree view

‘Assets Info’ 창에서 보고자하는 에셋을 선택(클릭)한 후  ‘View Data’ 버튼 컨트롤을 클릭하면 ‘Asset Data’ 창이 나타나면서 선택한 에셋의 정보를 보여준다.

에셋은 트리구조로 구성되어있으며 각 항목은 Field라 부른다. 필드는 C# 클래스에 있는 멤버 변수 중 Serialize 가능한 변수를 나열한 것이다. 필드는 Type과 Field 이름, 값으로 구성되어있으며 각 필드는 자식(child)를 1개 이상 가지고 있을 수 있다. 여기서 Type은 클래스의 형(type)과 같고, Field 이름은 멤버의 이름과 같다. child가 있는 Field는 값이 없을 수 있다.

필드가 가질 수 있는 Type은 아래와 같이 크게 3가지로 구분할 수 있고, Asset Data에 다음과 같이 표시된다.

  • Type이 System 변수인 경우
    : UInt, Int, float(single), double, string 등
    필드에 type과 Field이름, 값이 함께 표시되어있으며, 자식 Field는 존재하지 않는다.
  • Base Type이 UnityEngine.Object 인 경우
    : Type 이 System의 변수가 아닌 객체 중 단독으로 Asset으로 존재하는 경우
    Type은 PPtr<${{Asset의 Type}}>으로 표시되고 Field 이름이 존재하고, 자식 Field에 해당 Asset의 Assets 파일 위치(type: int, Field 이름: m_FieldID)와 그 Assets 파일에서의 Asset위치(type: SInt64, Field 이름: m_PathID)이 존재한다. Asset Data에서는 가리키는 Asset을 ‘[view asset]’으로 바로 확인할 수 있다.
  • Base Type이 System.Object 인 경우
    : 위의 두 조건을 만족하지 않는 나머지 type
    필드는 type과 이름으로 구성되어있고, 자식 필드는 해당 필드의 멤버 변수로 구성되어있다.

그리고 마지막으로, MonoBehaviour를 보려할 때 이상한 창이 뜬다면 아래의 ‘Get script information’ 섹션을 확인하면 된다.

Export Raw

assets 파일에 저장된 asset을 저장되어있는 그대로 추출할때 ‘Export Raw’를 사용한다.

추출하고자 하는 asset을 선택한 후 ‘Export Raw’를 클릭한다.

In 'Assets Info' window, select asset to export.

저장하고자 하는 이름을 정하고 ‘저장(S)’을 클릭한다. 기본적으로는 ‘{{Asset 이름}}-{{Assets 파일명.확장자}}-{{Asset Path ID}}.dat’으로 저장된다. 에셋의 이름이 없거나 MonoBehaviour의 경우 {{Asset 이름}}이 ‘unnamed asset’으로 지정된다.

Set name of exported raw asset in FileSaveDialog. Basically, {{asset name}}-{{assets name.extension}}-{{asset Path ID}.dat

resources.assets 파일에 있는 해당 에셋과 추출한 파일을 Hex 에디터로 비교해보면 동일한 것을 확인할 수 있다.(블록 선택된 부분)

Compare 'LiberationSans SDF' asset in resources asset and exported asset using 'HxD' hex editor. each block selected area are same

Import Raw

외부에서 수정한 에셋 raw 파일을 지정한 에셋에 덮어쓰기 위한 기능이다. 해보기에 앞서서 위에서 추출한 에셋의 에셋 이름을 미리 수정해보자.

Import Asset - Modify Asset using hex editor(red part is modified)

위에서 추출한 ‘LiberationSans SDF’ MonoBehaviour의 raw 파일에서 ‘LiberationSans SDF'(18자) 문자열을 (18자)로 글자수가 같게 수정한 후 저장하였다. (위 사진의 빨간색 글자 부분)

‘Assets Info’에서 덮어쓰고자 하는 Asset을 선택한 후 ‘Import Raw’를 클릭한다.

Select asset what you overwrite and click 'Import Raw' for importing asset into selected Path ID

위에서 방금 수정한 에셋 raw 파일을 선택한 후 ‘열기(O)’를 클릭한다.

Select modified raw asset file and click 'Open(O)'

‘Assets Info’ 창에서, 덮어쓸 에셋의 ‘Modified’ 열이 ‘*’ 표시가 되어있는가 확인한다.

Modified Asset is marked as star('*') at 'Modified' column

Detail List와 Asset Info에는 수정된 사항이 반영 안되지만(처음 assets을 불러올 때 전부 읽어오기때문) ‘View Data’로 해당 에셋을 살펴보면 위에서 수정한 이름이 반영되어있다. 이를 아래에서 해볼 assets 저장하기로 저장하면 된다.

Edited Name is applied from 'LiberationSans SDF' to 'XXXXXXXXXXXXXXXXXX'

Export Dump

raw와 dump의 차이는 raw는 컴퓨터가 이해할 수 있는 Serialized된 데이터가 나열되어있을 뿐이지만, dump는 ‘Asset Data’ 윈도우에서 볼 수 있는것 처럼 사람이 이해할 수 있도록 문자로 데이터를 보여준다. 이해하기도 편하고 수정하기도 편하다. 그럼 dumped asset을 추출해본다. (위에서 수정한 사항은 원래대로 되돌렸다)

‘Export raw’와 비슷한 방식으로 추출하고자 하는 에셋을 선택하고, 저장할 이름을 지정한 다음(dumped asset은 기본 확장자가 txt이다.) 추출된 dumped asset을 열어보면 아래의 그림과 같다. ‘Asset Data’ 창에서 볼 수 있는 구조와 유사하게 출력된다.

Export Dump - Dumped Asset

Import Dump

위의 ‘Import Raw’에서는 무언가를 수정하려면 각 type이 가지는 크기를 계산하면서 어느 위치(offset)에 수정하고자하는 값이 몇 바이트를 가지는지, float, double type의 경우 값을 byte로 어떻게 바꾸어야하는지 고려해야할 사항이 많다. 이에 반해 Import Dump는 구조, 필드의 값만 바꾸어주면 나머지 작업은 알아서 해준다. 여기서는 에셋의 이름을 길이를 바꾸어서, 그리고 Int, float 등의 다른 type 필드도 수정해보고, 이를 불러와본다.

위에서 추출한 에셋중 ‘m_Name’과 ‘material’의 ‘m_PathID’, ‘m_fontInfo’의 ‘PointSize’ 필드를 아래와 같이 수정하였다.

Modified Dumped Asset

수정된 에셋을 Import raw할 때와 마찬가지로 ‘Import Dump’ 버튼을 클릭하여 불러온다. ‘Modified’ 열이 ‘*’ 표시가 되었는지 확인하고, 덮어쓴 에셋을 ‘View Data’를 통해 확인해보면 다음과 같다.

Import Dump - After import dump, selected items are modified than previous in 'Asset Data' window

Plugins

플러그인은 raw, dump를 내보내거나 불러와 덮어쓰는 기능외에 아래의 몇몇 Asset Type에 대하여 편리하게 편집할 수 있는 추가 기능이다. 각 타입에 대해 간단하게 설명하고 넘어간다.

TextAsset

‘Export to .txt’, ‘Import from .txt’는 ‘TextAsset’의 실제 내용인 ‘m_Script’ 부분만 추출하거나 덮어쓰는 기능을 제공해준다. 추출, 불러와 덮어쓰기하는 방법은 위의 ‘Export Raw(Dump)’나 ‘Import Raw(Dump)’와 동일하다. 다만, 추출, 덮어쓰는 대상이 ‘TextAsset’의 내용물로 바뀌었을 뿐이다.

Texture

‘Texture’는 일반적으로 이미지 파일을 담고있다. 이 또한 위의 ‘TextAsset’ 처럼 ‘Texture’ 에 담겨있는 이미지 파일을 추출하여 png나 tga로 저장하거나, 외부의 이미지를 가져와 Texture로 변환하여 덮어쓸 수 있다.

Remove

간단히 해당 asset을 assets에서 삭제하는 기능이다.

에셋 저장

위에서 ‘Import Raw’, ‘Import Dump’, ‘Plugins’ 등을 통해 에셋이 수정되었을 경우 에셋의 ‘Modified’ 열에 ‘*’ 표시가 된다. 이 상태에서 ‘OK’ 버튼을 클릭하면 변경사항을 저장할 것인가 묻는다.

Assets save - If click 'OK' button in 'Assets info' window after modify asset, UABE ask to save the change

예를 클릭하면 어느 경로에 수정된 assets 파일을 저장할 것인가 물어본다. 또는, 상단 메뉴에서 ‘File’-‘Save’를 클릭하는 것으로도 에셋을 어느 경로에 저장할 것인가 물어보는 창을 띄울 수 있다. UABE에서 열고 있는 assets은 열려있는 상태라서 덮어쓰기가 안된다. 원본 파일의 이름과 다른 이름으로 저장하자.
Set assets name which you want to save. should set name as different as original assets file. I set saved assets name as 'resources.assets.mod' different as original 'resources.assets'

Search by name

에셋 이름으로 대상 에셋을 검색할 수 있다.

상단 메뉴에서 ‘View’ -> ‘Search by name’을 클릭한다.

Click View -> Search by name at above menu bar

‘Query ( * allowed)’ 옆의 ‘TextBox’에 검색하고자하는 에셋의 이름을 입력한다.

쿼리에는 에셋의 이름과 정확하게 일치하는 것만 찾아준다. 만약 ‘ASDF’로 시작하는 에셋을 찾고자 한다면 ‘ASDF*’로, ‘ASDF’로 끝나는 에셋은 ‘*ASDF’로, ‘ASDF’를 포함하는 에셋은 ‘*ASDF’로 검색해야한다.

(UABE 기준으로) GameObject 에셋은 에셋 이름 앞에 ‘GameObject ‘가 붙으며 MonoBehaviour 에셋은 ‘MonoBehaviour ‘ 가 붙는다. 따라서 ‘ASDF’를 포함하는 MonoBehaviour를 찾으려면 ‘MonoBehaviour *ASDF*’ 로 검색해야한다. 물론 ‘*ASDF*’로 검색할 수도 있다.

‘Case sensitive’ 체크박스는 대소문자를 엄격히 구분하여 대소문자까지 일치하는 경우만 검색할 때 쓴다. 체크되어있지 않으면 대소문자에 관계없이 일치하는 에셋을 찾는다.

‘Start at selection’은 에셋을 검색할때 ‘Detail List’의 순서를 기준으로 위 아래 중 어디에서 부터 검색할 것인가를 정하는 옵션이다.

Input 'MonoBehaviour LiberationSans SDF' into 'TextBox' next to 'Query (* allowed)'

검색기능을 통해 찾을때는 무조건 위(또는 아래)에서 시작하므로 계속 검색을 하려면 ‘View->Continue search (F3)’ 를 클릭하거나 또는 ‘F3’ 키를 눌러서 계속 검색을 진행할 수 있다.

Go to Asset

검색하고자하는 에셋이 정확히 어느 파일(File ID 또는 assets 파일명)에 어느 위치(Path ID)에 있는지 안다면 위치를 입력해서 해당 에셋을 바로 찾을 수 있다.

‘View’->’Go to Asset’을 클릭하여 File ID에 해당하는 assets 파일명을 입력하고, Path ID에 해당하는 에셋 위치를 숫자로 입력한 뒤 ‘OK’버튼을 클릭하면 원하는 에셋으로 포커스가 바뀐다.

Go to asset - Click 'View'-'Go to asset'

Go to asset - Select assets file name next to File ID and input Path ID

Dependencies

Assets에 있는 에셋이 다른 Assets에 있는 에셋을 참조하려할 때 본래 Assets에 있는 에셋의 Dependencies 순서에 따라 자신의 Assets을 0번으로 하는 m_FileID가 매겨진다. UABE는 제일 처음 불러온 Assets에 기재되어있는 의존성 순서에따라 다른 Assets을 불러오고 불러온 Assets에도 의존성이 있으면 다시 다른 Assets을 불러온다.

.\-(0) resources.assets ⋯⋯⋯⋯ (0)
.  +-(1)/(0) globalgamemanagers.assets ⋯⋯⋯⋯ (1)
.  |   (1) resources/unity_builtin_extra ⋯⋯⋯⋯ (2)
.  |   (2) library/unity default resources ⋯⋯⋯⋯ (3)
.  | (2) library/unity default resources
.  \-(3)/(0) sharedassets0.assets ⋯⋯⋯⋯ (4)
.      (1) globalgamemanagers.assets
.      (2) library/unity default resources

‘Slime Rancher’의 resources.assets 파일을 기준으로 의존성을 설명하겠다. resources.assets 파일에는 ‘globalgamemanagers.assets’, ‘library/unity default resources’, ‘sharedassets0.assets’이 필요하다 한다. ‘resources.assets’을 예로 들 때  m_FileID를 0으로하여 의존성에 나와있는 순서대로 1씩 커져서 m_FileID가 1인 assets은 ‘globalgamemanagers.assets’가 되고, m_FileID이 2인 assets은 ‘library/unity default resources’, 3은 ‘sharedassets0.assets’이 된다. 만약 resources.assets 파일에 있는 어떤 에셋이 ‘library/unity default resources’ 파일에 있는 어떤 에셋을 PPtr로 참조한다 할때 m_FileID가 2가 된다.

위에 표시한 의존성 구조에서 assets 이름 앞의 ({{숫자}})는 해당 assets 안에서 m_FileID를 말하고 / 가 붙어있는것은 참조하고 있는 에셋이 자신의 의존성을 다시 가지고 있다면 자신의 파일 안에서의 의존성 순서(m_FileID)를 나타낸다. UABE는 의존된 모든 assets을 위의 구조도에서 위에서부터 읽어오게되고 거기에 순서대로 File ID에 숫자를 붙인다. ‘View Data’를 통해 에셋을 볼 때 PPtr로 참조하고 있는 에셋이 UABE가 불러온 Detail List상에서 어느 assets을 가리키는지 m_FileID의 값 뒤에 괄호로 별도로 표시할 때 쓰인다.

‘Assets info’ 창에서 상단 메뉴의 ‘View’->’Dependencies’를 클릭하면 의존성을 볼 수 있다.

Dependencies - Click 'View'-'Dependencies'

‘Dependencies’ 창에서 위의 ComboBox 컨트롤에 나타나있는 assets 순서는 UABE에서 불러온 assets들의 순서이고, 아래의 ListBox에는 ComboBox 컨트롤에서 선택한 에셋의 의존성이 나와있다. 다만 조금 이상한 점이 자기 자신의 File ID가 0이 되어야하고 의존하고 있는 assets은 1부터 시작해야하는데 0부터 시작하는 것으로 나와있다는 것. 아래의 순서에서 +1을 더해서 보면된다.

Dependencies - Dependencies windows

아래는 ‘resources.assets’을 열어서 의존성으로 인해 불러와진 assets 들 중 다섯번째로 불러와진 ‘sharedassets0.assets’ 파일에 있는 어떤 에셋을 ‘View Data’를 통해 본 모습이다. ‘PPtr<MonoScript> m_Script’는 ‘globalgamemanagers.assets’에 있는 MonoScript 에셋을 가리킨다. ‘sharedasset0.assets’ 파일의 의존성에는 ‘globalgamemanagers.assets’는 자신을 포함하여 두번째에  있고 ‘resources.assets’가 필요한 모든 assets 파일을 불러왔을 때 ‘globalgamemanagers.assets’는 두번째에 있다. 따라서 m_FileID가 1이고 UABE에서 에셋파일을 불러온 순서상에서 assets 파일 위치인 괄호안의 숫자도 1이된다.
‘PPtr<$Material> material’은 ‘sharedassets0.assets’ 파일 자신에 있는 에셋을  참조하고 있다. 자기자신은 m_FileID가 0이고, UABE상에서 ‘sharedassets0.assets’는 5번째로 불러와졌기 때문에 괄호안에는 4로 표시된다.

중요한건 m_FileID은 assets 자신을 0으로 하고, 의존성 순서를 기준으로하는 상대 위치라는 것만 알아주면 된다.

View asset in sharedassets0.assets(third assets in dependencies). PPtr MonoScript point a asset in globalgamemanager.assets, so m_FileID is 1, and 1 in bracket. PPtr Material point a asset in itself assets. so m_FileID is 0, and 4 in bracket

Container

Get script information

UABE 2.2 버전부터 MonoBehaviour의 데이터 구조를 볼 수 있는 기능이 추가되었다. Assembly에서 정보를 추출하여 Serialization 된 바이너리에서 정보를 볼 수 있게 되었다. assets을 열고, 처음으로 MonoBehaviour를 ‘View Data’로 보거나, ‘Export Dump’, ‘Import Dump’할 때 Assembly에서 정보를 읽어올 것인가 물어본다.

Windows name is depended as action what you do like 'View Data'('Asset View'), 'Export Dump', or 'Import Dump'. Ask to read additional MonoBehaviour type information.

MonoBehaviour 추가 정보를 얻으려고 할 때 해당 기능을 사용한다. 만약 해당 창에서 아니오를 눌렀을 때 이 창을 다시 보고 싶다면 ‘Assets info’ 창의 상단 메뉴에 ‘Tools’-‘Get script information’을 클릭한다. 그러면 다음과 같이 ‘Open the Assembly file’ 창이 뜰 수도 있다. 유니티 엔진에서 기본적으로 포함되어야할 어셈블리, 각종 플러그인에서 Editor용으로 사용되는 어셈블리 중 없는 것을 찾을려고 한다. 게임이 정상적으로 작동한다면, 모든 Assembly가 있다는 소리이니 찾는 창을 모두 취소 또는 ‘X’로 끄면 된다.

단, 유니티 엔진 2018.2 버전 이후로 어셈블리 정보가 저장되는 방식이 바뀌어서 아래의 창이 뜨면 ‘Managed’ 폴더 내에 있는 모든 *.dll 파일을 선택한 후 ‘열기’를 클릭하면 된다. (이는 Unity Assets Bundle Extractor 2.2stable 버전부터 고쳐졌습니다.)

Get script information - Ask assemblys path not detected. Click Cancel

그러면 다음과 같이 추가적인 어셈블리 정보를 읽어오는 별도의 프로그램이 검은 창에 뜰 것이고 바로 사라질 것이다.

Reading MonoBehaviour class database from assemblies.

Edit Type Package

UABE에서 assets 파일을 열고 안에 있는 에셋의 내용물을 보기 위해 각 type이 어떻게 Serialization 되어있는지를 기록해둔 Database를 버전별로 모아둔 파일이 package 파일이다.

‘Unity Assets Bundle Extractor’ 창의 메뉴 바에서 ‘Options’->’Edit Type Package’을 클릭한다.

Edit Type Package - Click 'Options'-'Edit Type Package' at menu bar in 'Unity Assets Bundle Extractor'

파일 열기 다이얼로그창에서 ‘classdata.tpk’ 파일을 선택한다. 해당 파일은 ‘AssetsBundleExtractor.exe’ 파일이 있는 폴더에 있다.

Select classdata.tpk in 'AssetsBundleExtractor folder same as 'AssetsBundleExtractor.exe' folder in FileOpenDialog

여기서 자주 사용할 기능은 class database 파일을 export하는 것이다. 나중에 UABE API를 사용할 때 열어보고자 하는 게임의 버전의 class database를 선택하고 ‘Export’ 버튼을 클릭하면 어디에 저장할 지 물어보는 창이 뜬다. 단, 여기서 ‘Compress the file’ 체크 박스와 ‘Optimize’ 체크박스는 열어보고있는 package 파일을 저장할 때 옵션이고 ‘Export’할 때 옵션은 아니다.

Select database in listbox at left of window, and Click 'Export' in 'Edit type package' window. I select 'U5.6.0f3'

보통 나는 파일 이름을 정할 때 버전명을 주로 패키지파일에 있는 각 데이터베이스 파일의 이름을 사용한다. 프로그램에 버그가 있는지 확장자를 붙여주지 않으면 이름 끝에 ‘.dat’이 자동으로 붙지 않는다.

Set a name of class database file exported in FileSaveDialog. I set name same as original database name.

Edit Type Database

위에서 추출한 database 파일을 열어서 내용물을 확인해보거나 압축되어있는 데이터베이스 파일을 압축해제해서 저장할 수 있다. 위와 마찬가지로 ‘Unity Assets Bundle Extractor’ 창의 상단 메뉴에서 ‘Options’-‘Edit Type Database’를 클릭한다.

Edit Type Database - Click 'Options'-'Edit Type Database' at menu bar in 'Unity Assets Bundle Extractor'

파일 열기 다이얼로그에서 위에서 export한 데이터베이스 파일을 선택한다.

Select database file what just export. I select 'U5.6.0f3.dat' file.

‘Edit Type Database’ 창에는 ‘Type’의 목록과 선택된 Type의 이름, Type ID(Hex로 표기)을 보거나 수정할 수 있는 영역, 해당 Type을 편집할 수 있는 버튼. Type을 추가하거나 제거할 수 있는 버튼, 그리고 열어보고있는 데이터베이스 파일을 압축해서 저장할 지(LZMA/LZ4), 최적화(최적화가 무슨 기능인지는 모르겠다)하여 저장할 지 선택하는 체크박스가 있다.

일단, 여기서는 열고있는 데이터베이스파일가 압축되어있는 것을 해제하는 방법만 알려줄 것이고, 나중에 다른 기능이 필요하면 그 때 본 항목을 수정할 것이다.

‘Edit Type Database’ 창에서 ‘Compress the file (LZMA)’ 옆에 있는 체크박스를 체크 해제 하고 ‘OK’ 버튼을 누르면 된다. 데이터베이스 편집창은 assets을 열 때와 달리 현제 열고 있는 파일을 수정할 수 있기 때문에 편집하고있는 데이터베이스 파일을 별도의 파일로 저장할 필요가 없다.

Edit Type Database window. In left, listbox of type(class). In right up, Type name, Type ID(Hex), and Edit button are.  In right middle, add and remove type button are. In right bottom, 'Compress the file (LZMA)', '~ (LZ4)' and 'Optimize (fast)', '~ (slow)' checkboxs are.

본 데이터베이스 파일로 어떤 유니티 버전으로 빌드된 assets을 열 것인지 설정한다. 기본 설정대로 두고 ‘OK’ 버튼을 클릭한다.

There is listbox of unity versions bottom of 'Enter all targeted Unity versions ' in upper of 'Targeted versions' windows. In bottom, there are textbox to enter versions to add, Add and Remove button. Last, there is OK button

그러면 편집하고 있던 database 파일의 용량이 변하는 것을 확인할 수 있다.

광고

유니티 게임의 한글화와 패치 제작 – Unity Asset Bundle Extractor(UABE) 사용법”의 24개의 생각

  1. 강좌 감사합니다. 번역시도중에 여기저기 떠돌아 다녔는데 16진수 헤더 분석법이니 뭐니 머리가 헤롱헤롱하는 강좌들은 도통 이해가 안되더군요. 유니티 엔진이라는 특정성이 있긴 하지만 번역하려던 게임에 대한 추출이 현실적 되는거 같아서 고무적입니다.

    좋아요

  2. 안녕하세요
    안드로이드 어플리케이션 에서 사운드파일 추출하기를 원하는데 파일중
    assets.lst 가있는데 Unity Asset Bundle Extractor 으로 오픈이 안되요ㅜㅜ 도와주세요
    unable to read bundle file(Invaild file or unkown version?) 이라고만떠요

    좋아요

  3. export raw할때 path가 음수이면 저장할때 값이 다르게 저장되는데 이유 혹시 아시는 분 있나요
    이거 머리아프네요

    좋아요

    1. AssetBundle에서는 보통 path가 음수인 경우가 있는데 이때도 수정자체는 잘됬었습니다. 어떤 게임에서 수정할 때 그런 문제가 발생하는지, 어떤방법으로 수정했는지 알려주시면 확인후 댓글로 알려드리겠습니다.

      좋아요

      1. 저도 같은 상황이라 글을 남깁니다.
        UABE에서 data unpack 이후 path ID 가 음수인 파일을 Export 할때, (Raw, Dump 상관없이)
        저장되는 Default 파일 이름에서 path ID 부분이 아예 다른 숫자로 바뀌어 버립니다.
        아예 Random은 아니고 일정한 방식으로 변환되는거 같습니다만 원래 path ID와는 전혀 상관 없는 숫자가 나와
        원래 UABE에서 정렬되있던 순서와 Export된 파일들의 순서가 달라 애로사항을 겪었습니다.
        음수앞에 붙는 하이픈 때문이라고 추측되지만 명확한 원인과 해결방법은 아직 찾지 못하였습니다.
        질문한 당사자는 아니지만 같은 상황이라 여기에 글 남김니다. 끼어들어 죄송합니다.

        좋아요

      2. 지금 생각해보면 그냥 uabe에서 unsigned int을 출력할때 int으로 생각해서 출력해서 그런거같습니다.
        uabe에서 -2^16이 파일명으로는 2^16로 -2^0-1이 2^32-1이라 이니까
        파일명에 2^32를 빼면 uabe에 나오는 수일껍니다.

        좋아요

      3. 숫자가 맞지 않아 원본의 포럼에 가서 찾아본 결과 32비트가 아니라 64비트 문제였던 것으로 확인했습니다.

        https://community.7daystodie.com/topic/1871-unity-assets-bundle-extractor/page/32/

        Exported 된 파일에서 2^64를 빼면 원본의 File ID 가 나오는것을 확인했습니다.
        이제 문제는 어떻게 자동적으로 처리할지가 문제네요.
        파일 이름을 바꾸면 Import를 대량으로 할 수 없게되니…
        도움 감사합니다! 혹시 해결한다면 밑에 새로 댓글로 남기겠습니다

        좋아요

  4. 덕분에 한글화 작업에 맨땅에 헤딩하는데 헬맷쓴 느낌입니다 ^^
    정말 감사히 보고 있습니다. 자주 찾아와서 보고있어요
    그런데 궁금한게 있는데
    제가 폰트 파일을 import raw를 해서 폰트파일을 입히고 modified에 별 들어온거 확인한 다음에 저장을 하고 불러오면 폰트이름들이 unnamed asset으로 변경되어 있습니다 파일을 export해서 .dat을 .ttf로 바꾸고 열어보면 제가 넣고자 했던 파일이 들어있는 겁니다. 그런데 막상 게임에서는 변화가 없는데 왜 그러는걸까요? 도와주세요 ㅠㅠ

    좋아요

  5. 유니티 게임에서 폰트는 폰트파일이 아니라 폰트 에셋 형태로 존재하고 폰트 파일(ttf)는 그 에셋의 한 프로퍼티(멤버)에 바이트 배열로 존재합니다. 직접 이 파일을 수정하기 힘드니 UnityL10nTool을 통해 수정하는 것을 추천 드립니다.

    좋아요

  6. 플러그인에서 사운드를 추출할떄 unable to open streamed file 이라는 오류가 뜨는데 어떻게 하죠? ㅠㅠ

    좋아요

    1. 사운드와 이미지는 assets 파일이 아닌 동일한 이름을 가지고있는 .bundle이나 .resS 파일에있습니다.
      파일이 존재하는지 확인해보시고 그래도 안되면 추출하고자하는 에셋의 View Data(asset) 화면에서 streaming 프로퍼티안의 내용물이 보이게 캡쳐해서 올려주세요

      좋아요

  7. 굉장히 도움이 되었습니다!
    이 강좌를 통해 한글화가 조금씩 나아가는것에 대하여 굉장히 기쁩니다.
    다만 문제가 있는것이 UABE를 사용하여 asset에서 대사 파일을 추출하는데
    export dump로 txt 파일을 추출하여 수정후 import dump를 하려 했으나
    어찌된 일인지 import dump된 파일의 view data를 보면
    중간부분부터 뚝 끊겨 적용이 안되어 텍스트 파일의 반만큼만 적용되버리고 맙니다.
    말로는 설명이 잘 안 와닿으실터이나 사진을 캡쳐하여 올릴수 없으니 아쉽군요.
    gameobject 와 monoscript는 잘 반영되는데 희안하게 $Material에서 뚝 끊겨버립니다
    혹시라도 도움을 주실수 있으시면 감사하겠습니다.

    좋아요

    1. 계속하면서 발견한거지만, 이미 수정된 데이터를 다시 export dump 할때는 밑의 부분이 전혀 나오지 않지만, export raw를 사용하면 중간의 일정데이터는 사라졌지만 밑의부분은 멀쩡히 나오는것을 확인했습니다.

      좋아요

      1. 저도 가끔 겪는 UABE 버그인데, Export, Import Dump할 때 몇몇 에셋에서 일부가 사라지는 문제를 저도 겪었습니다. 저같은경우 작은 값 변경정도는 그냥 Raw를 추출해서 대충 값이 어디있을지 계산해서 수정후 Import시켰습니다.
        만약 txt로 추출해서 안되면 json으로 추출해보시고 그래도 안되면 다시 연락주세요 제가 한번 살펴보겠습니다.

        좋아요

  8. 파일 수정 후 한번에 파일 집어넣는 법은 없나요 , 수정한 파일이 100여개가 넘는데 이걸 전부 수동으로 하나하나 찾아 입력해서 변경해야하나요 ?.?

    좋아요

  9. 써놓으신 강좌 잘 보았습니다. TextAssets이 안보이는 경우는 어떻게 해야할까요? 대사가 들어있는듯한 파일은 resources.assets에서 발견했지만 그부분에 있는 대사를 한글로 번역해서 빌드를 하면 crash 되면서 실행이 되지 않습니다. 게임 이름은 Two point hospital 입니다.

    좋아요

  10. 2019.4버전이 안열려서 찾아보니 바쁘셔서 지원을 못하시는 거였군요
    그래도 좋은 프로그램 만들어주셔서 감사합니다

    좋아요

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

%s에 연결하는 중