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