U
01 / 22 · 10 分钟
常见问题

Unity 的 Git:该提交什么,该忽略什么

简短回答

怎样用 Git 管理 Unity 项目而不把它弄坏?

提交 Assets/、ProjectSettings/ 和每一个 .meta;忽略 Library/、Temp/、obj/、Build/ 和 Logs/。在任何人 clone 之前把 Version Control 设成 Visible Meta Files、Asset Serialization 设成 Force Text,大的二进制文件一开始就放进 Git LFS,并且按 prefab 拆分工作,让两个人永远不必合并同一个场景。

Git 跟 Unity 配合得很好。出问题的地方在于:一个 Unity 工程里混着三类文件 —— 你做出来的东西、Unity 为你做的东西所写下的记录,以及 Unity 能够从头重建的东西 —— 而 Git 分不出它们。提交错了组,仓库就变成几个 G 的垃圾,每次 pull 都冲突。开头把这三类理清一次,剩下的就只是普通的 Git。

三类文件

  • 你做出来的东西:Assets/ 下面的一切 —— 场景、脚本、prefab、模型、贴图。仓库就是为它而存在的。

  • Unity 为此写下的记录:ProjectSettings/、Packages/manifest.json,以及每个 asset 各一个 .meta 文件。体积很小,而且必须提交。

  • Unity 自己会重建的东西:Library/、Temp/、Logs/、obj/、Build/。好几个 G,每台机器都不一样,对别人毫无价值。绝对不要提交。

先把工程设置好

  1. 1

    打开 Edit▸Project Settings▸Editor。把 Version Control mode 设成 Visible Meta Files,把 Asset Serialization mode 设成 Force Text。

  2. 2

    Force Text 会把场景和 prefab 写成 YAML 而不是二进制。二进制场景对 Git 来说就是一坨读不了的东西:你看不出改了什么,也永远合不了两个人的工作。

  3. 3

    这两项设置要在任何人 clone 工程之前就提交。以后再改,会把所有场景文件重写进一个巨大的提交里。

.gitignore 文件

把它放在仓库根目录,和 Assets 文件夹同级。末尾的斜杠是有意义的:它表示这是文件夹,所以一个碰巧叫 Temp 的文件仍然会被跟踪。

.gitignore
[Ll]ibrary/
[Tt]emp/
[Oo]bj/
[Bb]uild/
[Bb]uilds/
[Ll]ogs/
[Uu]serSettings/
[Mm]emoryCaptures/

# Editor and OS noise
.vs/
.idea/
.DS_Store
*.csproj
*.sln
*.user

# Build outputs
*.apk
*.aab
*.unitypackage

# Crash reports
sysinfo.txt

如果已经把 Library 提交上去了

terminal
git rm -r --cached Library Temp obj Build
git commit -m "Stop tracking generated folders"

--cached 只把它们移出 Git,不会从你的硬盘上删掉。历史里仍然留着它们,所以在有人重写历史之前仓库都会一直很大;对一个还年轻的工程来说,重建一个新仓库通常比去学 git filter-repo 更快。

大文件:贴图、模型、音频

二进制文件每改一次,Git 就完整地存一份新的。一个 40 MB 的模型重新导出十次,仓库就要永远背着 400 MB。Git LFS 改为只存一个指针,文件本体放在别处。

terminal
git lfs install
git lfs track "*.psd" "*.fbx" "*.blend" "*.wav" "*.mp3" "*.mp4"
git add .gitattributes

两个人,一个场景

这是 Git 没法替你解决的部分。场景文件是一整份描述其中所有物体的 YAML 文档,所以两个人在同一个场景的不同角落干活,动的仍然是同一个文件,而 Git 会给你一个它根本无从做对的合并。

  • 按 prefab 拆分工作。一个人负责敌人的 prefab,另一个负责 UI 的 prefab,场景里只放实例。两个 prefab 就是两个文件,两个文件不会冲突。

  • 大关卡用 additive 场景:一个区域一个场景,运行时一起加载。每个人打开的是自己的那个文件。

  • 把「谁正开着这个场景」说出来。两三个人的团队里,这比任何工具都快、都靠谱。

  • 万一 .unity 文件还是冲突了,就整个采用一边,另一边的活儿用手重做一遍。手工合并过的 YAML 场景打开时损坏的概率高到不值得去试。