聊聊Unity项目管理的那些事:Git-flow和Unity
0x00 前言
0x01 基础:Unity项目如何做版本管理?
为什么更喜欢git?
初来项目组到时候,项目还在使用SVN作为版本管理的工具。作为一个不喜欢SVN的人,自然而然想到了换用git来做版本管理。这里当然并不是说svn不如git好,只是它们的思路的确是不一样的。
与SVN相比,git是一个分布式的版本管理工具。这一点可能是我喜欢git胜过svn的一个决定性原因。
当我们使用git从远端版本库/服务器上check out代码后,git会在自己的机器上克隆一个自己的本地版本库。这样我们在本地就实现了版本的管理,而不必像svn那样必须和服务器连接。举一个例子,当我们在本地开发自己的功能时一旦不小心有了错误的操作,我们只需要在本地进行版本回退即可。如果使用svn的话,这种问题的修改似乎就变得不那么方便了。
喜欢git的另一个原因就是使用git的分支了。我们可以在本地的同一个工作目录下快速的切换不同的分支,每个分支之间都是隔离的。当我们不想影响主分支的时候,可以十分轻松的利用git创建一个新的分支进行开发。
总之,使用git替换svn作为团队的新的版本管理工具之后,团队的开发效率提高了很多。
git和Unity
既然项目组决定采用git作为新的版本管理工具,那么首先的一点就是我们要先确认哪些文件是需要纳入版本管理的。同时,在确认需要管理的文件时,顺便重新规整一下整个项目的目录结构,不仅仅是为了更加便于git进行版本管理,同时也可以更好的维护项目。
上图便是一个典型的Unity项目的默认目录。我们可以看到默认的Unity项目的目录下就已经有很多文件和文件夹了。
但是,作为版本管理,我们通常只需要关注两个文件夹即可。即:Assets文件夹和ProjectSettings文件夹。
其中,Assets文件夹主要用来存放项目的资源,例如脚本文件、贴图、材质、声音资源等等。
而ProjectSettings文件夹则用来存放一些项目的设置,例如输入设置、物理系统的设置、Player设置、Layer、Tags等等。我们可以在Unity的编辑器中的Edit->Project Settings菜单来调整这些设置信息。
默认目录下的其余文件或文件夹都可以由这两个文件夹的内容生成出来。
例如,如果Assets文件夹中包括C#脚本文件,则Unity会在目录生成C#工程文件Assembly-CSharp.csproj。
除此之外, Unity的一些特殊的文件夹也会生成一些工程文件。例如Editor文件夹内如果有C#脚本,则会生成一个Assembly-CSharp-Editor工程文件。
除了这些工程文件之外,Unity还会生成一些文件夹。例如Library、Temp、obj这三个文件夹。它们同样是Unity自动生成的。
Library文件夹的内容主要是在项目中导入资源时产生的一些本地的缓存。
Temp和obj这两个文件夹则是在项目构建时产生的临时文件。
因此,我们可以通过git的.gitignore文件来将不需要被git管理的文件/文件夹添加到忽略列表。下面是github提供的一份适用于Unity项目的 .gitignore 文件列表。
/[Ll]ibrary/
/[Tt]emp/
/[Oo]bj/
/[Bb]uild/
/[Bb]uilds/
/Assets/AssetStoreTools*
# Autogenerated VS/MD/Consulo solution and project files
ExportedObj/
.consulo/
*.csproj
*.unityproj
*.sln
*.suo
*.tmp
*.user
*.userprefs
*.pidb
*.booproj
*.svd
# Unity3D generated meta files
*.pidb.meta
# Unity3D Generated File On Crash Reports
sysinfo.txt
# Builds
*.apk
*.unitypackage
除此之外,我们还需要将Unity为导入资源生成的.meta文件也纳入版本管理,和相应的资源一同维护。meta文件的重要性在于Unity会利用它来处理对应资源之间的引用关系。
为了处理资源之间的引用关系,Unity在序列化时会通过两个数据来保证正确的引用关系。即文件GUID和以及本地ID,其中文件GUID便保存在meta文件中。
fileFormatVersion: 2
guid: 437eb1afce72bb44ca24c6ac3fe90c1d
timeCreated: 1453720237
licenseType: Store
NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
只要使用文本工具打开meta文件即可以看到其内容。
另外还需要注意到的事情便是git版本管理时的文件冲突问题。通常当我们合并两个相同的地方都有修改的分支时,都会产生冲突。
一旦git不知道如何自动合并,就需要我们来手动解决冲突了。如果文件是文本文件,git便会在有冲突的地方做上标记(如 <<<<<<< HEAD ==== >>>>>>> HASH_ID等),参考这些标记我们可以很方便的解决冲突问题。
但是,如果文件是二进制的文件,一旦发生冲突则很难查看git插入的冲突标识,解决起来是比较棘手的。因此Unity项目的资产序列化最好生成文本文件,而不是二进制文件。我们可以在设置中选择序列化的策略。
这样场景文件和prefab等文件就会被序列化为yaml文本文件:
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!29 &1
SceneSettings:
m_ObjectHideFlags: 0
m_PVSData:
m_PVSObjectsArray: []
m_PVSPortalsArray: []
m_OcclusionBakeSettings:
smallestOccluder: 5
smallestHole: 0.25
backfaceThreshold: 100
--- !u!104 &2