LightGame 完成 Windows
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
"""Print per-GUID analysis of the foreground Tilemap to help identify TileIds.
|
||||
|
||||
For each tile asset GUID, prints:
|
||||
- count
|
||||
- bounding box (min/max x, y in Unity cell coords)
|
||||
- 5 sample positions
|
||||
- top neighbor distribution: which GUID most often sits directly ABOVE this one
|
||||
- bottom neighbor distribution: which GUID most often sits directly BELOW
|
||||
|
||||
Run:
|
||||
python tools/analyze_foreground.py
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import sys
|
||||
from collections import Counter, defaultdict
|
||||
from typing import Dict, Tuple
|
||||
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
import unity_to_level as u2l
|
||||
|
||||
|
||||
def short(guid: str) -> str:
|
||||
return guid[:8]
|
||||
|
||||
|
||||
def main() -> int:
|
||||
with open(u2l.SCENE_PATH, "r", encoding="utf-8") as f:
|
||||
text = f.read()
|
||||
docs = u2l.split_documents(text)
|
||||
go_names = u2l.parse_gameobjects(docs)
|
||||
tms = u2l.parse_tilemaps(docs, go_names)
|
||||
|
||||
fg = tms.get("foreground")
|
||||
if not fg:
|
||||
print("no foreground tilemap")
|
||||
return 1
|
||||
|
||||
# Build a (x, y) -> guid map; drop duplicates conservatively.
|
||||
cell_guid: Dict[Tuple[int, int], str] = {}
|
||||
for x, y, idx in fg.cells:
|
||||
if 0 <= idx < len(fg.asset_guids):
|
||||
cell_guid[(x, y)] = fg.asset_guids[idx]
|
||||
|
||||
# Group cells by guid.
|
||||
by_guid: Dict[str, list] = defaultdict(list)
|
||||
for (x, y), guid in cell_guid.items():
|
||||
by_guid[guid].append((x, y))
|
||||
|
||||
# Order by count desc.
|
||||
ordered = sorted(by_guid.items(), key=lambda kv: -len(kv[1]))
|
||||
|
||||
print(f"foreground tile assets: {len(fg.asset_guids)}, total cells: {len(cell_guid)}")
|
||||
print()
|
||||
for guid, cells in ordered:
|
||||
xs = [c[0] for c in cells]
|
||||
ys = [c[1] for c in cells]
|
||||
# Neighbors: in Unity Y is up, so "above" = y+1, "below" = y-1.
|
||||
above_counter: Counter = Counter()
|
||||
below_counter: Counter = Counter()
|
||||
left_counter: Counter = Counter()
|
||||
for x, y in cells:
|
||||
up = cell_guid.get((x, y + 1))
|
||||
dn = cell_guid.get((x, y - 1))
|
||||
lf = cell_guid.get((x - 1, y))
|
||||
above_counter[up] += 1 # None means empty/sky
|
||||
below_counter[dn] += 1
|
||||
left_counter[lf] += 1
|
||||
|
||||
# Sample positions: a few spread out cells.
|
||||
sample = sorted(cells)[:: max(1, len(cells) // 5)][:5]
|
||||
|
||||
print(f"{short(guid)} ({guid})")
|
||||
print(f" count : {len(cells)}")
|
||||
print(f" bbox : x [{min(xs)} .. {max(xs)}] y [{min(ys)} .. {max(ys)}]")
|
||||
print(f" samples: {sample}")
|
||||
# top 3 of each direction
|
||||
def fmt(c: Counter) -> str:
|
||||
top = c.most_common(3)
|
||||
return ", ".join(
|
||||
f"{short(g) if g else '<empty>'}={n}" for g, n in top
|
||||
)
|
||||
print(f" above (Unity y+1): {fmt(above_counter)}")
|
||||
print(f" below (Unity y-1): {fmt(below_counter)}")
|
||||
print(f" left : {fmt(left_counter)}")
|
||||
# If almost all rows are the same y, it's probably a horizontal-only tile.
|
||||
y_hist = Counter(ys)
|
||||
top_y = y_hist.most_common(3)
|
||||
print(f" y histogram (top 3): {top_y}")
|
||||
# Single-row or single-col flag
|
||||
if len(set(ys)) <= 2:
|
||||
print(f" >>> appears on only {len(set(ys))} distinct row(s) — likely a 'top' or row-specific tile")
|
||||
if len(set(xs)) <= 2:
|
||||
print(f" >>> appears on only {len(set(xs))} distinct column(s)")
|
||||
print()
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user