Adds level prefabs, theme assets, audio, extensions, and deployment scripts for the Unity WebGL migration. Co-authored-by: Cursor <cursoragent@cursor.com>
125 lines
3.8 KiB
Python
125 lines
3.8 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
从 Unity Assets/Tile/{theme}.prefab + Assets/Texture/{theme} 生成 Cocos 调色板配置。
|
||
对齐 Unity 平铺调色板(如 sanxing:WallBlock / JumpBlock / Baseblock / kuai11)。
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
import json
|
||
import re
|
||
from pathlib import Path
|
||
|
||
# Unity 目录名 → Cocos / GameController 主题名
|
||
THEMES = {
|
||
"SILU": "silu",
|
||
"snow": "snow",
|
||
"sanxing": "sanxing",
|
||
"Chinese": "chinese",
|
||
"numMan": "numMan",
|
||
"redArmy": "redarmy",
|
||
"RED": "redArmy",
|
||
"Level": "default",
|
||
}
|
||
|
||
GROUND_NAMES = {"Baseblock", "JumpBlock"}
|
||
BORDER_NAMES = {"WallBlock", "kuai11", "Decor23", "素材切图-23", "素材切图2-23", "小游戏素材红色_03"}
|
||
|
||
|
||
def parse_palette_guids(prefab_text: str) -> list[str]:
|
||
guids: list[str] = []
|
||
in_array = False
|
||
for line in prefab_text.splitlines():
|
||
if "m_TileAssetArray:" in line:
|
||
in_array = True
|
||
continue
|
||
if in_array and "m_TileSpriteArray:" in line:
|
||
break
|
||
if in_array and "guid:" in line:
|
||
m = re.search(r"guid: ([a-f0-9]+)", line)
|
||
if m:
|
||
guids.append(m.group(1))
|
||
return guids
|
||
|
||
|
||
def read_meta_guid(meta_path: Path) -> str | None:
|
||
try:
|
||
for line in meta_path.read_text(encoding="utf-8").splitlines():
|
||
if line.startswith("guid:"):
|
||
return line.split(":", 1)[1].strip()
|
||
except Exception:
|
||
pass
|
||
return None
|
||
|
||
|
||
def guid_to_tile_name(theme_dir: Path, guid: str) -> str | None:
|
||
if not theme_dir.is_dir():
|
||
return None
|
||
for meta in theme_dir.glob("*.asset.meta"):
|
||
if read_meta_guid(meta) == guid:
|
||
return meta.name.replace(".asset.meta", "")
|
||
return None
|
||
|
||
|
||
def build_theme(unity_root: Path, unity_folder: str, cocos_key: str) -> dict | None:
|
||
tile_prefab = unity_root / "Assets" / "Tile" / f"{unity_folder}.prefab"
|
||
tex_dir = unity_root / "Assets" / "Texture" / unity_folder
|
||
if unity_folder == "Level":
|
||
tex_dir = unity_root / "Assets" / "Texture"
|
||
if not tile_prefab.is_file():
|
||
return None
|
||
guids = parse_palette_guids(tile_prefab.read_text(encoding="utf-8"))
|
||
tiles = []
|
||
for i, g in enumerate(guids):
|
||
name = guid_to_tile_name(tex_dir, g)
|
||
if not name:
|
||
continue
|
||
layer = "ground" if name in GROUND_NAMES else "border"
|
||
tex_rel = f"textures/{cocos_key}/{name}"
|
||
if cocos_key == "default":
|
||
tex_rel = f"textures/default/{name}"
|
||
tiles.append(
|
||
{
|
||
"display": name,
|
||
"layer": layer,
|
||
"tileKey": name,
|
||
"texture": tex_rel,
|
||
"unityIndex": i,
|
||
}
|
||
)
|
||
return {"displayName": cocos_key, "tiles": tiles}
|
||
|
||
|
||
def main():
|
||
import argparse
|
||
|
||
ap = argparse.ArgumentParser()
|
||
ap.add_argument("--unity-root", required=True)
|
||
ap.add_argument("--out", default="assets/resources/map-tiles/palettes")
|
||
args = ap.parse_args()
|
||
|
||
project = Path(__file__).resolve().parent.parent
|
||
unity_root = Path(args.unity_root)
|
||
out_dir = project / args.out
|
||
out_dir.mkdir(parents=True, exist_ok=True)
|
||
|
||
all_themes: dict[str, dict] = {}
|
||
for unity_folder, cocos_key in THEMES.items():
|
||
t = build_theme(unity_root, unity_folder, cocos_key)
|
||
if not t or not t["tiles"]:
|
||
print(f" skip {unity_folder}")
|
||
continue
|
||
all_themes[cocos_key] = t
|
||
(out_dir / f"{cocos_key}.json").write_text(
|
||
json.dumps(t, indent=2, ensure_ascii=False), encoding="utf-8"
|
||
)
|
||
print(f" {cocos_key}: {len(t['tiles'])} tiles")
|
||
|
||
(out_dir / "_index.json").write_text(
|
||
json.dumps({"themes": all_themes}, indent=2, ensure_ascii=False), encoding="utf-8"
|
||
)
|
||
print(f"Wrote -> {out_dir}")
|
||
|
||
|
||
if __name__ == "__main__":
|
||
main()
|