雑用担当の備忘録

技術的な話のみになります。翻訳データそのものはありません。 カテゴリ>その他>注意事項を必ず参照してください

カテゴリ:解析 > Unity5

某所に記述した MonoBehaviour に関する解説をまとめておきます
題材は UGCW です。

ターゲットは
resources_00001.-161
resources_00001.-225

-161 は LoadingScreen をシリアライズしたファイル

LoadingScreen は

public class LoadingScreen : MonoBehaviour
{
 public Text tips;
 public Image picture;
 public Text version;
 public float showMinTime;
 public Sprite[] preloadingScreen;
 public LoadingScreen.PreloadingSet[] prelodingSet;
}
public struct LoadingScreen.PreloadingSet
{
 public string text;
}
UGCW01
Text, Image, Sprite はオブジェクトで objID(dword + ddword) で表されます
(0x20~0x23 + 0x24~0x2B)
00 00 00 00 85 FE 01 00 00 00 00 00 が tips の objID になります。
00 00 00 00 BE 03 02 00 00 00 00 00 が picture
00 00 00 00 00 00 00 00 00 00 00 00 が version(Null オブジェクト)

float は dword
0x44~0x47: 00 00 40 40
Little endian なので 0x40400000 になってこの実数値は 3.0
したがって showMinTime = 3.0

ここまでは固定のサイズになりますが
次の Sprite は配列なので可変になります。objID の倍数のサイズになる
0x48: 06 00 00 00
が配列長
従って preloadingScreen[6] になり Sprite の objID は 6 個存在する。
6(dword + ddword) なので 0x4C~0x93 までが preloadingScreen

PreloadingSet も配列なので
0x94 が配列長 0x10A の個数 preloadingSet がある

preloadingSet は string で

string は 文字列長+文字列+padding で構成される。

"AAAAA" の文字列は
05 00 00 00 41 41 41 41 41 00 00 00
と表される

05 00 00 00 の部分が文字列サイズで
41 41 41 41 41 が "AAAAA" の文字コード(utf-8)
00 00 00 は padding

padding が 00 00 00 の3バイトになるのは
41 41 41 41 41 が5バイトなので、4の倍数になるように調整する必要がある(アライメント)
今回は8バイトになるように 5+3 で 00 00 00 の padding が必要になる

"あああああ" の場合は
0F 00 00 00 E3 81 82 E3 81 82 E3 81 82 E3 81 82
E3 81 82 00
と表現され
'あ' の文字コードは E3 81 82 の部分
5(E3 81 82) = 5x3 = 15 = 0xF が文字列サイズ

文字列は 15 なので padding は 16 になるように 00 の1バイトとなる。


-225 のファイルは Language で

public class Language : MonoBehaviour
{
 public Language.LocalizationGroup[] Groups;
}
public class Language.LocalizationGroup
{
 public string[] Keys;
 public string[] Values;
}
UGCW02
Groups.length = 10 で
Groups[0].keys.length = 7 個ある
Groups[0].keys[0] = "OfficerRank_Captain"

Groups[0].values.length = 7 個ある
Groups[0].values[0] = "Captain"

ということです。

font について

SotD は bitmap font です。Unity の bitmap フォントは色々なパターン(NGUI 等)があるのですが今回は標準形の bitmap font で UnityEx 上で font (type 128) のファイル名の拡張子が font_raw で表示されているものです。ttf の方は dynamic font になります。

font_raw:

struct FontRaw {
    ascii_stzrt_offset: i32,
    tracking: f32,
    line_spacing: f32,
    character_spacing: i32,
    character_padding: i32,
    convert_case: i32,
    default_material: ObjId,
    character_rects_size: u32,      // 0 == dynamic font, 0 != bitmap font
    character_rects: Vec<CharacterInfo>,
    texture: ObjId,
    kerning_size: u32,
    kerning: Vec<PairData>,
    pixel_scale: f32,
    font_data_size: u32,            // 0 != dynamic font, 0 == bitmap font
    font_data: Vec<u8>,             // ttf image
    font_size: f32,
    ascent: f32,
    default_style: i32,
    font_name_size: u32,
    font_names: Vec<FontName>,
    fallback_fonts_size: u32,
    fallback_font: Vec<FallbackFont>,
    font_rendering_mode: i32,
}

ここで注目するのは、bitmap font は caracter_rects (座標情報)のデータが存在し dynamic font は font_data (ttf ファイルそのもの) が存在する。
つまり bitmap → dynamic への変換は
character_rects_size = 0;
character_rects はカット
kerning_size = 0;  << kerning はカット
kerning は無し
font_data_size = ttf ファイルサイズ
font_data = ttf ファイルデータと置き換える
とし
convert_case = -2;
とすると dynamic font へ変換されます。
後は、この変換された raw_font データを UnityEx にてインポートすると
SotD_01j
SotD_02j
SotD_03j

と表示されます。
フォントサイズは要調整のような気もするが…

Localization data:

LocalizationUtils にてロードしているのでキャストしている LocalizationTagBundle に注目する。
LocalizationTagBundle は単なる LocalizationTag のコンテナなので LocalizationTag に注目する。

public class LocalizationTag
{
    public int m_Id;
    public string m_Tag;
    public string m_E; // english
    public string m_F;   // french
    public string m_I;    // Italian
    public string m_G;  // German
    public string m_S;  // Spanish
    public string m_P;  // Portuguese
}

なのでこれっぽい。コンテナの方の LocalizationTagBundle で GameObjectID を検索する。
GameObjectID = 1780

resource.assets の MonoBehaviour (type:114) で 1780 にマッチするデータを抽出すると拡張子 -20 のデータだとわかる。(現時点のバージョン。この部分は更新により変動があります。)
-20 の中身を見ると、LocalizationTag があるのがわかります。
文字コードは UTF-8
で上記の情報より編集しやすいようにバイナリ<>テキストツールを作成するとよい。

オリジナル
SotD_01
Localization data 書き換え後
SotD_01e
オリジナル
SotD_02
Localization data 書き換え後
SotD_02e
オリジナル
SotD_03
Localization data 書き換え後
SotD_03e

はい、文字化けしています(表示されていない)。
bitmap フォントを使用しているのですがこれを dynamic フォントに変換すると正常に表示されるようになります。
フォントの話は次回

SotD_01
概要:
  • Unity 5.3.4p5
  • Localization data: resources.assets (LocalizationTagBundle, LocalizationTag)
  • Font: bitmap, sharedassets0.assets

SotD_01j

a147

lblActivateInGame
01876.1 → 0x754
file name: level1_00503.-15
mTrueTypeFont: 0x1984 → font_body.ttf
mFont: 0xA9AE → resources_00002.-15 (UIFont: AgencyB_32p)

lblTooltipLine
00612.1 → 0x264
file name: level1_00167.-15
mTrueTypeFont: 0x0 → null
mFont: 0xA9AE → resources_00002.-15 (UIFont: AgencyB_32p)

lblStealthIndicator
00045.1 → 0x2D
file name: level1_00009.-15
mTrueTypeFont: 0x0 → null
mFont: 0xA9AE → resources_00002.-15 (UIFont: AgencyB_32p)

lblCriticalHitText
00520.1 → 0x208
file name: level1_00143.-15
mTrueTypeFont: 0x0 → null
mFont: 0xA9AE → resources_00002.-15 (UIFont: AgencyB_32p)

a146 との違いは lblActivateInGame のファイル名が変更になったのと mTrueTypeFont の font_body.ttf の値が変わっているので注意する。

何のこと?という感じだろうからこの辺りの解析を自動化してパッチをあてるツールを作成しました。
こちら
pass:zt

動作確認は a147 ですけど、自動解析するので多少のバージョンアップには耐えれると思います。
 
追記: a15e でも動作しているっぽい。この調子だと何もいじらずに a15 でも行けそうな感じですなー
a15正式版でも大丈夫です。

↑このページのトップヘ