As I mentioned before, I’ve been working on a videogame project using XNA. However, the need to accelerate the rate of development required us to change our work habits and tools.
Having decided to work with Unity, we started the porting of Dark Recon this year. Everything was going pretty well; we created a repo on Github (hence, Git) and I started coding my load of the job. However, things started to get messy with the repo because of two things I want to address in this post, as a way to help others that might be suffering from the same problem.
Ignoring Unity’s junk
Unity creates a lot of files when you open a project; many of them, temporary files or local files. Even if you open up Unity by mistake, those files (junk for our repo) are created or modified. So, we have a system that tracks file changes (Git) and a constant folder that changes every time. Luckily, Git uses a special file where the user can specify which files will be ignored by the system and thus not counted as part of the repo.
Github, the git-based online hosting service we use, has plenty of templates for many kind of projects, that help as a starting point. For example, say you are coding a project with Visual Studio; the project not only consists on the .cs files you coded, but Visual Studio’s files of that project and the builds of that project as well. If you are working on a team, the only things important to be stored in the repo are the .cs files, everything else is something that must remain local to your computer. A template for a VS project will likely contain the basic information of what files are to be ignored. In the case of Unity, there’s no useful pre-defined template offered by Github (I found one, but it’s incomplete).
After spending a whole morning doing some research, I ended up with the following .ignore file for a Unity project:
#For Mac developers .DS_Store [Oo]bj/ [Tt]emp/ [Ll]ibrary #These are files in the root folder of the project *.tmproj *.csproj *.unityproj *.sln *.suo *.user *.pidb *.userprefs
Essentially, we are ignoring files related to the preferences of the current user’s Unity, as well as files created if you use Visual Studio as your code editor.
Also, we’re ignoring three folders. The Temp folder is, as the name suggests, a folder with temporary files; every time you open Unity, the folder is created and deleted when you close Unity. The Library folder contains all the compiled material the project needs to run; this folder is created if none is found, and is only important to the current user, not the whole team. I dont know what does the Obj folder contains, and I can’t seem to find anything on Google.
While researching, various sources only specified a couple of Library sub-folders, instead of the whole folder. But the support page of Unity specified the whole folder should be ignored.
There’s one last trick. Unity offers a paid Asset version control system (which seems to suck), and recently offered support for external Version Control Systems (i.e. SVN, Mercurial and git). In order to make our project VCS-friendly, we must open it and go to Edit > Project Settings > Editor and select “Meta files” under Version Control Mode. By default, Unity stores all asset information on a subfolder under the Library folder we just ignored in the .ignore file; what this change does is that now every asset (texture, audio, scene, etc.) will be accompanied by a .meta file that keeps log of that specific file. I’m pretty sure that doing this is the reason why the whole Library folder can be ignored.
Using an appropriate workflow
Good, we now have a “clean” repo with just the files we need and nothing else. But, there’s still room for some problems. When multiple users modify the same file, there’s the need to merge both changes into the same file. With text files this is tedious, but doable. With binary files (images, audio, Unity scene files, etc.) this is not (humanly) possible.
So, if you and your co-worker modify the same Scene in Unity, there’ll we trouble. Luckily, I found a blog post that described an easy workflow to minimize the chances of occurrence of this kind of issues.
The solution presented on that blog is to track what assets are being modified, in order that other team members don’t modify it in the meantime. It’s like riding shotgun, but for developers
Say you want to work with a Scene and you’ll be adding a couple of enemies and change the texture of them. You should inform the others that both the scene and the enemy prefab are currently reserved. Then, you pull any changes from the master branch (to update to the latest version of those assets), do your work and then update the master branch (to make those changes available to the rest of the team). Lastly, you free the assets for others to modify them (if needed).
To keep track of which assets are being used by whom, you could set up a Google Docs document (or use other methods, as the last link hinted).
As I said, this will not completely avoid the binary merge issue, but it greatly helps to minimize its occurrence (if applied correctly), even if it is a pain in the ass (and it is).
In conclusion, working with CVSs and Unity is feasible, but it needs a couple of steps of previous work: configure the project and specify the .gitignore file. Also, even if some CVSs, like git, are wonderful tools, they can’t solve problems arising from certain human interaction. If we don’t follow a structured workflow, not even git will be able to help us.
This is the list of links I visited while doing my research:
- Using External Version Control Systems with Unity (Unity support page)
- Using Version Control with Unity3D (Mercurial users, check this one).
- Using Git With Unity
- Unity3D Projects, Version Control and Git
- Setup Unity in Git
- Git vs Asset Server for Unity 3D projects
- Some Git and some Unity
- Unity: Git source control – a basic .gitignore
- Using Git for Unity 3D Source Control
- Which folders in a Unity project are critical folders?