@@ -30,6 +30,7 @@ from export_unity_levels import (
|
||||
VDIR_RE,
|
||||
kind_from_path,
|
||||
parse_spawns,
|
||||
infer_theme_from_level,
|
||||
build_border_cache,
|
||||
)
|
||||
from export_unity_prefab_maps import parse_level_prefab
|
||||
@@ -50,10 +51,12 @@ def parse_level_block(chunk: str, lid: int) -> dict:
|
||||
path_m = LEVEL_PATH_RE.search(chunk)
|
||||
level_path = path_m.group(1) if path_m else f"Assets/Prefabs/Level/Level{lid}.prefab"
|
||||
ext_id = normalize_level_id(lid)
|
||||
spawns, spawn_paths = parse_spawns(chunk)
|
||||
return {
|
||||
"levelID": ext_id,
|
||||
"boundary": {"x": bx, "y": by},
|
||||
"spawns": parse_spawns(chunk),
|
||||
"spawns": spawns,
|
||||
"theme": infer_theme_from_level(ext_id, spawn_paths),
|
||||
"unityPrefab": level_path.replace("\\", "/"),
|
||||
"cocosPrefab": prefab_resource_path(ext_id),
|
||||
}
|
||||
@@ -124,6 +127,8 @@ def strip_internal(L: dict) -> dict:
|
||||
out["ground"] = L["ground"]
|
||||
if L.get("border"):
|
||||
out["border"] = L["border"]
|
||||
if L.get("theme"):
|
||||
out["theme"] = L["theme"]
|
||||
return out
|
||||
|
||||
|
||||
@@ -131,6 +136,9 @@ def main():
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument("--unity-root", required=True, help="Unity 项目根目录(含 Assets)")
|
||||
ap.add_argument("--output", required=True, help="输出 levels-database.json")
|
||||
ap.add_argument("--merge-into", default="", help="合并到已有 JSON(保留范围外关卡)")
|
||||
ap.add_argument("--min-level-id", type=int, default=0, help="仅导出 levelID >= 此值")
|
||||
ap.add_argument("--max-level-id", type=int, default=0, help="仅导出 levelID <= 此值")
|
||||
ap.add_argument("--limit", type=int, default=0, help="仅导出前 N 个关卡(调试用)")
|
||||
ap.add_argument("--skip-prefab-maps", action="store_true", help="不解析 Unity prefab 瓦片(快,地图由 Cocos 预制体承担)")
|
||||
args = ap.parse_args()
|
||||
@@ -145,10 +153,14 @@ def main():
|
||||
print("Parsing Levels*.cs …")
|
||||
levels = parse_all_levels_cs(core)
|
||||
ids = sorted(levels.keys())
|
||||
if args.min_level_id > 0:
|
||||
ids = [i for i in ids if i >= args.min_level_id]
|
||||
if args.max_level_id > 0:
|
||||
ids = [i for i in ids if i <= args.max_level_id]
|
||||
if args.limit > 0:
|
||||
ids = ids[: args.limit]
|
||||
levels = {k: levels[k] for k in ids}
|
||||
print(f"Level definitions: {len(levels)}")
|
||||
levels = {k: levels[k] for k in ids}
|
||||
print(f"Level definitions: {len(levels)} ({ids[0] if ids else '?'}-{ids[-1] if ids else '?'})")
|
||||
|
||||
from_prefab = 0
|
||||
from_ring = 0
|
||||
@@ -165,18 +177,56 @@ def main():
|
||||
else:
|
||||
from_ring += 1
|
||||
|
||||
payload = {
|
||||
"version": 1,
|
||||
"generatedAt": datetime.now(timezone.utc).isoformat(),
|
||||
"source": "Unity Levels*.cs + Assets/Prefabs/Level/*.prefab",
|
||||
"stats": {
|
||||
"total": len(levels),
|
||||
"withPrefabTilemap": from_prefab,
|
||||
"withBoundaryRing": from_ring,
|
||||
},
|
||||
"levelIdBase": LEVEL_ID_BASE,
|
||||
"levels": {str(levels[lid]["levelID"]): strip_internal(levels[lid]) for lid in ids},
|
||||
}
|
||||
exported = {str(levels[lid]["levelID"]): strip_internal(levels[lid]) for lid in ids}
|
||||
|
||||
if args.merge_into:
|
||||
merge_path = Path(args.merge_into)
|
||||
if merge_path.is_file():
|
||||
print(f"Merging into {merge_path} …")
|
||||
base = json.loads(merge_path.read_text(encoding="utf-8"))
|
||||
base_levels = base.get("levels", {})
|
||||
base_levels.update(exported)
|
||||
payload = {
|
||||
**base,
|
||||
"version": 2,
|
||||
"generatedAt": datetime.now(timezone.utc).isoformat(),
|
||||
"source": "Unity Levels*.cs + Assets/Prefabs/Level/*.prefab (merged)",
|
||||
"stats": {
|
||||
"total": len(base_levels),
|
||||
"withPrefabTilemap": from_prefab,
|
||||
"withBoundaryRing": from_ring,
|
||||
"exportedRange": len(exported),
|
||||
},
|
||||
"levelIdBase": LEVEL_ID_BASE,
|
||||
"levels": base_levels,
|
||||
}
|
||||
else:
|
||||
print(f"warn: merge target missing, writing export only: {merge_path}", file=sys.stderr)
|
||||
payload = {
|
||||
"version": 2,
|
||||
"generatedAt": datetime.now(timezone.utc).isoformat(),
|
||||
"source": "Unity Levels*.cs + Assets/Prefabs/Level/*.prefab",
|
||||
"stats": {
|
||||
"total": len(exported),
|
||||
"withPrefabTilemap": from_prefab,
|
||||
"withBoundaryRing": from_ring,
|
||||
},
|
||||
"levelIdBase": LEVEL_ID_BASE,
|
||||
"levels": exported,
|
||||
}
|
||||
else:
|
||||
payload = {
|
||||
"version": 2,
|
||||
"generatedAt": datetime.now(timezone.utc).isoformat(),
|
||||
"source": "Unity Levels*.cs + Assets/Prefabs/Level/*.prefab",
|
||||
"stats": {
|
||||
"total": len(exported),
|
||||
"withPrefabTilemap": from_prefab,
|
||||
"withBoundaryRing": from_ring,
|
||||
},
|
||||
"levelIdBase": LEVEL_ID_BASE,
|
||||
"levels": exported,
|
||||
}
|
||||
|
||||
out = Path(args.output)
|
||||
out.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
Reference in New Issue
Block a user