/// <summary> /// Attempts to start the build process if user confirms. /// </summary> private void TryStartBuild() { Action <DialogBox.ResultType> dialogCallback = (result) => { if (result == DialogBox.ResultType.Yes) { TrySaveScene(); } else if (result == DialogBox.ResultType.No) { Build(); } }; if (EditorApplication.IsSceneModified()) { DialogBox.Open("Warning", "You current scene has modifications. Do you wish to save them first?", DialogBox.Type.YesNoCancel, dialogCallback); } else { Build(); } }
/// <summary> /// Called when the user requests that the editor shuts down. You must manually close the editor from this /// method if you choose to accept the users request. /// </summary> static void OnEditorQuitRequested() { Action <DialogBox.ResultType> dialogCallback = (result) => { if (result == DialogBox.ResultType.Yes) { TrySaveScene(); } else if (result == DialogBox.ResultType.No) { EditorApplication.SaveProject(); EditorApplication.Quit(); } }; if (EditorApplication.IsSceneModified()) { DialogBox.Open("Warning", "You current scene has modifications. Do you wish to save them first?", DialogBox.Type.YesNoCancel, dialogCallback); } else { EditorApplication.SaveProject(); EditorApplication.Quit(); } }
/// <summary> /// Tests saving, loading and updating of prefabs. /// </summary> private static void UnitTest4_Prefabs() { if (!EditorApplication.IsProjectLoaded) { Debug.LogWarning("Skipping unit test as no project is loaded."); return; } if (EditorApplication.IsSceneModified()) { Debug.LogWarning("Cannot perform unit test as the current scene is modified."); return; } Action PrintSceneState = () => { SceneObject root = Scene.Root; Stack <SceneObject> todo = new Stack <SceneObject>(); todo.Push(root); StringBuilder output = new StringBuilder(); while (todo.Count > 0) { SceneObject so = todo.Pop(); int numChildren = so.GetNumChildren(); for (int i = numChildren - 1; i >= 0; i--) { SceneObject child = so.GetChild(i); output.AppendLine(child.Name); todo.Push(child); } } Debug.Log(output); }; // Disabled because it's a slow test, enable only when relevant (or when a build machine is set up) return; string oldScene = Scene.ActiveSceneUUID; Scene.Clear(); try { // Simple scene save & load { { // unitTest4Scene_0.prefab: // so0 (Comp1) // - so0_0 // - so0_1 (Comp1) // - so0_1_0 (Comp1) // so1 (Comp2) // - so1_0 SceneObject so0 = new SceneObject("so0"); SceneObject so1 = new SceneObject("so1"); SceneObject so0_0 = new SceneObject("so0_0"); SceneObject so0_1 = new SceneObject("so0_1"); SceneObject so1_0 = new SceneObject("so1_0"); SceneObject so0_1_0 = new SceneObject("so0_1_0"); so0_0.Parent = so0; so0_1.Parent = so0; so1_0.Parent = so1; so0_1_0.Parent = so0_1; so0_1_0.LocalPosition = new Vector3(10.0f, 15.0f, 20.0f); so0_1.LocalPosition = new Vector3(1.0f, 2.0f, 3.0f); so1_0.LocalPosition = new Vector3(0, 123.0f, 0.0f); UT1_Component1 comp0 = so0.AddComponent <UT1_Component1>(); UT1_Component2 comp1 = so1.AddComponent <UT1_Component2>(); UT1_Component1 comp1_1 = so0_1.AddComponent <UT1_Component1>(); UT1_Component1 comp0_1_0 = so0_1_0.AddComponent <UT1_Component1>(); comp0.otherSO = so0_1_0; comp0.otherComponent = comp1; comp1_1.b = "originalValue2"; comp0_1_0.b = "testValue"; comp0_1_0.otherSO = so0; comp0_1_0.otherComponent2 = comp0; EditorApplication.SaveScene("unitTest4Scene_0.prefab"); } { EditorApplication.LoadScene("unitTest4Scene_0.prefab"); SceneObject sceneRoot = Scene.Root; SceneObject so0 = sceneRoot.FindChild("so0", false); SceneObject so1 = sceneRoot.FindChild("so1", false); SceneObject so0_0 = so0.FindChild("so0_0", false); SceneObject so0_1 = so0.FindChild("so0_1", false); SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false); Assert(so0_0 != null); Assert(so0_1 != null); Assert(so0_1_0 != null); UT1_Component1 comp0 = so0.GetComponent <UT1_Component1>(); UT1_Component2 comp1 = so1.GetComponent <UT1_Component2>(); UT1_Component1 comp0_1_0 = so0_1_0.GetComponent <UT1_Component1>(); Assert(comp0 != null); Assert(comp1 != null); Assert(comp0_1_0 != null); Assert(comp0_1_0.b == "testValue"); Assert(comp0.otherSO == so0_1_0); Assert(comp0.otherComponent == comp1); Assert(comp0_1_0.otherSO == so0); Assert(comp0_1_0.otherComponent2 == comp0); } } Debug.Log("Passed stage 1"); // Load & save a scene that contains a prefab and references its objects { { // unitTest4Scene_1.prefab: // parentSO0 // - [unitTest4Scene_0.prefab] // parentSO1 // - parentSO1_0 (Comp1) Scene.Clear(); SceneObject parentSO0 = new SceneObject("parentSO0", false); SceneObject parentSO1 = new SceneObject("parentSO1", false); SceneObject parentSO1_0 = new SceneObject("parentSO1_0", false); parentSO1_0.Parent = parentSO1; parentSO0.LocalPosition = new Vector3(50.0f, 50.0f, 50.0f); UT1_Component1 parentComp1_0 = parentSO1_0.AddComponent <UT1_Component1>(); Prefab scene0Prefab = ProjectLibrary.Load <Prefab>("unitTest4Scene_0.prefab"); SceneObject prefabInstance = scene0Prefab.Instantiate(); prefabInstance.Parent = parentSO0; prefabInstance.LocalPosition = Vector3.Zero; SceneObject so0 = prefabInstance.FindChild("so0", false); SceneObject so1 = prefabInstance.FindChild("so1", false); SceneObject so0_1 = so0.FindChild("so0_1", false); SceneObject so1_0 = so1.FindChild("so1_0", false); SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false); UT1_Component1 comp0_1_0 = so0_1_0.GetComponent <UT1_Component1>(); parentComp1_0.otherSO = so1_0; parentComp1_0.otherComponent2 = comp0_1_0; EditorApplication.SaveScene("unitTest4Scene_1.prefab"); } { EditorApplication.LoadScene("unitTest4Scene_1.prefab"); SceneObject parentSO0 = Scene.Root.FindChild("parentSO0", false); SceneObject parentSO1 = Scene.Root.FindChild("parentSO1", false); SceneObject parentSO1_0 = parentSO1.FindChild("parentSO1_0", false); UT1_Component1 parentComp1_0 = parentSO1_0.GetComponent <UT1_Component1>(); SceneObject prefabInstance = parentSO0.GetChild(0); SceneObject so0 = prefabInstance.FindChild("so0", false); SceneObject so1 = prefabInstance.FindChild("so1", false); SceneObject so0_1 = so0.FindChild("so0_1", false); SceneObject so1_0 = so1.FindChild("so1_0", false); SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false); UT1_Component1 comp0_1_0 = so0_1_0.GetComponent <UT1_Component1>(); Assert(parentComp1_0.otherSO == so1_0); Assert(parentComp1_0.otherComponent2 == comp0_1_0); } } Debug.Log("Passed stage 2"); // Modify prefab, reload the scene and ensure it is updated with modified prefab { { // unitTest4Scene_0.prefab: // so0 // - so0_1 (Comp1) // - so0_1_0 (Comp1) // so1 (Comp1, Comp2) // - so1_0 // - so1_1 Scene.Load("unitTest4Scene_0.prefab"); SceneObject sceneRoot = Scene.Root; SceneObject so0 = sceneRoot.FindChild("so0", false); SceneObject so0_0 = so0.FindChild("so0_0", false); SceneObject so0_1 = so0.FindChild("so0_1", false); SceneObject so1 = sceneRoot.FindChild("so1", false); SceneObject so1_0 = so1.FindChild("so1_0", false); SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false); SceneObject so1_1 = new SceneObject("so1_1"); so1_1.Parent = so1; so0.RemoveComponent <UT1_Component1>(); UT1_Component1 comp1 = so1.AddComponent <UT1_Component1>(); UT1_Component1 comp0_1_0 = so0_1_0.GetComponent <UT1_Component1>(); so0_0.Destroy(); comp1.otherSO = so1_0; comp1.otherComponent2 = comp0_1_0; comp0_1_0.otherSO = so1_1; comp0_1_0.otherComponent2 = comp1; comp0_1_0.a = 123; comp0_1_0.b = "modifiedValue"; so1.Name = "so1_modified"; so1.LocalPosition = new Vector3(0, 999.0f, 0.0f); EditorApplication.SaveScene("unitTest4Scene_0.prefab"); } { EditorApplication.LoadScene("unitTest4Scene_1.prefab"); SceneObject parentSO0 = Scene.Root.FindChild("parentSO0", false); SceneObject parentSO1 = Scene.Root.FindChild("parentSO1", false); SceneObject parentSO1_0 = parentSO1.FindChild("parentSO1_0", false); UT1_Component1 parentComp1_0 = parentSO1_0.GetComponent <UT1_Component1>(); SceneObject prefabInstance = parentSO0.GetChild(0); SceneObject so0 = prefabInstance.FindChild("so0", false); SceneObject so1 = prefabInstance.FindChild("so1_modified", false); SceneObject so0_0 = so0.FindChild("so0_0", false); SceneObject so0_1 = so0.FindChild("so0_1", false); SceneObject so1_0 = so1.FindChild("so1_0", false); SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false); SceneObject so1_1 = so1.FindChild("so1_1", false); UT1_Component1 comp0 = so0.GetComponent <UT1_Component1>(); UT1_Component1 comp1 = so1.GetComponent <UT1_Component1>(); UT1_Component1 comp0_1_0 = so0_1_0.GetComponent <UT1_Component1>(); Assert(parentComp1_0.otherSO == so1_0); Assert(parentComp1_0.otherComponent2 == comp0_1_0); Assert(so1_1 != null); Assert(so0_0 == null); Assert(comp0 == null); Assert(comp0_1_0.otherSO == so1_1); Assert(comp0_1_0.otherComponent2 == comp1); Assert(comp0_1_0.a == 123); Assert(comp0_1_0.b == "modifiedValue"); Assert(comp1.otherSO == so1_0); Assert(comp1.otherComponent2 == comp0_1_0); Assert(MathEx.ApproxEquals(so1.LocalPosition.y, 999.0f)); } } Debug.Log("Passed stage 3"); // Make instance specific changes to the prefab, modify the prefab itself and ensure // both changes persist { // Create new scene referencing the prefab and make instance modifications { // unitTest4Scene_2.prefab: // parent2SO0 // - [unitTest4Scene_0.prefab] // parent2SO1 // - parent2SO1_0 (Comp1) // unitTest4Scene_0.prefab (unitTest4Scene_2.prefab instance): // so0 (Comp1(INSTANCE)) // - so0_0 (INSTANCE) // - so0_1 (Comp1) // - so0_1_0 (Comp1) // so1 (Comp2) // - so1_0 Scene.Clear(); SceneObject parent2SO0 = new SceneObject("parent2SO0"); SceneObject parent2SO1 = new SceneObject("parent2SO1"); SceneObject parent2SO1_0 = new SceneObject("parent2SO1_0"); parent2SO1_0.Parent = parent2SO1; UT1_Component1 parentComp1_0 = parent2SO1_0.AddComponent <UT1_Component1>(); Prefab scene0Prefab = ProjectLibrary.Load <Prefab>("unitTest4Scene_0.prefab"); SceneObject prefabInstance = scene0Prefab.Instantiate(); prefabInstance.Parent = parent2SO0; SceneObject so0 = prefabInstance.FindChild("so0", false); SceneObject so1 = prefabInstance.FindChild("so1_modified", false); SceneObject so0_1 = so0.FindChild("so0_1", false); SceneObject so1_0 = so1.FindChild("so1_0", false); SceneObject so1_1 = so1.FindChild("so1_1", false); SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false); UT1_Component2 comp1 = so1.GetComponent <UT1_Component2>(); UT1_Component1 comp0_1_0 = so0_1_0.GetComponent <UT1_Component1>(); UT1_Component1 comp0_1 = so0_1.GetComponent <UT1_Component1>(); SceneObject so0_0 = new SceneObject("so0_0"); so0_0.Parent = so0; UT1_Component1 comp0 = so0.AddComponent <UT1_Component1>(); so1.RemoveComponent <UT1_Component1>(); so1_1.Destroy(); comp0.otherSO = so0_1_0; comp0.otherComponent = comp1; parentComp1_0.otherSO = so1_0; parentComp1_0.otherComponent2 = comp0_1_0; comp0_1_0.otherSO = parent2SO1_0; comp0_1_0.otherComponent2 = parentComp1_0; comp0_1_0.b = "instanceValue"; comp0_1.b = "instanceValue2"; EditorApplication.SaveScene("unitTest4Scene_2.prefab"); } Debug.Log("Passed stage 4.1"); // Reload the scene and ensure instance modifications remain { EditorApplication.LoadScene("unitTest4Scene_2.prefab"); SceneObject root = Scene.Root; SceneObject parent2SO0 = root.FindChild("parent2SO0", false); SceneObject parent2SO1 = root.FindChild("parent2SO1", false); SceneObject parent2SO1_0 = parent2SO1.FindChild("parent2SO1_0", false); SceneObject prefabInstance = parent2SO0.GetChild(0); SceneObject so0 = prefabInstance.FindChild("so0", false); SceneObject so1 = prefabInstance.FindChild("so1_modified", false); SceneObject so0_0 = so0.FindChild("so0_0", false); SceneObject so0_1 = so0.FindChild("so0_1", false); SceneObject so1_0 = so1.FindChild("so1_0", false); SceneObject so1_1 = so1.FindChild("so1_1", false); SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false); UT1_Component1 parentComp1_0 = parent2SO1_0.GetComponent <UT1_Component1>(); UT1_Component1 comp0 = so0.GetComponent <UT1_Component1>(); UT1_Component2 comp1 = so1.GetComponent <UT1_Component2>(); UT1_Component1 comp11 = so1.GetComponent <UT1_Component1>(); UT1_Component1 comp0_1_0 = so0_1_0.GetComponent <UT1_Component1>(); UT1_Component1 comp0_1 = so0_1.GetComponent <UT1_Component1>(); Assert(so0_0 != null); Assert(comp0 != null); Assert(so1_1 == null); Assert(comp11 == null); Assert(comp0.otherSO == so0_1_0); Assert(comp0.otherComponent == comp1); Assert(parentComp1_0.otherSO == so1_0); Assert(parentComp1_0.otherComponent2 == comp0_1_0); Debug.Log(comp0_1_0.otherSO == null); if (comp0_1_0.otherSO != null) { Debug.Log(comp0_1_0.otherSO.InstanceId + " - " + parent2SO1_0.InstanceId); } Assert(comp0_1_0.otherSO == parent2SO1_0); Assert(comp0_1_0.otherComponent2 == parentComp1_0); Assert(comp0_1_0.b == "instanceValue"); Assert(comp0_1.b == "instanceValue2"); } Debug.Log("Passed stage 4.2"); // Load original scene and ensure instance modifications didn't influence it { EditorApplication.LoadScene("unitTest4Scene_1.prefab"); SceneObject parentSO0 = Scene.Root.FindChild("parentSO0", false); SceneObject parentSO1 = Scene.Root.FindChild("parentSO1", false); SceneObject parentSO1_0 = parentSO1.FindChild("parentSO1_0", false); UT1_Component1 parentComp1_0 = parentSO1_0.GetComponent <UT1_Component1>(); SceneObject prefabInstance = parentSO0.GetChild(0); SceneObject so0 = prefabInstance.FindChild("so0", false); SceneObject so1 = prefabInstance.FindChild("so1_modified", false); SceneObject so0_0 = so0.FindChild("so0_0", false); SceneObject so0_1 = so0.FindChild("so0_1", false); SceneObject so1_0 = so1.FindChild("so1_0", false); SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false); SceneObject so1_1 = so1.FindChild("so1_1", false); UT1_Component1 comp0 = so0.GetComponent <UT1_Component1>(); UT1_Component1 comp1 = so1.GetComponent <UT1_Component1>(); UT1_Component1 comp0_1_0 = so0_1_0.GetComponent <UT1_Component1>(); UT1_Component1 comp0_1 = so0_1.GetComponent <UT1_Component1>(); Assert(parentComp1_0.otherSO == so1_0); Assert(parentComp1_0.otherComponent2 == comp0_1_0); Assert(so1_1 != null); Assert(so0_0 == null); Assert(comp0 == null); Assert(comp0_1_0.otherSO == so1_1); Assert(comp0_1_0.otherComponent2 == comp1); Assert(comp0_1_0.a == 123); Assert(comp0_1_0.b == "modifiedValue"); Assert(comp1.otherSO == so1_0); Assert(comp1.otherComponent2 == comp0_1_0); Assert(comp0_1.b == "originalValue2"); Assert(MathEx.ApproxEquals(so1.LocalPosition.y, 999.0f)); } Debug.Log("Passed stage 4.3"); // Modify prefab and ensure both prefab and instance modifications remain { // unitTest4Scene_0.prefab: // so0 (Comp1) // - so0_1 // - so0_1_0 (Comp1) // so1 (Comp1, Comp2) // - so1_1 // - so1_2 (Comp1) // unitTest4Scene_0.prefab (unitTest4Scene_2.prefab instance): // so0 (Comp1) // - so0_0 // - so0_1 (Comp1) // - so0_1_0 (Comp1) // so1 (Comp2) // - so1_2 (Comp1) Scene.Load("unitTest4Scene_0.prefab"); SceneObject sceneRoot = Scene.Root; SceneObject so0 = sceneRoot.FindChild("so0", false); SceneObject so0_1 = so0.FindChild("so0_1", false); SceneObject so1 = sceneRoot.FindChild("so1_modified", false); SceneObject so1_0 = so1.FindChild("so1_0", false); SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false); SceneObject so1_2 = new SceneObject("so1_2"); so1_2.Parent = so1; so0.AddComponent <UT1_Component1>(); so0_1.RemoveComponent <UT1_Component1>(); so1_0.Destroy(); UT1_Component1 comp3 = so1_2.AddComponent <UT1_Component1>(); UT1_Component1 comp0_1_0 = so0_1_0.GetComponent <UT1_Component1>(); comp0_1_0.b = "modifiedValueAgain"; so1.Name = "so1_modifiedAgain"; comp3.otherSO = so0_1; comp3.otherComponent2 = comp0_1_0; EditorApplication.SaveScene("unitTest4Scene_0.prefab"); } Debug.Log("Passed stage 4.4"); // Reload the scene and ensure both instance and prefab modifications remain { EditorApplication.LoadScene("unitTest4Scene_2.prefab"); SceneObject root = Scene.Root; SceneObject parent2SO0 = root.FindChild("parent2SO0", false); SceneObject parent2SO1 = root.FindChild("parent2SO1", false); SceneObject parent2SO1_0 = parent2SO1.FindChild("parent2SO1_0", false); SceneObject prefabInstance = parent2SO0.GetChild(0); SceneObject so0 = prefabInstance.FindChild("so0", false); SceneObject so1 = prefabInstance.FindChild("so1_modifiedAgain", false); SceneObject so0_0 = so0.FindChild("so0_0", false); SceneObject so0_1 = so0.FindChild("so0_1", false); SceneObject so1_0 = so1.FindChild("so1_0", false); SceneObject so1_1 = so1.FindChild("so1_1", false); SceneObject so1_2 = so1.FindChild("so1_2", false); SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false); UT1_Component1 parentComp1_0 = parent2SO1_0.GetComponent <UT1_Component1>(); UT1_Component1 comp0 = so0.GetComponent <UT1_Component1>(); UT1_Component2 comp1 = so1.GetComponent <UT1_Component2>(); UT1_Component1 comp11 = so1.GetComponent <UT1_Component1>(); UT1_Component1 comp0_1_0 = so0_1_0.GetComponent <UT1_Component1>(); UT1_Component1 comp3 = so1_2.AddComponent <UT1_Component1>(); // Check instance modifications (they should override any prefab modifications) Assert(so0_0 != null); Assert(comp0 != null); Assert(so1_1 == null); Assert(comp11 == null); Assert(comp0.otherSO == so0_1_0); Assert(comp0.otherComponent == comp1); Assert(parentComp1_0.otherSO == so1_0); Assert(parentComp1_0.otherComponent2 == comp0_1_0); Assert(comp0_1_0.otherSO == parent2SO1_0); Assert(comp0_1_0.otherComponent2 == parentComp1_0); Assert(comp0_1_0.b == "instanceValue"); // Check prefab modifications Assert(so1_0 == null); Assert(so1.Name == "so1_modifiedAgain"); Assert(comp3.otherSO == so0_1); Assert(comp3.otherComponent2 == comp0_1_0); } Debug.Log("Passed stage 4.5"); } } catch { PrintSceneState(); throw; } finally { if (!string.IsNullOrEmpty(oldScene)) { Scene.Load(ProjectLibrary.GetPath(oldScene)); } else { Scene.Clear(); } ProjectLibrary.Delete("unitTest4Scene_0.prefab"); ProjectLibrary.Delete("unitTest4Scene_1.prefab"); ProjectLibrary.Delete("unitTest4Scene_2.prefab"); } }
/// <summary> /// Tests saving, loading and updating of prefabs. /// </summary> private static void UnitTest4_Prefabs() { if (!EditorApplication.IsProjectLoaded) { Debug.LogWarning("Skipping unit test as no project is loaded."); return; } if (EditorApplication.IsSceneModified()) { Debug.LogWarning("Cannot perform unit test as the current scene is modified."); return; } // Disabled because it's a slow test, enable only when relevant (or when a build machine is set up) /* * Action PrintSceneState = () => * { * SceneObject root = Scene.Root; * * Stack<SceneObject> todo = new Stack<SceneObject>(); * todo.Push(root); * * StringBuilder output = new StringBuilder(); * while (todo.Count > 0) * { * SceneObject so = todo.Pop(); * * int numChildren = so.GetNumChildren(); * for (int i = numChildren - 1; i >= 0; i--) * { * SceneObject child = so.GetChild(i); * * output.AppendLine(child.Name); * todo.Push(child); * } * } * * Debug.Log(output); * }; * * UUID oldScene = Scene.ActiveSceneUUID; * Scene.Clear(); * * try * { * // Simple scene save & load * { * { * // unitTest4Scene_0.prefab: * // so0 (Comp1) * // - so0_0 * // - so0_1 (Comp1) * // - so0_1_0 (Comp1) * // so1 (Comp2) * // - so1_0 * * SceneObject so0 = new SceneObject("so0"); * SceneObject so1 = new SceneObject("so1"); * SceneObject so0_0 = new SceneObject("so0_0"); * SceneObject so0_1 = new SceneObject("so0_1"); * SceneObject so1_0 = new SceneObject("so1_0"); * SceneObject so0_1_0 = new SceneObject("so0_1_0"); * * so0_0.Parent = so0; * so0_1.Parent = so0; * so1_0.Parent = so1; * so0_1_0.Parent = so0_1; * * so0_1_0.LocalPosition = new Vector3(10.0f, 15.0f, 20.0f); * so0_1.LocalPosition = new Vector3(1.0f, 2.0f, 3.0f); * so1_0.LocalPosition = new Vector3(0, 123.0f, 0.0f); * * UT1_Component1 comp0 = so0.AddComponent<UT1_Component1>(); * UT1_Component2 comp1 = so1.AddComponent<UT1_Component2>(); * UT1_Component1 comp1_1 = so0_1.AddComponent<UT1_Component1>(); * UT1_Component1 comp0_1_0 = so0_1_0.AddComponent<UT1_Component1>(); * * comp0.otherSO = so0_1_0; * comp0.otherComponent = comp1; * * comp1_1.b = "originalValue2"; * * comp0_1_0.b = "testValue"; * comp0_1_0.otherSO = so0; * comp0_1_0.otherComponent2 = comp0; * * EditorApplication.SaveScene("unitTest4Scene_0.prefab"); * } * { * EditorApplication.LoadScene("unitTest4Scene_0.prefab"); * * SceneObject sceneRoot = Scene.Root; * SceneObject so0 = sceneRoot.FindChild("so0", false); * SceneObject so1 = sceneRoot.FindChild("so1", false); * SceneObject so0_0 = so0.FindChild("so0_0", false); * SceneObject so0_1 = so0.FindChild("so0_1", false); * SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false); * * Assert(so0_0 != null); * Assert(so0_1 != null); * Assert(so0_1_0 != null); * * UT1_Component1 comp0 = so0.GetComponent<UT1_Component1>(); * UT1_Component2 comp1 = so1.GetComponent<UT1_Component2>(); * UT1_Component1 comp0_1_0 = so0_1_0.GetComponent<UT1_Component1>(); * * Assert(comp0 != null); * Assert(comp1 != null); * Assert(comp0_1_0 != null); * Assert(comp0_1_0.b == "testValue"); * Assert(comp0.otherSO == so0_1_0); * Assert(comp0.otherComponent == comp1); * Assert(comp0_1_0.otherSO == so0); * Assert(comp0_1_0.otherComponent2 == comp0); * } * } * * Debug.Log("Passed stage 1"); * * // Load & save a scene that contains a prefab and references its objects * { * { * // unitTest4Scene_1.prefab: * // parentSO0 * // - [unitTest4Scene_0.prefab] * // parentSO1 * // - parentSO1_0 (Comp1) * * Scene.Clear(); * * SceneObject parentSO0 = new SceneObject("parentSO0", false); * SceneObject parentSO1 = new SceneObject("parentSO1", false); * SceneObject parentSO1_0 = new SceneObject("parentSO1_0", false); * * parentSO1_0.Parent = parentSO1; * parentSO0.LocalPosition = new Vector3(50.0f, 50.0f, 50.0f); * * UT1_Component1 parentComp1_0 = parentSO1_0.AddComponent<UT1_Component1>(); * * Prefab scene0Prefab = ProjectLibrary.Load<Prefab>("unitTest4Scene_0.prefab"); * SceneObject prefabInstance = scene0Prefab.Instantiate(); * prefabInstance.Parent = parentSO0; * prefabInstance.LocalPosition = Vector3.Zero; * * SceneObject so0 = prefabInstance.FindChild("so0", false); * SceneObject so1 = prefabInstance.FindChild("so1", false); * SceneObject so0_1 = so0.FindChild("so0_1", false); * SceneObject so1_0 = so1.FindChild("so1_0", false); * SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false); * * UT1_Component1 comp0_1_0 = so0_1_0.GetComponent<UT1_Component1>(); * * parentComp1_0.otherSO = so1_0; * parentComp1_0.otherComponent2 = comp0_1_0; * * EditorApplication.SaveScene("unitTest4Scene_1.prefab"); * } * { * EditorApplication.LoadScene("unitTest4Scene_1.prefab"); * * SceneObject parentSO0 = Scene.Root.FindChild("parentSO0", false); * SceneObject parentSO1 = Scene.Root.FindChild("parentSO1", false); * SceneObject parentSO1_0 = parentSO1.FindChild("parentSO1_0", false); * * UT1_Component1 parentComp1_0 = parentSO1_0.GetComponent<UT1_Component1>(); * * SceneObject prefabInstance = parentSO0.GetChild(0); * SceneObject so0 = prefabInstance.FindChild("so0", false); * SceneObject so1 = prefabInstance.FindChild("so1", false); * SceneObject so0_1 = so0.FindChild("so0_1", false); * SceneObject so1_0 = so1.FindChild("so1_0", false); * SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false); * * UT1_Component1 comp0_1_0 = so0_1_0.GetComponent<UT1_Component1>(); * * Assert(parentComp1_0.otherSO == so1_0); * Assert(parentComp1_0.otherComponent2 == comp0_1_0); * } * } * * Debug.Log("Passed stage 2"); * * // Modify prefab, reload the scene and ensure it is updated with modified prefab * { * { * // unitTest4Scene_0.prefab: * // so0 * // - so0_1 (Comp1) * // - so0_1_0 (Comp1) * // so1 (Comp1, Comp2) * // - so1_0 * // - so1_1 * * Scene.Load("unitTest4Scene_0.prefab"); * * SceneObject sceneRoot = Scene.Root; * SceneObject so0 = sceneRoot.FindChild("so0", false); * SceneObject so0_0 = so0.FindChild("so0_0", false); * SceneObject so0_1 = so0.FindChild("so0_1", false); * SceneObject so1 = sceneRoot.FindChild("so1", false); * SceneObject so1_0 = so1.FindChild("so1_0", false); * SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false); * * SceneObject so1_1 = new SceneObject("so1_1"); * so1_1.Parent = so1; * * so0.RemoveComponent<UT1_Component1>(); * UT1_Component1 comp1 = so1.AddComponent<UT1_Component1>(); * UT1_Component1 comp0_1_0 = so0_1_0.GetComponent<UT1_Component1>(); * * so0_0.Destroy(); * * comp1.otherSO = so1_0; * comp1.otherComponent2 = comp0_1_0; * * comp0_1_0.otherSO = so1_1; * comp0_1_0.otherComponent2 = comp1; * comp0_1_0.a = 123; * comp0_1_0.b = "modifiedValue"; * * so1.Name = "so1_modified"; * so1.LocalPosition = new Vector3(0, 999.0f, 0.0f); * * EditorApplication.SaveScene("unitTest4Scene_0.prefab"); * } * * { * EditorApplication.LoadScene("unitTest4Scene_1.prefab"); * * SceneObject parentSO0 = Scene.Root.FindChild("parentSO0", false); * SceneObject parentSO1 = Scene.Root.FindChild("parentSO1", false); * SceneObject parentSO1_0 = parentSO1.FindChild("parentSO1_0", false); * * UT1_Component1 parentComp1_0 = parentSO1_0.GetComponent<UT1_Component1>(); * * SceneObject prefabInstance = parentSO0.GetChild(0); * SceneObject so0 = prefabInstance.FindChild("so0", false); * SceneObject so1 = prefabInstance.FindChild("so1_modified", false); * SceneObject so0_0 = so0.FindChild("so0_0", false); * SceneObject so0_1 = so0.FindChild("so0_1", false); * SceneObject so1_0 = so1.FindChild("so1_0", false); * SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false); * SceneObject so1_1 = so1.FindChild("so1_1", false); * * UT1_Component1 comp0 = so0.GetComponent<UT1_Component1>(); * UT1_Component1 comp1 = so1.GetComponent<UT1_Component1>(); * UT1_Component1 comp0_1_0 = so0_1_0.GetComponent<UT1_Component1>(); * * Assert(parentComp1_0.otherSO == so1_0); * Assert(parentComp1_0.otherComponent2 == comp0_1_0); * Assert(so1_1 != null); * Assert(so0_0 == null); * Assert(comp0 == null); * Assert(comp0_1_0.otherSO == so1_1); * Assert(comp0_1_0.otherComponent2 == comp1); * Assert(comp0_1_0.a == 123); * Assert(comp0_1_0.b == "modifiedValue"); * Assert(comp1.otherSO == so1_0); * Assert(comp1.otherComponent2 == comp0_1_0); * Assert(MathEx.ApproxEquals(so1.LocalPosition.y, 999.0f)); * } * } * * Debug.Log("Passed stage 3"); * * // Make instance specific changes to the prefab, modify the prefab itself and ensure * // both changes persist * { * // Create new scene referencing the prefab and make instance modifications * { * // unitTest4Scene_2.prefab: * // parent2SO0 * // - [unitTest4Scene_0.prefab] * // parent2SO1 * // - parent2SO1_0 (Comp1) * * // unitTest4Scene_0.prefab (unitTest4Scene_2.prefab instance): * // so0 (Comp1(INSTANCE)) * // - so0_0 (INSTANCE) * // - so0_1 (Comp1) * // - so0_1_0 (Comp1) * // so1 (Comp2) * // - so1_0 * * Scene.Clear(); * * SceneObject parent2SO0 = new SceneObject("parent2SO0"); * SceneObject parent2SO1 = new SceneObject("parent2SO1"); * SceneObject parent2SO1_0 = new SceneObject("parent2SO1_0"); * * parent2SO1_0.Parent = parent2SO1; * * UT1_Component1 parentComp1_0 = parent2SO1_0.AddComponent<UT1_Component1>(); * * Prefab scene0Prefab = ProjectLibrary.Load<Prefab>("unitTest4Scene_0.prefab"); * SceneObject prefabInstance = scene0Prefab.Instantiate(); * prefabInstance.Parent = parent2SO0; * * SceneObject so0 = prefabInstance.FindChild("so0", false); * SceneObject so1 = prefabInstance.FindChild("so1_modified", false); * * SceneObject so0_1 = so0.FindChild("so0_1", false); * SceneObject so1_0 = so1.FindChild("so1_0", false); * SceneObject so1_1 = so1.FindChild("so1_1", false); * SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false); * * UT1_Component2 comp1 = so1.GetComponent<UT1_Component2>(); * UT1_Component1 comp0_1_0 = so0_1_0.GetComponent<UT1_Component1>(); * UT1_Component1 comp0_1 = so0_1.GetComponent<UT1_Component1>(); * * SceneObject so0_0 = new SceneObject("so0_0"); * so0_0.Parent = so0; * UT1_Component1 comp0 = so0.AddComponent<UT1_Component1>(); * * so1.RemoveComponent<UT1_Component1>(); * so1_1.Destroy(); * * comp0.otherSO = so0_1_0; * comp0.otherComponent = comp1; * * parentComp1_0.otherSO = so1_0; * parentComp1_0.otherComponent2 = comp0_1_0; * * comp0_1_0.otherSO = parent2SO1_0; * comp0_1_0.otherComponent2 = parentComp1_0; * comp0_1_0.b = "instanceValue"; * * comp0_1.b = "instanceValue2"; * * EditorApplication.SaveScene("unitTest4Scene_2.prefab"); * } * * Debug.Log("Passed stage 4.1"); * * // Reload the scene and ensure instance modifications remain * { * EditorApplication.LoadScene("unitTest4Scene_2.prefab"); * * SceneObject root = Scene.Root; * SceneObject parent2SO0 = root.FindChild("parent2SO0", false); * SceneObject parent2SO1 = root.FindChild("parent2SO1", false); * SceneObject parent2SO1_0 = parent2SO1.FindChild("parent2SO1_0", false); * * SceneObject prefabInstance = parent2SO0.GetChild(0); * * SceneObject so0 = prefabInstance.FindChild("so0", false); * SceneObject so1 = prefabInstance.FindChild("so1_modified", false); * SceneObject so0_0 = so0.FindChild("so0_0", false); * SceneObject so0_1 = so0.FindChild("so0_1", false); * SceneObject so1_0 = so1.FindChild("so1_0", false); * SceneObject so1_1 = so1.FindChild("so1_1", false); * SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false); * * UT1_Component1 parentComp1_0 = parent2SO1_0.GetComponent<UT1_Component1>(); * UT1_Component1 comp0 = so0.GetComponent<UT1_Component1>(); * UT1_Component2 comp1 = so1.GetComponent<UT1_Component2>(); * UT1_Component1 comp11 = so1.GetComponent<UT1_Component1>(); * UT1_Component1 comp0_1_0 = so0_1_0.GetComponent<UT1_Component1>(); * UT1_Component1 comp0_1 = so0_1.GetComponent<UT1_Component1>(); * * Assert(so0_0 != null); * Assert(comp0 != null); * Assert(so1_1 == null); * Assert(comp11 == null); * * Assert(comp0.otherSO == so0_1_0); * Assert(comp0.otherComponent == comp1); * * Assert(parentComp1_0.otherSO == so1_0); * Assert(parentComp1_0.otherComponent2 == comp0_1_0); * * Assert(comp0_1_0.otherSO == parent2SO1_0); * Assert(comp0_1_0.otherComponent2 == parentComp1_0); * Assert(comp0_1_0.b == "instanceValue"); * * Assert(comp0_1.b == "instanceValue2"); * } * * Debug.Log("Passed stage 4.2"); * * // Load original scene and ensure instance modifications didn't influence it * { * EditorApplication.LoadScene("unitTest4Scene_1.prefab"); * * SceneObject parentSO0 = Scene.Root.FindChild("parentSO0", false); * SceneObject parentSO1 = Scene.Root.FindChild("parentSO1", false); * SceneObject parentSO1_0 = parentSO1.FindChild("parentSO1_0", false); * * UT1_Component1 parentComp1_0 = parentSO1_0.GetComponent<UT1_Component1>(); * * SceneObject prefabInstance = parentSO0.GetChild(0); * SceneObject so0 = prefabInstance.FindChild("so0", false); * SceneObject so1 = prefabInstance.FindChild("so1_modified", false); * SceneObject so0_0 = so0.FindChild("so0_0", false); * SceneObject so0_1 = so0.FindChild("so0_1", false); * SceneObject so1_0 = so1.FindChild("so1_0", false); * SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false); * SceneObject so1_1 = so1.FindChild("so1_1", false); * * UT1_Component1 comp0 = so0.GetComponent<UT1_Component1>(); * UT1_Component1 comp1 = so1.GetComponent<UT1_Component1>(); * UT1_Component1 comp0_1_0 = so0_1_0.GetComponent<UT1_Component1>(); * UT1_Component1 comp0_1 = so0_1.GetComponent<UT1_Component1>(); * * Assert(parentComp1_0.otherSO == so1_0); * Assert(parentComp1_0.otherComponent2 == comp0_1_0); * Assert(so1_1 != null); * Assert(so0_0 == null); * Assert(comp0 == null); * Assert(comp0_1_0.otherSO == so1_1); * Assert(comp0_1_0.otherComponent2 == comp1); * Assert(comp0_1_0.a == 123); * Assert(comp0_1_0.b == "modifiedValue"); * Assert(comp1.otherSO == so1_0); * Assert(comp1.otherComponent2 == comp0_1_0); * Assert(comp0_1.b == "originalValue2"); * Assert(MathEx.ApproxEquals(so1.LocalPosition.y, 999.0f)); * } * * Debug.Log("Passed stage 4.3"); * * // Modify prefab and ensure both prefab and instance modifications remain * { * // unitTest4Scene_0.prefab: * // so0 (Comp2) * // - so0_1 * // - so0_1_0 (Comp1) * // so1 (Comp1, Comp2) * // - so1_1 * // - so1_2 (Comp1) * * // unitTest4Scene_0.prefab (unitTest4Scene_2.prefab instance): * // so0 (Comp1) * // - so0_0 * // - so0_1 (Comp1) * // - so0_1_0 (Comp1) * // so1 (Comp2) * // - so1_2 (Comp1) * * Scene.Load("unitTest4Scene_0.prefab"); * * SceneObject sceneRoot = Scene.Root; * SceneObject so0 = sceneRoot.FindChild("so0", false); * SceneObject so0_1 = so0.FindChild("so0_1", false); * SceneObject so1 = sceneRoot.FindChild("so1_modified", false); * SceneObject so1_0 = so1.FindChild("so1_0", false); * SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false); * * SceneObject so1_2 = new SceneObject("so1_2"); * so1_2.Parent = so1; * * so0.AddComponent<UT1_Component2>(); * so0_1.RemoveComponent<UT1_Component1>(); * so1_0.Destroy(); * * UT1_Component1 comp3 = so1_2.AddComponent<UT1_Component1>(); * UT1_Component1 comp0_1_0 = so0_1_0.GetComponent<UT1_Component1>(); * comp0_1_0.b = "modifiedValueAgain"; * so1.Name = "so1_modifiedAgain"; * * comp3.otherSO = so0_1; * comp3.otherComponent2 = comp0_1_0; * * EditorApplication.SaveScene("unitTest4Scene_0.prefab"); * } * * Debug.Log("Passed stage 4.4"); * * // Reload the scene and ensure both instance and prefab modifications remain * { * EditorApplication.LoadScene("unitTest4Scene_2.prefab"); * * SceneObject root = Scene.Root; * SceneObject parent2SO0 = root.FindChild("parent2SO0", false); * SceneObject parent2SO1 = root.FindChild("parent2SO1", false); * SceneObject parent2SO1_0 = parent2SO1.FindChild("parent2SO1_0", false); * * SceneObject prefabInstance = parent2SO0.GetChild(0); * * SceneObject so0 = prefabInstance.FindChild("so0", false); * SceneObject so1 = prefabInstance.FindChild("so1_modifiedAgain", false); * SceneObject so0_0 = so0.FindChild("so0_0", false); * SceneObject so0_1 = so0.FindChild("so0_1", false); * SceneObject so1_0 = so1.FindChild("so1_0", false); * SceneObject so1_1 = so1.FindChild("so1_1", false); * SceneObject so1_2 = so1.FindChild("so1_2", false); * SceneObject so0_1_0 = so0_1.FindChild("so0_1_0", false); * * UT1_Component1 parentComp1_0 = parent2SO1_0.GetComponent<UT1_Component1>(); * UT1_Component1 comp0 = so0.GetComponent<UT1_Component1>(); * UT1_Component2 comp1 = so1.GetComponent<UT1_Component2>(); * UT1_Component1 comp11 = so1.GetComponent<UT1_Component1>(); * UT1_Component1 comp0_1_0 = so0_1_0.GetComponent<UT1_Component1>(); * UT1_Component1 comp3 = so1_2.GetComponent<UT1_Component1>(); * * // Check instance modifications (they should override any prefab modifications) * Assert(so0_0 != null); * Assert(comp0 != null); * Assert(so1_1 == null); * Assert(comp11 == null); * * Assert(comp0.otherSO == so0_1_0); * Assert(comp0.otherComponent == comp1); * * Assert(parentComp1_0.otherSO == so1_0); * Assert(parentComp1_0.otherComponent2 == comp0_1_0); * * Assert(comp0_1_0.otherSO == parent2SO1_0); * Assert(comp0_1_0.otherComponent2 == parentComp1_0); * Assert(comp0_1_0.b == "instanceValue"); * * // Check prefab modifications * Assert(so1_0 == null); * Assert(so1.Name == "so1_modifiedAgain"); * * Assert(comp3.otherSO == so0_1); * Assert(comp3.otherComponent2 == comp0_1_0); * } * * Debug.Log("Passed stage 4.5"); * } * } * catch * { * PrintSceneState(); * * throw; * } * finally * { * if (!oldScene.IsEmpty()) * Scene.Load(ProjectLibrary.GetPath(oldScene)); * else * Scene.Clear(); * * ProjectLibrary.Delete("unitTest4Scene_0.prefab"); * ProjectLibrary.Delete("unitTest4Scene_1.prefab"); * ProjectLibrary.Delete("unitTest4Scene_2.prefab"); * } */ }