1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
| import argparse import subprocess import os import json import hashlib from datetime import datetime
class UnityABBuilder: def __init__(self, config): self.config = config self.unity_path = config.get('unity_path', '') self.project_path = config.get('project_path', '') self.output_path = config.get('output_path', '') def build(self): """执行 Unity 构建""" cmd = [ self.unity_path, '-batchmode', '-nographics', '-silent-crashes', '-projectPath', self.project_path, '-executeMethod', 'AssetBundleBuilder.BuildAll', '-buildTarget', self.config['platform'], '-buildType', self.config['build_type'], '-outputPath', self.output_path, '-logFile', os.path.join(self.output_path, 'unity_build.log'), '-quit' ] print(f"执行命令: {' '.join(cmd)}") result = subprocess.run(cmd, capture_output=True, text=True) if result.returncode != 0: raise Exception(f"Unity 构建失败: {result.stderr}") return True def generate_manifest(self): """生成资源清单文件""" manifest = { "version": self.config['version'], "build_number": self.config['build_number'], "platform": self.config['platform'], "build_time": datetime.now().isoformat(), "total_size": 0, "files": [] } for root, dirs, files in os.walk(self.output_path): for file in files: if file.endswith('.ab') or file.endswith('.json'): file_path = os.path.join(root, file) relative_path = os.path.relpath(file_path, self.output_path) file_info = self.get_file_info(file_path, relative_path) manifest['files'].append(file_info) manifest['total_size'] += file_info['size'] manifest_path = os.path.join(self.output_path, 'resource_manifest.json') with open(manifest_path, 'w', encoding='utf-8') as f: json.dump(manifest, f, indent=2, ensure_ascii=False) return manifest def get_file_info(self, file_path, relative_path): """获取文件详细信息""" stat = os.stat(file_path) return { "name": relative_path.replace('\\', '/'), "size": stat.st_size, "md5": self.calculate_md5(file_path), "mtime": stat.st_mtime } def calculate_md5(self, file_path): """计算文件 MD5""" hash_md5 = hashlib.md5() with open(file_path, "rb") as f: for chunk in iter(lambda: f.read(4096), b""): hash_md5.update(chunk) return hash_md5.hexdigest()
def main(): parser = argparse.ArgumentParser(description='Unity AssetBundle 构建工具') parser.add_argument('--platform', required=True, choices=['StandaloneWindows64', 'Android', 'iOS', 'WebGL'], help='目标平台') parser.add_argument('--type', default='Full', choices=['Full', 'Incremental', 'Clean'], help='构建类型') parser.add_argument('--version', default='1.0.0', help='版本号') args = parser.parse_args() config = { 'unity_path': 'C:\\Program Files\\Unity\\Hub\\Editor\\2021.3.21f1\\Editor\\Unity.exe', 'project_path': os.getcwd(), 'output_path': f'D:\\AB_Output\\build_{datetime.now().strftime("%Y%m%d_%H%M%S")}', 'platform': args.platform, 'build_type': args.type, 'version': args.version, 'build_number': os.environ.get('BUILD_NUMBER', '0') } builder = UnityABBuilder(config) try: print("开始构建 AssetBundle...") builder.build() print("生成资源清单...") manifest = builder.generate_manifest() print(f"构建完成!总计 {len(manifest['files'])} 个文件,大小: {manifest['total_size'] / 1024 / 1024:.2f} MB") except Exception as e: print(f"构建失败: {e}") return 1 return 0
if __name__ == '__main__': exit(main())
|