123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
-
- namespace GitMerge
- {
- using UnityEngine;
- using UnityEditor;
- using UnityEngine.SceneManagement;
- using UnityEditor.SceneManagement;
- using System.Collections.Generic;
- using Object = UnityEngine.Object;
- public class MergeManagerScene : MergeManagerBase
- {
- private const int NUMBER_OF_INITIALIZATION_STEPS = 3;
- private Scene theirScene;
- public MergeManagerScene(GitMergeWindow window, VCS vcs)
- : base(window, vcs)
- {
- }
- public bool TryInitializeMerge(string path = null)
- {
- var activeScene = EditorSceneManager.GetActiveScene();
- if (activeScene.isDirty)
- {
- window.ShowNotification(new GUIContent("Please make sure there are no unsaved changes before attempting to merge."));
- return false;
- }
- DisplayProgressBar(0, "Checking out scene...");
- isMergingScene = true;
- var scenePath = path ?? activeScene.path;
- // Overwrite the current scene to prevent the reload/ignore dialog that pops up after the upcoming changes to the file.
- // Pressing "reload" on it would invalidate the GameObject references we're about to collect.
- EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single);
- Lightmapping.ForceStop();
- vcs.CheckoutOurs(scenePath);
- CheckoutTheirVersionOf(scenePath);
- AssetDatabase.Refresh();
- DisplayProgressBar(1, "Opening scene...");
- activeScene = EditorSceneManager.OpenScene(scenePath, OpenSceneMode.Single);
- MergeAction.inMergePhase = false;
- ObjectDictionaries.Clear();
- List<GameObject> ourObjects;
- try
- {
- DisplayProgressBar(2, "Collecting differences...");
- // Find all of "our" objects
- ourObjects = GetAllSceneObjects();
- ObjectDictionaries.AddToOurObjects(ourObjects);
- // Add "their" objects
- theirScene = EditorSceneManager.OpenScene(theirFilename, OpenSceneMode.Additive);
- var addedObjects = GetAllNewSceneObjects(ourObjects);
- BuildAllMergeActions(ourObjects, addedObjects);
- ObjectDictionaries.AddToTheirObjects(addedObjects);
- MoveGameObjectsToScene(theirScene.GetRootGameObjects(), activeScene);
- }
- finally
- {
- EditorSceneManager.UnloadSceneAsync(theirScene);
- AssetDatabase.DeleteAsset(theirFilename);
- EditorUtility.ClearProgressBar();
- }
-
- if (allMergeActions.Count == 0)
- {
- window.ShowNotification(new GUIContent("No conflict found for this scene."));
- return false;
- }
- MergeAction.inMergePhase = true;
- return true;
- }
- private static void DisplayProgressBar(int step, string text)
- {
- var progress = step / (float)NUMBER_OF_INITIALIZATION_STEPS;
- EditorUtility.DisplayProgressBar("GitMerge for Unity", text, progress);
- }
- private static void MoveGameObjectsToScene(IEnumerable<GameObject> addedObjects, Scene scene)
- {
- foreach (var obj in addedObjects)
- {
- EditorSceneManager.MoveGameObjectToScene(obj, scene);
- }
- }
- private static List<GameObject> GetAllSceneObjects()
- {
- var objects = (GameObject[])Object.FindObjectsOfType(typeof(GameObject));
- return new List<GameObject>(objects);
- }
- /// <summary>
- /// Finds all GameObjects in the scene, minus the ones passed.
- /// </summary>
- private static List<GameObject> GetAllNewSceneObjects(List<GameObject> oldObjects)
- {
- var all = GetAllSceneObjects();
- foreach (var obj in oldObjects)
- {
- all.Remove(obj);
- }
- return all;
- }
- /// <summary>
- /// Completes the merge process after solving all conflicts.
- /// Cleans up the scene by deleting "their" GameObjects, clears merge related data structures,
- /// executes git add scene_name.
- /// </summary>
- public override void CompleteMerge()
- {
- MergeAction.inMergePhase = false;
- ObjectDictionaries.DestroyTheirObjects();
- ObjectDictionaries.Clear();
- EditorSceneManager.SaveScene(EditorSceneManager.GetActiveScene());
- allMergeActions = null;
- vcs.MarkAsMerged(fileName);
- // Directly committing here might not be that smart, since there might be more conflicts
- window.ShowNotification(new GUIContent("Scene successfully merged."));
- }
- /// <summary>
- /// Aborts merge by using "our" version in all conflicts.
- /// Cleans up merge related data.
- /// </summary>
- public override void AbortMerge(bool showNotification = true)
- {
- base.AbortMerge(showNotification);
-
- EditorSceneManager.CloseScene(theirScene, true);
- EditorSceneManager.SaveScene(EditorSceneManager.GetActiveScene());
- }
- }
- }
|