Working on workflow for Unity and git
Unity3D seems to be a great software for rapid prototype development. It certainly is but when properly used. You’re alone with your prototype? It’s OK but I was the other case. When it comes to collaborate there’s a belief that nothing will change during the process of development. Well, the reality is that the teamwork does change a lot. If you dare to work with team using Unity, then you may find my experience useful to you.
Our workflow in Unity with git
Our workflow looks like this:
- Develop feature on some branch (don’t have to but it’s easier to explain). Then commit.
- Minimize Unity so it won’t refresh assets (or alternatively close it).
- Fetch code from our central git server.
- Try to rebase my branch with origin/master branch.
Code rebase is being done normally. Code should be tested for compilation and whether it can be run. It can be easily felt in practice that descriptions for our git commits are very important. That’s because it’s hard to test whether everything works when we don’t understand what to test after making our own changes.
The worst thing is that this very simple (programmers’) workflow was not well designed into the Unity feature list.
Houston…
Unity3D has shown us some real collaboration issues:
- difficulties due to code merge because Strings are everywhere. Tags, Layers, object names, prefabs or animations - you can’t easily put those strings into constants.
- difficult refactoring (changing scripts names or moving them to subfolders)
- difficulties with merging scenes
Problem that emerge from points 2 and 3 - merge after refactor - can be a really hard lesson. I will describe those issues in detail showing my (semi-) solutions that worked for us.
Problem #1 - Update my Constant Strings!
Creating GameObject from Prefab by name? Referencing to a Layer? Putting some Tag into GameObject? Starting some animation by name? What if you change any of those names in those never-wanted refactor times? Putting Prefab all those names into constants is pretty easy. The problem is how to update them. After some frustrations I managed to code some constant updaters for Layers and Tags.
First I have found C# constants generator in AlmostLogical blog. And here’s my modification: https://gist.github.com/Namek/ecafa24a6ae3d730baf1
The main difference is that my version generates Layers.cs file with proper layer masks which are needed in Physics.Raycast() instead of just layer id. Usage is fairly simple - when you change some Layers or Tags in Unity, choose menu option Edit -> Rebuild Tags And Layers Enums.
Problem #2 - script is missing and I don’t know which one
Scripts are missing when you change their names or locations. This one is pretty easy to solve. Use that tool, it’s pretty cool:
http://www.daikonforge.com/dfgui/missing-script/
Unfortunately, you can’t entirely rely on it. Sometimes findings of this tool are ambiguous. Sometimes it doesn’t find anything at all, not sure why. Anyway, always check your merge conflicts by hand because this tool was made only as a refactor helper.
Problem #3 - Scene merge?
Bigger problem appears when there are merge conflicts in _scenes _or prefabs. We use UniMerge for it. It’s important to know how to use that tool or actually how to develop project before using it:
- Generally try to not put anything on the Scene. Put everything to Prefabs if it’s possible. Thanks to that there will be much less stuff to merge.
- Merging scenes with missing script components is a painfull process so don’t move scripts using Unity file manager but rather system file manager. It’s because Unity changes IDs in .meta files when you move and this is something you don’t want to happen. That’s because such scripts are disconnected from objects attached to Prefabs and already prepared Scene GameObjects.
- If you really have to have some GameObjects in Scene, then try to not change their names too often. UniMerge will show you two different objects instead of one found as renamed. Then, if that object is being connected to another you will probably lose connection after this two-to-one merge. Same story for Prefabs, try to not rename them.
So you see that it’s important to know how to use UniMerge to be effective, but it’s totally worth to be paid for.
Well…
When I talk about this topic to some people, they argue that I’m just ranting about Unity3D and to them that’s simple fanboy-type hate. No. Unity3D is a great software. It makes one able to create multiplatform games, it’s relatively cheap, it’s being developed and tested thoroughly, covers many usage cases (currently both 3D and 2D) and has big community. Even if it’s business all about moneyz it still generates some happiness while using it.
To those who feel that I only rant about Unity, I’ll tell exactly what I’m against in it. My arguing basically consists of two things:
- it’s architecture which is neither ECS or OOP (I already discussed it here). It’s in the middle - GOC (GameObject Components). It’s totally fine. This point is about beginners. People who have never seen anything than imperative and/or object-oriented programming make bad code in Unity. This code is being shared in blogs and overall community does it badly. My opinion.
- it’s easy to work alone but very hard to work with a team. Unity makes us all referencing assets through code rather than GUI because changed disconnected assets are not reported by the software itself. It all ends that we’re avoiding GUI and making some new patterns/procedures for coding, assets providing workflow and finally testing.
OK, where’s the full workflow?
I’m not gonna present any workflow with assets because that’s pretty much individual. Some people create assets in Photoshop, some in Unity3D plugins, Blender or other tools. But ultimately the programmers have to deal with it and with themselves and I have covered my worst struggles about it.
There are more people having problems with collaboration. I just covered some problems that touch myself very hardly. To find more knowledge on the topic (or rants) take a look to following links (some of it may be old).