Tools/prefab_tree.py — 팩 데모 프리팹 계층·앵커·크기·스프라이트·색·글자 추출(화면별 레퍼런스 재제작용 · #1104)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
33663ecea0
commit
64a1dd5795
|
|
@ -0,0 +1,86 @@
|
||||||
|
# 팩 데모 프리팹을 레퍼런스로 화면을 옮길 때 수치 추출(PD 2026-11-09 화면별 레퍼런스 재제작) — 예: <ComfyUI venv python> -I Tools/prefab_tree.py "<팩>/Prefabs/Prefabs_DemoScene_Panels/Collection_List.prefab" "<팩>/ResourcesData" Content 4
|
||||||
|
# Unity 프리팹 YAML → 계층(이름 · 앵커 · 위치 · 크기 · 이미지 스프라이트/색 · TMP 글자/크기/색) 출력 — 인수: 프리팹 · 스프라이트 루트 · [시작 이름] · [최대 깊이]
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
|
path, sproot = sys.argv[1], sys.argv[2]
|
||||||
|
start = sys.argv[3] if len(sys.argv) > 3 else None
|
||||||
|
maxd = int(sys.argv[4]) if len(sys.argv) > 4 else 99
|
||||||
|
txt = open(path, encoding='utf-8', errors='ignore').read()
|
||||||
|
docs = {}
|
||||||
|
for m in re.finditer(r'--- !u!(\d+) &(-?\d+)[^\n]*\n(.*?)(?=\n--- !u!|\Z)', txt, re.S):
|
||||||
|
docs[m.group(2)] = (m.group(1), m.group(3))
|
||||||
|
guid2name = {}
|
||||||
|
for root, _, files in os.walk(sproot):
|
||||||
|
for f in files:
|
||||||
|
if f.endswith('.meta'):
|
||||||
|
g = re.search(r'guid: (\w+)', open(os.path.join(root, f), encoding='utf-8', errors='ignore').read())
|
||||||
|
if g:
|
||||||
|
guid2name[g.group(1)] = f[:-5]
|
||||||
|
|
||||||
|
|
||||||
|
def field(body, key):
|
||||||
|
m = re.search(r'\n\s*' + key + r': (.*)', '\n' + body)
|
||||||
|
return m.group(1).strip() if m else ''
|
||||||
|
|
||||||
|
|
||||||
|
go_comps = {}
|
||||||
|
go_name = {}
|
||||||
|
for fid, (t, body) in docs.items():
|
||||||
|
if t == '1':
|
||||||
|
go_name[fid] = field(body, 'm_Name')
|
||||||
|
go_comps[fid] = re.findall(r'component: \{fileID: (-?\d+)\}', body)
|
||||||
|
rt_of = {}
|
||||||
|
for g, comps in go_comps.items():
|
||||||
|
for c in comps:
|
||||||
|
if c in docs and docs[c][0] == '224':
|
||||||
|
rt_of[g] = c
|
||||||
|
go_of_rt = {v: k for k, v in rt_of.items()}
|
||||||
|
|
||||||
|
|
||||||
|
def v2(s):
|
||||||
|
m = re.findall(r'[-\d.]+', s)
|
||||||
|
return '(' + ','.join(str(round(float(x), 1)) for x in m) + ')' if m else ''
|
||||||
|
|
||||||
|
|
||||||
|
def desc(g):
|
||||||
|
rt = docs[rt_of[g]][1]
|
||||||
|
out = '%s a%s-%s p%s pos%s size%s' % (go_name[g], v2(field(rt, 'm_AnchorMin')), v2(field(rt, 'm_AnchorMax')), v2(field(rt, 'm_Pivot')), v2(field(rt, 'm_AnchoredPosition')), v2(field(rt, 'm_SizeDelta')))
|
||||||
|
for c in go_comps[g]:
|
||||||
|
if c not in docs or docs[c][0] != '114':
|
||||||
|
continue
|
||||||
|
b = docs[c][1]
|
||||||
|
if not re.search(r'm_Enabled: 1', b):
|
||||||
|
continue
|
||||||
|
sp = re.search(r'm_Sprite: \{fileID: -?\d+, guid: (\w+)', b)
|
||||||
|
col = re.search(r'm_Color: \{r: ([\d.]+), g: ([\d.]+), b: ([\d.]+), a: ([\d.]+)\}', b)
|
||||||
|
if sp:
|
||||||
|
hexc = '#%02X%02X%02X/%.2f' % tuple([int(float(x) * 255 + 0.5) for x in col.groups()[:3]] + [float(col.group(4))]) if col else ''
|
||||||
|
ty = field(b, 'm_Type')
|
||||||
|
ppu = field(b, 'm_PixelsPerUnitMultiplier')
|
||||||
|
out += ' | IMG ' + guid2name.get(sp.group(1), sp.group(1)[:8]) + ' ' + hexc + ' t' + ty + (' ppu' + ppu if ppu and ppu != '1' else '')
|
||||||
|
tx = re.search(r'm_text: (.*)', b)
|
||||||
|
if tx:
|
||||||
|
fc = re.search(r'm_fontColor: \{r: ([\d.]+), g: ([\d.]+), b: ([\d.]+), a: ([\d.]+)\}', b)
|
||||||
|
hexc = '#%02X%02X%02X' % tuple(int(float(x) * 255 + 0.5) for x in fc.groups()[:3]) if fc else ''
|
||||||
|
out += ' | TXT "%s" size%s %s align%s' % (tx.group(1)[:30], field(b, 'm_fontSize'), hexc, field(b, 'm_HorizontalAlignment') or field(b, 'm_textAlignment'))
|
||||||
|
if 'm_EffectDistance' in b:
|
||||||
|
out += ' | FX ' + v2(field(b, 'm_EffectDistance'))
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
def walk(g, d):
|
||||||
|
if d > maxd:
|
||||||
|
return
|
||||||
|
print(' ' * d + desc(g))
|
||||||
|
rt = docs[rt_of[g]][1]
|
||||||
|
for c in re.findall(r'- \{fileID: (-?\d+)\}', rt.split('m_Children:')[1].split('m_Father')[0]) if 'm_Children:' in rt else []:
|
||||||
|
if c in go_of_rt:
|
||||||
|
walk(go_of_rt[c], d + 1)
|
||||||
|
|
||||||
|
|
||||||
|
roots = [g for g in go_name if g in rt_of and (start and go_name[g] == start)]
|
||||||
|
if not roots:
|
||||||
|
roots = [g for g in go_name if g in rt_of and field(docs[rt_of[g]][1], 'm_Father') == '{fileID: 0}']
|
||||||
|
walk(roots[0], 0)
|
||||||
Loading…
Reference in New Issue