在游戏开发团队协作中,Unity工程打包后的产物管理一直是个容易被忽视却影响效率的关键环节。我们团队最近就遇到了这样的痛点:每次打包后,美术和策划需要手动将AB包(AssetBundle)复制到SVN指定目录,再手动提交更新。这个过程中经常出现版本错乱、遗漏文件甚至覆盖他人修改的情况。
经过内部讨论,我们决定开发一套自动化流程来解决以下核心问题:
方案采用Unity Editor扩展结合Python脚本的方式实现自动化流水线:
code复制[Unity Build Pipeline] → [Post-build Python Script] → [SVN Client] → [Remote Repository]
关键组件说明:
选择Python而非C#实现文件操作和SVN交互,主要基于:
在Editor文件夹下创建BuildPostprocessor.cs:
csharp复制using UnityEditor;
using UnityEngine;
using System.Diagnostics;
public class BuildPostProcessor
{
[PostProcessBuild(1)]
public static void OnPostprocessBuild(BuildTarget target, string path)
{
if(target != BuildTarget.StandaloneWindows) return;
string pythonPath = @"C:\Python39\python.exe";
string scriptPath = Application.dataPath + "/Editor/PostBuild.py";
ProcessStartInfo start = new ProcessStartInfo();
start.FileName = pythonPath;
start.Arguments = $"\"{scriptPath}\" \"{path}\"";
start.UseShellExecute = false;
Process.Start(start);
}
}
重要提示:需要确保Python环境已安装并配置系统PATH变量
PostBuild.py核心逻辑:
python复制import os
import sys
import shutil
from datetime import datetime
import subprocess
def svn_commit(folder_path, message):
try:
subprocess.run(f'svn add "{folder_path}" --force', check=True)
subprocess.run(f'svn commit "{folder_path}" -m "{message}"', check=True)
return True
except subprocess.CalledProcessError as e:
print(f"SVN操作失败: {e}")
return False
def main():
if len(sys.argv) < 2:
print("请传入构建输出路径")
return
build_path = sys.argv[1]
target_dir = r"\\svn-server\game_assets\AB"
# 创建版本目录
version = datetime.now().strftime("%Y%m%d_%H%M")
dest_path = os.path.join(target_dir, version)
if not os.path.exists(dest_path):
os.makedirs(dest_path)
# 复制文件
for item in os.listdir(build_path):
s = os.path.join(build_path, item)
d = os.path.join(dest_path, item)
if os.path.isdir(s):
shutil.copytree(s, d)
else:
shutil.copy2(s, d)
# SVN提交
commit_msg = f"Auto commit build {version}"
if svn_commit(dest_path, commit_msg):
print(f"成功提交版本 {version}")
else:
print("提交失败,请手动处理")
if __name__ == "__main__":
main()
当SVN目录存在锁定文件时,自动清理:
python复制def cleanup_svn_locks(folder):
for root, dirs, files in os.walk(folder):
if '.svn' in dirs:
dirs.remove('.svn') # 跳过.svn目录
for file in files:
if file.endswith('.lock'):
os.remove(os.path.join(root, file))
为避免每次全量复制,实现差异对比:
python复制def sync_files(src, dst):
for item in os.listdir(src):
src_path = os.path.join(src, item)
dst_path = os.path.join(dst, item)
if not os.path.exists(dst_path) or \
os.path.getmtime(src_path) > os.path.getmtime(dst_path):
if os.path.isdir(src_path):
shutil.copytree(src_path, dst_path, dirs_exist_ok=True)
else:
shutil.copy2(src_path, dst_path)
建议在Python脚本中添加以下保障措施:
python复制def safe_operation(func, *args, max_retries=3, **kwargs):
for i in range(max_retries):
try:
return func(*args, **kwargs)
except Exception as e:
if i == max_retries - 1:
raise
time.sleep(1)
测试数据对比:
| 操作方式 | 平均耗时 | 错误率 |
|---|---|---|
| 人工操作 | 8-15分钟 | 23% |
| 自动化流程 | 1-2分钟 | <1% |
该方案可轻松适配以下需求变更:
只需修改Python脚本中的对应模块即可实现,例如添加邮件通知:
python复制import smtplib
from email.mime.text import MIMEText
def send_notification(version, status):
msg = MIMEText(f"构建版本 {version} {status}")
msg['Subject'] = f'[构建系统] {version} 状态通知'
msg['From'] = 'auto-build@company.com'
msg['To'] = 'team@company.com'
with smtplib.SMTP('smtp.company.com') as server:
server.send_message(msg)
这套系统在我们团队运行三个月以来,构建部署效率提升87%,版本混乱问题完全杜绝。最大的收获是让非技术同事也能放心使用最新构建资源,不再需要反复确认版本是否正确。