Unity incorporates a tool called UnityYAMLMerge that can merge scene and prefab files in a semantically correct way. The tool can be accessed from the command line and is also available to third party version control software.
In the Editor window (menu: Edit > Project Settings, then select the Editor category), you have the option to select a third party version control tool (Perforce or PlasticSCM, for example). When one of these tools is enabled, you will see a Smart Merge menu under the Version Control heading. The menu has four options:
The UnityYAMLMerge tool is shipped with the Unity editor; assuming Unity is installed in the standard location, the path to UnityYAMLMerge will be:
C:\Program Files\Unity\Editor\Data\Tools\UnityYAMLMerge.exe
or
C:\Program Files (x86)\Unity\Editor\Data\Tools\UnityYAMLMerge.exe
…on Windows and
/Applications/Unity/Unity.app/Contents/Tools/UnityYAMLMerge
…on Mac OSX (use the Show Package Contents command from the Finder to access this folder).
UnityYAMLMerge is shipped with a default fallback file (called mergespecfile.txt, also in the Tools folder) that specifies how it should proceed with unresolved conflicts or unknown files. This also allows you to use it as the main merge tool for version control systems (such as git) that don’t automatically select merge tools based on file extensions. The most common tools are already listed by default in mergespecfile.txt but you can edit this file to add new tools or change options.
You can run UnityYAMLMerge as a standalone tool from the command line (you can see full usage instructions by running it without any arguments). Set-up instructions for common version control systems are given below.
.unity
.merge -p %b %1 %2 %r
Then, follow the same procedure to add the .prefab
extension.
Add the following text to your .git
or .gitconfig
file:
[merge]
tool = unityyamlmerge
[mergetool "unityyamlmerge"]
trustExitCode = false
cmd = '<path to UnityYAMLMerge>' merge -p "$BASE" "$REMOTE" "$LOCAL" "$MERGED"
Add the following text to your .hgrc
file:
[merge-patterns]
**.unity = unityyamlmerge
**.prefab = unityyamlmerge
[merge-tools]
unityyamlmerge.executable = <path to UnityYAMLMerge>
unityyamlmerge.args = merge -p --force $base $other $local $output
unityyamlmerge.checkprompt = True
unityyamlmerge.premerge = False
unityyamlmerge.binary = False
Add the following to your ~/.subversion/config
file:
[helpers]
merge-tool-cmd = <path to UnityYAMLMerge>
.unity
in the extension field. <path to UnityYAMLMerge> merge -p %base %theirs %mine %merged
Then, follow the same procedure to add the .prefab
extension.
.unity
extension. <path to UnityYAMLMerge> merge -p "@basefile" "@sourcefile" "@destinationfile" "@output"
Then, follow the same procedure to add the .prefab
extension.
merge -p $BASE $REMOTE $LOCAL $MERGED
in the Arguments text field.To customize how UnityYAMLMerge merges files, configure the mergerules.txt file. This is available in the Editor/Data/Tools
folder of your Unity installation.
The various configuration options are as follows.
The arrays configuration section tells UnityYAMLMerge to treat the specified path as an array; either as a “set” with a key value, or as a “plain” array without key values. The default for all arrays is to do a hybrid mode and try to match with some known heuristics.
[arrays]
set *.GameObject.m_Component *.fileID
set *.Prefab.m_Modification.m_Modifications target.fileID target.guid propertyPath
plain *.MeshRenderer.m_Materials
plain *.Renderer.m_Materials
The exclusions configuration section indicates which paths to exclude from merging. If both sides have been modified, they are then treated as a conflict and will show up for user input.
[exclusions]
exclude *.MeshRenderer.m_Materials.*
exclude *.SpriteRenderer.m_Materials
exclude *.SpriteRenderer.m_Color
include *.ParticleSystem.InitialModule
exclude *.ParticleSystem.*
exclude *.ParticleSystem.InitialModule.*
#excludeDepend *.MonoBehaviour m_Script ^m_
excludeIfContains *.MonoBehaviour.* x y z
excludeIfContains *.MonoBehaviour.* r g b
The comparisons section takes into account negligible differences between float values to ignore per user settings. When enabled, floating point comparison is done relatively to account for relative error. You can configure comparison in the following ways:
The relative comparison value determines epsilon and how comparison will scale with the size of the floats’ relative error. The absolute comparison cutoff determines at which point float comparison switches from absolute to relative from zero (on a graph).
Note: Comparison values should be between float epsilon (~0.00000011921) and 1.0
[comparisons]
float *.Transform.m_LocalPosition.x 0.0000005
float *.Transform.m_LocalPosition.y 0.0000005
float *.Transform.m_LocalPosition.z 0.0000005
float *.Transform.m_LocalRotation.x 0.00005 0.001
float *.Transform.m_LocalRotation.y
float *.Transform.m_LocalRotation.z 0.00005 0.001
float *.Transform.m_LocalRotation.w