无论是个人开发还是团队开发,养成好的版本管理习惯可以大大提高开发效率。常用的版本管理软件一般用SVN或者Git。尽管2者都在用,但是更加偏好SVN一些。安装TortoiseSVN就可以直接将SVN管理软件集成到Windows的Explorer中了。点击鼠标右键就会有SVN的相关菜单,可以非常方便地CheckOut项目以及Commit和Update。
在使用Unity3D开发时,目前主流的代码编辑器(IDE)都会选择Virsual Studio(VS)。作为宇宙第一强大的IDE,VS自然也有SVN插件——Virsual SVN。安装后就可以在VS里面进行SVN操作了。如下图所示,一个项目如果已经纳入了版本管理,在文件前面会有标记。绿色表示同步,黄色表示不同步,红色则表示冲突。可以使用右键进行SVN操作
但是美中不足是Unity3D里面没法快速地进行SVN操作。一般都是回到Explorer中然后进行提交,不够便捷。查看了Unity Asset Store上的SVN插件,发现大多过于复杂,或者一些操作不符合原有的操作习惯。所以对于以极简高效为原则的我来说,还不如自己写一个足够用的小工具。
在《unity插件开发——一个例子:简单的svn集成》中,已经说明了相关方法是,通过Process.Start方法开启一个TortoiseProc.exe进程,并将参数(点击《TortoiseSVN 操作》查看所有参数)传给TortoiseProc,使之执行相关的命令。
using System; using System.Diagnostics; using System.IO; using UnityEditor; using UnityEngine; public class SvnEditor : EditorWindow { #region Setup private const string Svnkey = "key_svnroot"; private const string SvnName = "TortoiseProc.exe"; private static string s_svnpath = SvnName; [MenuItem("SVN/Setup", priority = 0)] public static void Setup() { GetWindow<SvnEditor>(); } #endregion #region Log [MenuItem("Assets/SVN/", priority = 10)] [MenuItem("Assets/SVN/LogAll", priority = 11)] [MenuItem("SVN/", priority = 10)] [MenuItem("SVN/LogAll", priority = 11)] public static void SVNLogAll() { SvnCmdProject(EmSVNCmd.Log); } [MenuItem("Assets/SVN/Log", priority = 1)] public static void SVNLog() { SvnCmdSelect(EmSVNCmd.Log); } #endregion #region Update [MenuItem("Assets/SVN/Update", priority = 2)] public static void SVNUpdate() { SvnCmdSelect(EmSVNCmd.Update); } [MenuItem("Assets/SVN/UpdateAll", priority = 12)] [MenuItem("SVN/UpdateAll", priority = 12)] public static void SVNUpdateAll() { SvnCmdProject(EmSVNCmd.Update); } #endregion #region Commit [MenuItem("Assets/SVN/CommitAll", priority = 13)] [MenuItem("SVN/CommitAll", priority = 13)] public static void SVNCommitAll() { SvnCmdProject(EmSVNCmd.Commit); } [MenuItem("Assets/SVN/Commit", priority = 3)] public static void SVNCommit() { SvnCmdSelect(EmSVNCmd.Commit); } #endregion #region Revert [MenuItem("Assets/SVN/Revert", priority = 4)] public static void SVNRevert() { SvnCmdSelect(EmSVNCmd.Revert); } #endregion #region Clearup [MenuItem("Assets/SVN/ClearUpAll", priority = 15)] [MenuItem("SVN/ClearUpAll", priority = 15)] public static void SVNClearUpAll() { SvnCmdProject(EmSVNCmd.Clearup); } #endregion #region core private static void SvnCmdProject(EmSVNCmd cmd) { var path = Application.dataPath; var project = Directory.GetParent(path); ProcessStart(cmd, project.FullName); } private static void SvnCmdSelect(EmSVNCmd cmd) { var select = Selection.activeObject; var path = AssetDatabase.GetAssetPath(select); ProcessStart(cmd, path); } private static void ProcessStart(EmSVNCmd cmd, string path) { #if UNITY_STANDALONE_WIN||UNITY_EDITOR_WIN try { var info = new ProcessStartInfo(s_svnpath) { Arguments = string.Format("/command:{0} /path:{1} /closeonend:0", cmd.ToString().ToLower(), path) }; Process.Start(info); } catch (Exception) { Setup(); } #endif } #endregion internal void OnEnable() { s_svnpath = EditorPrefs.GetString(Svnkey); } internal void OnGUI() { EditorGUILayout.LabelField("设置SVN"); EditorGUILayout.Space(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("SVN程序", GUILayout.Width(50)); EditorGUILayout.SelectableLabel(s_svnpath, GUILayout.Width(200)); if (GUILayout.Button("select")) { var path = EditorUtility.OpenFilePanel("请选择TortoiseProc.exe存储位置", "", "exe"); if (string.IsNullOrEmpty(path)) return; s_svnpath = path; EditorPrefs.SetString(Svnkey, s_svnpath); } if (GUILayout.Button("Clear")) { s_svnpath = SvnName; EditorPrefs.SetString(Svnkey, s_svnpath); } EditorGUILayout.EndHorizontal(); } private enum EmSVNCmd { Log, Update, Commit, Revert, Clearup } }