工程背景

最近在做 UE 数字孪生 / 大屏工程,人一多就绕不开协作:蓝图、关卡这些 .uasset / .umap 没法像 .cpp 那样三路合并,两边都改同一份,Git 只能二选一。

工程这边已经按 Git + LFS 在走(自建 GitLab、资源进 LFS、uasset/umap 标成 lockable),同时还要搞清楚几件事:Epic 到底主推啥、社区小团队为啥还在用 Git、锁能不能当真「对面立刻改不了」、想上编辑器加锁体验时插件跟不跟得上我们用的 UE 5.7

下面按选型 → 原理 → 踩坑记。

技术选型

官方推荐:Perforce(P4 / Helix Core)

Epic 文档和编辑器工作流,基本是按 Perforce 设计的:资源 Check Out(独占)→ 改 → Submit。引擎默认成熟集成也是 Perforce、SVN;Git 仍是 beta。Epic 自用的 UGS、Robomerge、Horde 等也围着 P4 转。

心智模型是中央库 + 独占检出,不是 Git 那套「随便改再合并」。要用 P4 做主流程,工程得进 P4 Depot(Submit),和现有 GitLab 是两套系统——不是在 UE 里把提供方改成 Perforce,Git 仓库就自动变 P4。

社区广泛使用:Git + LFS(+ 锁 / 插件)

小团队、独立开发、程序为主的项目里,更常见的是 Git + Git LFS:大资源走 LFS,.uasset / .umaplockable,改前 git lfs lock(或装 UEGitPlugin 在编辑器里 Check Out)。

可以按能力分层叠,共用同一套仓库:

1
2
3
L3  可选:UEGitPlugin(编辑器 Check Out ≈ LFS 锁)
L2 可选:内置 Git (beta),看状态 / 随手提交
L1 底座:Git + LFS + .gitignore / .gitattributes

💡tips: L2 对 LFS 锁支持很弱。真要编辑器里加锁,基本得上 L3。

多维对比

维度 Epic 主推(P4) 社区常见(Git + LFS)
定位 AAA / 中大型、美术密集协作的行业默认 小团队、已有 Git 习惯、预算/运维更简单
编辑器集成 一等公民,Check Out / Submit 内置 Git 弱;靠 UEGitPlugin 补锁体验
二进制锁 工作流原生,体验完整 LFS 锁 + 约定;感知偏查询/轮询
分支 Streams,习惯不同于 Git 程序员更熟的分支 / PR 模型
成本 ≤5 用户可免费;再多通常要买授权 自建 GitLab 一般不向 P4 公司按人付费
迁入成本 要另搭 Depot,从 Git 迁等于换主仓库 已有 GitLab 可继续用,配 LFS + lockable 即可

一句话:行业协作默认常是 P4;开源小团队仓库形态更多是 Git + LFS。 选哪条看团队规模、锁体验要求、以及愿不愿意换主仓库。

内网 / 涉密部署

两条都能完全自建、数据不出内网

说明
适用 自建 GitLab + LFS、自建 Helix Core(P4)
通常要避开 GitHub.com、未批准的公有云托管、Helix Cloud 等外网 SaaS(除非单位明文允许)

容易误会的是:Epic 主推 P4 ≠ 必须推到 Perforce 公有云。大厂、政企很多就是机房里自建 P4,和自建 GitLab 在保密模型上是同级的。怕的是数据出域,不是 P4 这个产品名。

对我们这种已有内网 GitLab、人还不多的工程:先把 L1(LFS + lockable + 改前加锁)跑稳往往更合适;真要美术侧强独占检出,再评估内网自建 P4。

追根溯源

冲突从哪来

根因只有一条:.uasset / .umap 是二进制,不能文本合并。同一路径两边都产生不同提交,就会冲突。

典型会撞:

  • 都没加锁(或远程没开 LFS locking)就改同一文件
  • 没先 pull,在过期二进制上改完再合
  • 两个分支各自新建了同路径资源

一般不会因「Git 合并」撞车的:只改 C++ / Config、两人改不同路径、被 ignore 不进库的内容。

撞了也没魔法:跟对方约定以谁为准 → 保留一方 → git add 再提交。之后对该资产加锁。

锁是怎么工作的

不会把两份 uasset 缝在一起。它向远程 LFS 锁服务登记「这路径现在归我」,把并行改变成排队改:

1
想改 → git lfs lock / Check Out → 再改 → commit/push → unlock
机制 作用
时间上串行 通常只有一个人在改该文件
远端有记录 别人 git lfs locks / Check Out 能看到占用
只读提示(lockable + 工具) 减少「忘了加锁就改」

属性大致这样配:

1
2
3
4
[attr]lock filter=lfs diff=lfs merge=lfs -text lockable

*.uasset lock
*.umap lock

⚠️ 远程(GitLab / GitHub 等)要开 Git LFS file locking,锁才在团队间生效。

想接近「一改就加锁」,靠的是编辑器 Checkout on modify + UEGitPlugin,不是 Git 自己监视磁盘:

1
2
3
4
[/Script/UnrealEd.EditorLoadingSavingSettings]
bSCCAutoAddNewFiles=False
bAutomaticallyCheckoutOnAssetModification=False
bPromptForCheckoutOnAssetModification=True

pre-commit 只能拦「未锁就提交」,补不上「改的时候自动占坑」。

锁的即时性

知道被锁了 ≠ 必须先 git pull 锁和文件内容是两套通道。

Git 内容(uasset 本体) LFS 文件锁
存在哪 提交历史 / 分支 LFS 锁服务 API
怎么更新 pull / fetch git lfs locks、Check Out、编辑器刷新
作用 拿到对方改完的文件 登记谁占用了路径

拆开看:

  • A 加锁成功:远端权威状态接近即时(一次 HTTP,通常秒级)
  • B 界面上看到:不是推送,是查询 / 轮询——自己去 lock、保存触发 Check Out、或插件后台刷新时才更新
  • 最硬的即时点:B 再对同一文件加锁被 API 拒绝(秒级),不是图标变蓝的那一下

实用预期

期望 是否成立
A 锁成功后,别人再也锁不上同一文件 ✅ 远端侧即时
B 编辑器像微信一样秒弹「被锁了」 ❌ 没有
B 一保存 / Check Out 就能发现 ✅ 通常秒级
只开着编辑器不动,图标马上变 ⚠️ 靠轮询,有缓存延迟
只有 pull 才知道锁 ❌ 错;锁不靠 pull

空窗期里两边都还没锁就动手,照样可能双改。纪律(先锁后改、目录分工)和工具缺一不可。最容易高估的是「锁 = 实时互斥推送」,最容易低估的是「没 lock 就改 uasset」。

遇到的坑

想把 L3 体验补上时,瞄了 UEGitPlugin——内容浏览器里 Check Out,接近 P4 那套加锁手感。

结果:正式 Release 最新还是 3.16(大约停在 UE 5.4),直接拿来对 UE 5.7 会编不过。5.7 给 ISourceControlProvider 加了纯虚函数,修复已经合进仓库的 **dev**,但维护者两年多没再打正式 Tag;问 5.7 能不能用,标准答复是「下 dev,别看 latest release」。

1
2
3
# 关编辑器后再编,别和 Live Coding 硬刚
cd YourProject/Plugins
git clone --branch dev --depth 1 https://github.com/ProjectBorealis/UEGitPlugin.git

连版本控制时提供方选 Git LFS 2,LFS 用户名要和远端锁身份一致。

即便跟 dev,社区里 5.7.1 仍有 unlock / revert 之类反馈——能编能用,个别功能可能不稳。团队若上,建议 钉死某个 dev commit,别裸追 HEAD,也别干等一个不知何时到来的 5.7 Release。

在这之前,L1 命令行加锁仍然管用:

1
2
3
4
5
git pull
git lfs lock Content/某关卡.umap
# …改完…
git commit && git push
git lfs unlock Content/某关卡.umap

参考资料