/// <summary> /// Returns the path to the original project. /// If currently open project is the original, returns its own path. /// If the original project folder cannot be found, retuns an empty string. /// </summary> /// <returns></returns> public static string GetOriginalProjectPath() { if (Clones.IsClone()) { /// If this is a clone... /// Original project path can be deduced by removing the suffix from the clone's path. string cloneProjectPath = ClonesManager.GetCurrentProject().projectPath; int index = cloneProjectPath.LastIndexOf(ClonesManager.CloneNameSuffix); if (index > 0) { string originalProjectPath = cloneProjectPath.Substring(0, index); if (Directory.Exists(originalProjectPath)) { return(originalProjectPath); } } return(string.Empty); } else { /// If this is the original, we return its own path. return(ClonesManager.GetCurrentProjectPath()); } }
/// <summary> /// Deletes the clone of the currently open project, if such exists. /// </summary> public static void DeleteClone(string cloneProjectPath) { /// Clone won't be able to delete itself. if (Clones.IsClone()) { return; } ///Extra precautions. if (cloneProjectPath == string.Empty) { return; } if (cloneProjectPath == ClonesManager.GetOriginalProjectPath()) { return; } //Check what OS is string identifierFile; string args; switch (Application.platform) { case (RuntimePlatform.WindowsEditor): Debug.Log("Attempting to delete folder \"" + cloneProjectPath + "\""); //The argument file will be deleted first at the beginning of the project deletion process //to prevent any further reading and writing to it(There's a File.Exist() check at the (file)editor windows.) //If there's any file in the directory being write/read during the deletion process, the directory can't be fully removed. identifierFile = Path.Combine(cloneProjectPath, Clones.ArgumentFileName); File.Delete(identifierFile); args = "/c " + @"rmdir /s/q " + string.Format("\"{0}\"", cloneProjectPath); StartHiddenConsoleProcess("cmd.exe", args); break; case (RuntimePlatform.OSXEditor): Debug.Log("Attempting to delete folder \"" + cloneProjectPath + "\""); //The argument file will be deleted first at the beginning of the project deletion process //to prevent any further reading and writing to it(There's a File.Exist() check at the (file)editor windows.) //If there's any file in the directory being write/read during the deletion process, the directory can't be fully removed. identifierFile = Path.Combine(cloneProjectPath, Clones.ArgumentFileName); File.Delete(identifierFile); FileUtil.DeleteFileOrDirectory(cloneProjectPath); break; case (RuntimePlatform.LinuxEditor): throw new System.NotImplementedException("No linux support yet :("); //break; default: Debug.LogWarning("Not in a known editor. Where are you!?"); break; } }
/// <summary> /// Creates clone from the project currently open in Unity Editor. /// </summary> /// <returns></returns> public static Project CreateCloneFromCurrent() { if (Clones.IsClone()) { Debug.LogError("This project is already a clone. Cannot clone it."); return(null); } string currentProjectPath = ClonesManager.GetCurrentProjectPath(); return(ClonesManager.CreateCloneFromPath(currentProjectPath)); }
private void OnGUI() { if (Clones.IsClone()) { EditorGUILayout.HelpBox( "This is a clone project. Please use the original project editor to change preferences.", MessageType.Info); return; } GUILayout.BeginVertical("HelpBox"); GUILayout.Label("Preferences"); GUILayout.BeginVertical("GroupBox"); AssetModPref.Value = EditorGUILayout.ToggleLeft( new GUIContent( "(recommended) Disable asset saving in clone editors- require re-open clone editors", "Disable asset saving in clone editors so all assets can only be modified from the original project editor" ), AssetModPref.Value); if (Application.platform == RuntimePlatform.WindowsEditor) { AlsoCheckUnityLockFileStaPref.Value = EditorGUILayout.ToggleLeft( new GUIContent( "Also check UnityLockFile lock status while checking clone projects running status", "Disable this can slightly increase Clones Manager window performance, but will lead to in-correct clone project running status" + "(the Clones Manager window show the clone project is still running even it's not) if the clone editor crashed" ), AlsoCheckUnityLockFileStaPref.Value); } GUILayout.EndVertical(); if (GUILayout.Button("Reset to default")) { AssetModPref.ClearValue(); AlsoCheckUnityLockFileStaPref.ClearValue(); Debug.Log("Editor preferences cleared"); } GUILayout.EndVertical(); }
public static string[] OnWillSaveAssets(string[] paths) { if (Clones.IsClone() && Preferences.AssetModPref.Value) { if (paths != null && paths.Length > 0 && !EditorQuit.IsQuiting) { EditorUtility.DisplayDialog( ClonesManager.ProjectName + ": Asset modifications saving detected and blocked", "Asset modifications saving are blocked in the clone instance. \n\n" + "This is a clone of the original project. \n" + "Making changes to asset files via the clone editor is not recommended. \n" + "Please use the original editor window if you want to make changes to the project files.", "ok" ); foreach (var path in paths) { Debug.Log("Attempting to save " + path + " are blocked."); } } return(new string[0] { }); } return(paths); }
private void OnGUI() { if (Application.platform == RuntimePlatform.LinuxEditor) { EditorGUILayout.HelpBox( "Sorry, but " + ClonesManager.ProjectName + " doesn't support Linux currently.\n" + "Please create a feature request on GitHub issue page if you want it to be added.", MessageType.Info); return; } /// If it is a clone project... if (Clones.IsClone()) { //Find out the original project name and show the help box string originalProjectPath = ClonesManager.GetOriginalProjectPath(); if (originalProjectPath == string.Empty) { /// If original project cannot be found, display warning message. EditorGUILayout.HelpBox( "This project is a clone, but the link to the original seems lost.\nYou have to manually open the original and create a new clone instead of this one.\n", MessageType.Warning); } else { /// If original project is present, display some usage info. EditorGUILayout.HelpBox( "This project is a clone of the project '" + Path.GetFileName(originalProjectPath) + "'.\nIf you want to make changes the project files or manage clones, please open the original project through Unity Hub.", MessageType.Info); } //Clone project custom argument. GUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Arguments", GUILayout.Width(70)); GUILayout.EndHorizontal(); string argumentFilePath = Path.Combine(ClonesManager.GetCurrentProjectPath(), Clones.ArgumentFileName); //Need to be careful with file reading / writing since it will effect the deletion of // the clone project(The directory won't be fully deleted if there's still file inside being read or write). //The argument file will be deleted first at the beginning of the project deletion process //to prevent any further being read and write. //Will need to take some extra cautious if want to change the design of how file editing is handled. if (File.Exists(argumentFilePath)) { string argument = File.ReadAllText(argumentFilePath, System.Text.Encoding.UTF8); string argumentTextAreaInput = EditorGUILayout.TextArea(argument, GUILayout.Height(50), GUILayout.MaxWidth(300) ); File.WriteAllText(argumentFilePath, argumentTextAreaInput, System.Text.Encoding.UTF8); } else { EditorGUILayout.LabelField("No argument file found."); } } else// If it is an original project... { if (isCloneCreated) { GUILayout.BeginVertical("HelpBox"); GUILayout.Label("Clones of this Project"); //List all clones clonesScrollPos = EditorGUILayout.BeginScrollView(clonesScrollPos); var cloneProjectsPath = ClonesManager.GetCloneProjectsPath(); for (int i = 0; i < cloneProjectsPath.Count; i++) { GUILayout.BeginVertical("GroupBox"); string cloneProjectPath = cloneProjectsPath[i]; bool isOpenInAnotherInstance = ClonesManager.IsCloneProjectRunning(cloneProjectPath); if (isOpenInAnotherInstance == true) { EditorGUILayout.LabelField("Clone " + i + " (Running)", EditorStyles.boldLabel); } else { EditorGUILayout.LabelField("Clone " + i); } GUILayout.BeginHorizontal(); EditorGUILayout.TextField("Clone project path", cloneProjectPath, EditorStyles.textField); if (GUILayout.Button("View Folder", GUILayout.Width(80))) { ClonesManager.OpenProjectInFileExplorer(cloneProjectPath); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Arguments", GUILayout.Width(70)); GUILayout.EndHorizontal(); string argumentFilePath = Path.Combine(cloneProjectPath, Clones.ArgumentFileName); //Need to be careful with file reading/writing since it will effect the deletion of //the clone project(The directory won't be fully deleted if there's still file inside being read or write). //The argument file will be deleted first at the beginning of the project deletion process //to prevent any further being read and write. //Will need to take some extra cautious if want to change the design of how file editing is handled. if (File.Exists(argumentFilePath)) { string argument = File.ReadAllText(argumentFilePath, System.Text.Encoding.UTF8); string argumentTextAreaInput = EditorGUILayout.TextArea(argument, GUILayout.Height(50), GUILayout.MaxWidth(300) ); File.WriteAllText(argumentFilePath, argumentTextAreaInput, System.Text.Encoding.UTF8); } else { EditorGUILayout.LabelField("No argument file found."); } EditorGUILayout.Space(); EditorGUILayout.Space(); EditorGUILayout.Space(); EditorGUI.BeginDisabledGroup(isOpenInAnotherInstance); if (GUILayout.Button("Open in New Editor")) { ClonesManager.OpenProject(cloneProjectPath); } GUILayout.BeginHorizontal(); if (GUILayout.Button("Delete")) { bool delete = EditorUtility.DisplayDialog( "Delete the clone?", "Are you sure you want to delete the clone project '" + ClonesManager.GetCurrentProject().name + "_clone'?", "Delete", "Cancel"); if (delete) { ClonesManager.DeleteClone(cloneProjectPath); } } GUILayout.EndHorizontal(); EditorGUI.EndDisabledGroup(); GUILayout.EndVertical(); } EditorGUILayout.EndScrollView(); if (GUILayout.Button("Add new clone")) { ClonesManager.CreateCloneFromCurrent(); } GUILayout.EndVertical(); GUILayout.FlexibleSpace(); } else { /// If no clone created yet, we must create it. EditorGUILayout.HelpBox("No project clones found. Create a new one!", MessageType.Info); if (GUILayout.Button("Create new clone")) { ClonesManager.CreateCloneFromCurrent(); } } } }