forked from BilalY/Rasagar
907 lines
42 KiB
C#
907 lines
42 KiB
C#
|
//#define KEEP_ARTIFACTS_FOR_INSPECTION
|
||
|
//#define ENABLE_TEST_LOGS
|
||
|
|
||
|
using System.Collections;
|
||
|
using System.IO;
|
||
|
using NUnit.Framework;
|
||
|
using UnityEditor;
|
||
|
#if !UNITY_2021_2_OR_NEWER
|
||
|
using UnityEditor.Experimental.SceneManagement;
|
||
|
#endif
|
||
|
using UnityEditor.SceneManagement;
|
||
|
using UnityEngine;
|
||
|
using UnityEngine.AI;
|
||
|
using UnityEngine.SceneManagement;
|
||
|
using UnityEngine.TestTools;
|
||
|
using Object = UnityEngine.Object;
|
||
|
|
||
|
namespace Unity.AI.Navigation.Editor.Tests
|
||
|
{
|
||
|
[Category("PrefabsWithNavMeshComponents")]
|
||
|
class NavMeshSurfaceInPrefabTests
|
||
|
{
|
||
|
const string k_AutoSaveKey = "AutoSave";
|
||
|
const string k_ParentFolder = "Assets";
|
||
|
const string k_TempFolderName = "TempPrefab";
|
||
|
|
||
|
static readonly string k_TempFolder = Path.Combine(k_ParentFolder, k_TempFolderName);
|
||
|
|
||
|
const int k_GrayArea = 7;
|
||
|
const int k_BrownArea = 10;
|
||
|
const int k_RedArea = 18;
|
||
|
const int k_OrangeArea = 26;
|
||
|
const int k_YellowArea = 30;
|
||
|
|
||
|
const int k_PrefabDefaultArea = k_YellowArea;
|
||
|
|
||
|
static bool s_EnterPlayModeOptionsEnabled;
|
||
|
static EnterPlayModeOptions s_EnterPlayModeOptions;
|
||
|
|
||
|
[SerializeField]
|
||
|
string m_PrefabPath;
|
||
|
[SerializeField]
|
||
|
string m_PreviousScenePath;
|
||
|
[SerializeField]
|
||
|
string m_TempScenePath;
|
||
|
[SerializeField]
|
||
|
int m_TestCounter;
|
||
|
[SerializeField]
|
||
|
GameObject m_MainInstance;
|
||
|
[SerializeField]
|
||
|
GameObject m_SecondInstance;
|
||
|
|
||
|
#if KEEP_ARTIFACTS_FOR_INSPECTION
|
||
|
const bool k_KeepSceneObjects = true;
|
||
|
#else
|
||
|
const bool k_KeepSceneObjects = false;
|
||
|
#endif
|
||
|
[OneTimeSetUp]
|
||
|
public void OneTimeSetup()
|
||
|
{
|
||
|
// Skip the entire setup phase that runs again each time an editor test enters playmode
|
||
|
if (EditorApplication.isPlaying)
|
||
|
return;
|
||
|
|
||
|
AssetDatabase.DeleteAsset(k_TempFolder);
|
||
|
var folderGUID = AssetDatabase.CreateFolder(k_ParentFolder, k_TempFolderName);
|
||
|
Assume.That(folderGUID, Is.Not.Empty);
|
||
|
|
||
|
SessionState.SetBool(k_AutoSaveKey, PrefabStageAutoSavingUtil.GetPrefabStageAutoSave());
|
||
|
PrefabStageAutoSavingUtil.SetPrefabStageAutoSave(false);
|
||
|
StageUtility.GoToMainStage();
|
||
|
|
||
|
m_PreviousScenePath = SceneManager.GetActiveScene().path;
|
||
|
m_TempScenePath = Path.Combine(k_TempFolder, "NavMeshSurfacePrefabTestsScene.unity");
|
||
|
var tempScene = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single);
|
||
|
EditorSceneManager.SaveScene(tempScene, m_TempScenePath);
|
||
|
EditorSceneManager.OpenScene(m_TempScenePath);
|
||
|
|
||
|
s_EnterPlayModeOptionsEnabled = EditorSettings.enterPlayModeOptionsEnabled;
|
||
|
s_EnterPlayModeOptions = EditorSettings.enterPlayModeOptions;
|
||
|
|
||
|
EditorSettings.enterPlayModeOptionsEnabled = true;
|
||
|
EditorSettings.enterPlayModeOptions = EnterPlayModeOptions.DisableDomainReload | EnterPlayModeOptions.DisableSceneReload;
|
||
|
}
|
||
|
|
||
|
[OneTimeTearDown]
|
||
|
public void OneTimeTearDown()
|
||
|
{
|
||
|
if (EditorApplication.isPlaying)
|
||
|
return;
|
||
|
|
||
|
PrefabStageAutoSavingUtil.SetPrefabStageAutoSave(SessionState.GetBool(k_AutoSaveKey, PrefabStageAutoSavingUtil.GetPrefabStageAutoSave()));
|
||
|
StageUtility.GoToMainStage();
|
||
|
|
||
|
EditorSceneManager.SaveScene(SceneManager.GetActiveScene());
|
||
|
|
||
|
if (string.IsNullOrEmpty(m_PreviousScenePath))
|
||
|
{
|
||
|
EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects, NewSceneMode.Single);
|
||
|
}
|
||
|
|
||
|
EditorSettings.enterPlayModeOptionsEnabled = s_EnterPlayModeOptionsEnabled;
|
||
|
EditorSettings.enterPlayModeOptions = s_EnterPlayModeOptions;
|
||
|
|
||
|
#if !KEEP_ARTIFACTS_FOR_INSPECTION
|
||
|
AssetDatabase.DeleteAsset(k_TempFolder);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
[UnitySetUp]
|
||
|
public IEnumerator SetupNewPrefabWithNavMesh()
|
||
|
{
|
||
|
if (EditorApplication.isPlaying)
|
||
|
yield break;
|
||
|
|
||
|
var plane = GameObject.CreatePrimitive(PrimitiveType.Plane);
|
||
|
plane.name = "NavMeshSurface" + (++m_TestCounter) + "Prefab";
|
||
|
var surface = plane.AddComponent<NavMeshSurface>();
|
||
|
surface.collectObjects = CollectObjects.Children;
|
||
|
|
||
|
m_PrefabPath = Path.Combine(k_TempFolder, plane.name + ".prefab");
|
||
|
var planePrefab = PrefabUtility.SaveAsPrefabAsset(plane, m_PrefabPath);
|
||
|
Object.DestroyImmediate(plane);
|
||
|
|
||
|
AssetDatabase.OpenAsset(planePrefab);
|
||
|
var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
|
||
|
var prefabSurface = prefabStage.prefabContentsRoot.GetComponent<NavMeshSurface>();
|
||
|
yield return TestUtility.BakeNavMeshAsync(prefabSurface, k_PrefabDefaultArea);
|
||
|
PrefabSavingUtil.SavePrefab(prefabStage);
|
||
|
StageUtility.GoToMainStage();
|
||
|
|
||
|
NavMesh.RemoveAllNavMeshData();
|
||
|
|
||
|
yield return null;
|
||
|
}
|
||
|
|
||
|
[UnityTearDown]
|
||
|
public IEnumerator TearDownAndReturnToMainStage()
|
||
|
{
|
||
|
if (EditorApplication.isPlaying)
|
||
|
yield return new ExitPlayMode();
|
||
|
|
||
|
var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
|
||
|
if (prefabStage != null)
|
||
|
prefabStage.ClearDirtiness();
|
||
|
|
||
|
StageUtility.GoToMainStage();
|
||
|
|
||
|
TestUtility.EliminateFromScene(ref m_MainInstance, k_KeepSceneObjects);
|
||
|
TestUtility.EliminateFromScene(ref m_SecondInstance, k_KeepSceneObjects);
|
||
|
|
||
|
yield return null;
|
||
|
}
|
||
|
|
||
|
static void TestNavMeshExistsAloneAtPosition(int expectedArea, Vector3 pos)
|
||
|
{
|
||
|
var expectedAreaMask = 1 << expectedArea;
|
||
|
|
||
|
#if ENABLE_TEST_LOGS
|
||
|
var areaExists = HasNavMeshAtPosition(pos, expectedAreaMask);
|
||
|
var otherAreasExist = HasNavMeshAtPosition(pos, ~expectedAreaMask);
|
||
|
Debug.Log(" mask=" + expectedAreaMask.ToString("x8") + " area " + expectedArea +
|
||
|
" Exists=" + areaExists + " otherAreasExist=" + otherAreasExist + " at position " + pos);
|
||
|
if (otherAreasExist)
|
||
|
{
|
||
|
for (var i = 0; i < 32; i++)
|
||
|
{
|
||
|
if (i == expectedArea)
|
||
|
continue;
|
||
|
|
||
|
var thisOtherAreaExists = HasNavMeshAtPosition(pos, 1 << i);
|
||
|
if (thisOtherAreaExists)
|
||
|
{
|
||
|
Debug.Log(" _another area that exists here " + i);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
Assert.IsTrue(HasNavMeshAtPosition(pos, expectedAreaMask), "Expected NavMesh with area {0} at position {1}.", expectedArea, pos);
|
||
|
Assert.IsFalse(HasNavMeshAtPosition(pos, ~expectedAreaMask), "A NavMesh with an area other than {0} exists at position {1}.", expectedArea, pos);
|
||
|
}
|
||
|
|
||
|
[UnityTest]
|
||
|
public IEnumerator NavMeshSurfacePrefab_WhenOpenedInPrefabMode_DoesNotActivateItsNavMesh(
|
||
|
[Values(RunMode.EditMode, RunMode.PlayMode)]
|
||
|
RunMode runMode)
|
||
|
{
|
||
|
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(m_PrefabPath);
|
||
|
AssetDatabase.OpenAsset(prefab);
|
||
|
|
||
|
if (runMode == RunMode.PlayMode)
|
||
|
yield return new EnterPlayMode();
|
||
|
|
||
|
NavMesh.SamplePosition(Vector3.zero, out var hit, 1000000f, new NavMeshQueryFilter { areaMask = NavMesh.AllAreas, agentTypeID = 0 });
|
||
|
Assert.That(hit.hit, Is.False, "The NavMesh instance of a prefab opened for edit should not be active under any circumstances.");
|
||
|
|
||
|
if (EditorApplication.isPlaying)
|
||
|
yield return new ExitPlayMode();
|
||
|
|
||
|
yield return null;
|
||
|
}
|
||
|
|
||
|
[UnityTest]
|
||
|
public IEnumerator NavMeshSurfacePrefab_AfterBakingInPrefabMode_DoesNotActivateItsNavMesh(
|
||
|
[Values(RunMode.EditMode, RunMode.PlayMode)]
|
||
|
RunMode runMode)
|
||
|
{
|
||
|
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(m_PrefabPath);
|
||
|
AssetDatabase.OpenAsset(prefab);
|
||
|
|
||
|
if (runMode == RunMode.PlayMode)
|
||
|
yield return new EnterPlayMode();
|
||
|
|
||
|
var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
|
||
|
var prefabSurface = prefabStage.prefabContentsRoot.GetComponent<NavMeshSurface>();
|
||
|
NavMeshAssetManager.instance.ClearSurfaces(new Object[] { prefabSurface });
|
||
|
PrefabSavingUtil.SavePrefab(prefabStage);
|
||
|
|
||
|
yield return TestUtility.BakeNavMeshAsync(prefabSurface, k_RedArea);
|
||
|
|
||
|
NavMesh.SamplePosition(Vector3.zero, out var hit, 1000000f, new NavMeshQueryFilter { areaMask = NavMesh.AllAreas, agentTypeID = 0 });
|
||
|
Assert.That(hit.hit, Is.False, "The NavMesh instance of a prefab opened for edit should not be active after baking the surface.");
|
||
|
|
||
|
prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
|
||
|
PrefabSavingUtil.SavePrefab(prefabStage);
|
||
|
|
||
|
NavMesh.SamplePosition(Vector3.zero, out hit, 1000000f, new NavMeshQueryFilter { areaMask = NavMesh.AllAreas, agentTypeID = 0 });
|
||
|
Assert.That(hit.hit, Is.False, "The NavMesh instance of a prefab opened for edit should not be active after baking the surface.");
|
||
|
|
||
|
if (EditorApplication.isPlaying)
|
||
|
yield return new ExitPlayMode();
|
||
|
}
|
||
|
|
||
|
[UnityTest]
|
||
|
public IEnumerator NavMeshSurfacePrefab_AfterBakingInPrefabMode_LeavesMainSceneUntouched(
|
||
|
[Values(RunMode.EditMode, RunMode.PlayMode)]
|
||
|
RunMode runMode)
|
||
|
{
|
||
|
Assume.That(HasNavMeshAtPosition(Vector3.zero), Is.False);
|
||
|
|
||
|
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(m_PrefabPath);
|
||
|
AssetDatabase.OpenAsset(prefab);
|
||
|
|
||
|
if (runMode == RunMode.PlayMode)
|
||
|
yield return new EnterPlayMode();
|
||
|
|
||
|
var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
|
||
|
Assume.That(prefabStage, Is.Not.Null);
|
||
|
Assume.That(prefabStage.prefabContentsRoot, Is.Not.Null);
|
||
|
|
||
|
var prefabSurface = prefabStage.prefabContentsRoot.GetComponent<NavMeshSurface>();
|
||
|
var initialPrefabNavMeshData = prefabSurface.navMeshData;
|
||
|
yield return TestUtility.BakeNavMeshAsync(prefabSurface, k_RedArea);
|
||
|
|
||
|
Assert.AreNotSame(initialPrefabNavMeshData, prefabSurface.navMeshData);
|
||
|
|
||
|
PrefabSavingUtil.SavePrefab(prefabStage);
|
||
|
StageUtility.GoToMainStage();
|
||
|
|
||
|
yield return null;
|
||
|
|
||
|
Assert.IsFalse(HasNavMeshAtPosition(Vector3.zero, NavMesh.AllAreas, 0, 1000.0f));
|
||
|
|
||
|
if (EditorApplication.isPlaying)
|
||
|
yield return new ExitPlayMode();
|
||
|
}
|
||
|
|
||
|
[UnityTest]
|
||
|
public IEnumerator NavMeshSurfacePrefab_WhenInstantiated_ReferencesTheSameNavMeshData(
|
||
|
[Values(RunMode.EditMode, RunMode.PlayMode)]
|
||
|
RunMode runMode)
|
||
|
{
|
||
|
if (runMode == RunMode.PlayMode)
|
||
|
yield return new EnterPlayMode();
|
||
|
|
||
|
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(m_PrefabPath);
|
||
|
m_MainInstance = TestUtility.InstantiatePrefab(prefab, "Surface" + m_TestCounter + "PrefabInstance");
|
||
|
TestNavMeshExistsAloneAtPosition(k_PrefabDefaultArea, Vector3.zero);
|
||
|
|
||
|
var instanceSurface = m_MainInstance.GetComponent<NavMeshSurface>();
|
||
|
Assume.That(instanceSurface, Is.Not.Null);
|
||
|
var instanceNavMeshData = instanceSurface.navMeshData;
|
||
|
|
||
|
var clonePosition = new Vector3(20, 0, 0);
|
||
|
m_SecondInstance = Object.Instantiate(m_MainInstance, clonePosition, Quaternion.identity);
|
||
|
Assume.That(m_SecondInstance, Is.Not.Null);
|
||
|
m_SecondInstance.name = "Surface" + m_TestCounter + "PrefabInstanceClone";
|
||
|
|
||
|
const int expectedAreaMask = 1 << k_PrefabDefaultArea;
|
||
|
Assert.IsTrue(HasNavMeshAtPosition(clonePosition, expectedAreaMask));
|
||
|
Assert.IsFalse(HasNavMeshAtPosition(clonePosition, ~expectedAreaMask));
|
||
|
|
||
|
var instanceCloneSurface = m_SecondInstance.GetComponent<NavMeshSurface>();
|
||
|
Assume.That(instanceCloneSurface, Is.Not.Null);
|
||
|
var instanceCloneNavMeshData = instanceCloneSurface.navMeshData;
|
||
|
Assert.AreSame(instanceNavMeshData, instanceCloneNavMeshData);
|
||
|
|
||
|
AssetDatabase.OpenAsset(prefab);
|
||
|
var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
|
||
|
Assume.That(prefabStage, Is.Not.Null);
|
||
|
Assume.That(prefabStage.prefabContentsRoot, Is.Not.Null);
|
||
|
|
||
|
var prefabSurface = prefabStage.prefabContentsRoot.GetComponent<NavMeshSurface>();
|
||
|
var prefabNavMeshData = prefabSurface.navMeshData;
|
||
|
Assert.AreSame(prefabNavMeshData, instanceNavMeshData);
|
||
|
|
||
|
StageUtility.GoToMainStage();
|
||
|
|
||
|
if (EditorApplication.isPlaying)
|
||
|
yield return new ExitPlayMode();
|
||
|
|
||
|
yield return null;
|
||
|
}
|
||
|
|
||
|
[UnityTest]
|
||
|
public IEnumerator NavMeshSurfacePrefab_WhenInstantiatedAndCleared_InstanceHasEmptyNavMeshData(
|
||
|
[Values(RunMode.EditMode, RunMode.PlayMode)]
|
||
|
RunMode runMode)
|
||
|
{
|
||
|
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(m_PrefabPath);
|
||
|
m_MainInstance = TestUtility.InstantiatePrefab(prefab, "Surface" + m_TestCounter + "PrefabInstance");
|
||
|
var instanceSurface = m_MainInstance.GetComponent<NavMeshSurface>();
|
||
|
Assume.That(instanceSurface.navMeshData != null, "NavMeshSurface in prefab instance must have NavMeshData.");
|
||
|
|
||
|
if (runMode == RunMode.PlayMode)
|
||
|
yield return new EnterPlayMode();
|
||
|
|
||
|
AssetDatabase.OpenAsset(prefab);
|
||
|
var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
|
||
|
var prefabSurface = prefabStage.prefabContentsRoot.GetComponent<NavMeshSurface>();
|
||
|
NavMeshAssetManager.instance.ClearSurfaces(new Object[] { prefabSurface });
|
||
|
PrefabSavingUtil.SavePrefab(prefabStage);
|
||
|
|
||
|
if (EditorApplication.isPlaying)
|
||
|
{
|
||
|
yield return new ExitPlayMode();
|
||
|
|
||
|
instanceSurface = m_MainInstance.GetComponent<NavMeshSurface>();
|
||
|
}
|
||
|
|
||
|
StageUtility.GoToMainStage();
|
||
|
Assert.IsTrue(instanceSurface.navMeshData == null,
|
||
|
"After the NavMeshSurface in the prefab has been cleared the prefab instance should no longer hold NavMeshData.");
|
||
|
const int expectedAreaMask = 1 << k_PrefabDefaultArea;
|
||
|
Assert.IsFalse(HasNavMeshAtPosition(Vector3.zero, expectedAreaMask));
|
||
|
|
||
|
yield return null;
|
||
|
}
|
||
|
|
||
|
[UnityTest]
|
||
|
public IEnumerator NavMeshSurfacePrefab_WhenBakesNewNavMesh_UpdatesTheInstance(
|
||
|
[Values(RunMode.EditMode, RunMode.PlayMode)]
|
||
|
RunMode runMode)
|
||
|
{
|
||
|
if (runMode == RunMode.PlayMode)
|
||
|
yield return new EnterPlayMode();
|
||
|
|
||
|
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(m_PrefabPath);
|
||
|
m_MainInstance = TestUtility.InstantiatePrefab(prefab, "Surface" + m_TestCounter + "PrefabInstanceOne");
|
||
|
|
||
|
TestNavMeshExistsAloneAtPosition(k_PrefabDefaultArea, m_MainInstance.transform.position);
|
||
|
|
||
|
AssetDatabase.OpenAsset(prefab);
|
||
|
TestNavMeshExistsAloneAtPosition(k_PrefabDefaultArea, m_MainInstance.transform.position);
|
||
|
|
||
|
var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
|
||
|
var prefabSurface = prefabStage.prefabContentsRoot.GetComponent<NavMeshSurface>();
|
||
|
|
||
|
yield return TestUtility.BakeNavMeshAsync(prefabSurface, k_RedArea);
|
||
|
|
||
|
TestNavMeshExistsAloneAtPosition(k_PrefabDefaultArea, m_MainInstance.transform.position);
|
||
|
|
||
|
PrefabSavingUtil.SavePrefab(prefabStage);
|
||
|
|
||
|
StageUtility.GoToMainStage();
|
||
|
|
||
|
m_SecondInstance = TestUtility.InstantiatePrefab(prefab, "Surface" + m_TestCounter + "PrefabInstanceTwo");
|
||
|
|
||
|
// Reactivate the object to apply the change of position immediately
|
||
|
m_SecondInstance.SetActive(false);
|
||
|
m_SecondInstance.transform.position = new Vector3(20, 0, 0);
|
||
|
m_SecondInstance.SetActive(true);
|
||
|
|
||
|
// Check that the second prefab instance has the new prefab area type
|
||
|
TestNavMeshExistsAloneAtPosition(k_RedArea, m_SecondInstance.transform.position);
|
||
|
|
||
|
// Only in edit mode, check that the prefab change has been picked up by the first instance
|
||
|
if (!EditorApplication.isPlaying)
|
||
|
{
|
||
|
TestNavMeshExistsAloneAtPosition(k_RedArea, m_MainInstance.transform.position);
|
||
|
|
||
|
// Modify the first instance
|
||
|
var instanceOneSurface = m_MainInstance.GetComponent<NavMeshSurface>();
|
||
|
yield return TestUtility.BakeNavMeshAsync(instanceOneSurface, k_BrownArea);
|
||
|
|
||
|
// Check that the first prefab instance kept its modified area type
|
||
|
TestNavMeshExistsAloneAtPosition(k_BrownArea, m_MainInstance.transform.position);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// After the prefab has been saved the running prefab instance should still have the old NavMeshData
|
||
|
TestNavMeshExistsAloneAtPosition(k_PrefabDefaultArea, m_MainInstance.transform.position);
|
||
|
}
|
||
|
|
||
|
if (EditorApplication.isPlaying)
|
||
|
yield return new ExitPlayMode();
|
||
|
|
||
|
yield return null;
|
||
|
}
|
||
|
|
||
|
[UnityTest]
|
||
|
public IEnumerator NavMeshSurfacePrefab_WhenInstanceRebaked_HasDifferentNavMeshData(
|
||
|
[Values(RunMode.EditMode, RunMode.PlayMode)]
|
||
|
RunMode runMode)
|
||
|
{
|
||
|
if (runMode == RunMode.PlayMode)
|
||
|
yield return new EnterPlayMode();
|
||
|
|
||
|
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(m_PrefabPath);
|
||
|
m_MainInstance = TestUtility.InstantiatePrefab(prefab, "Surface" + m_TestCounter + "PrefabInstance");
|
||
|
|
||
|
var clonePosition = new Vector3(20, 0, 0);
|
||
|
m_SecondInstance = Object.Instantiate(m_MainInstance, clonePosition, Quaternion.identity);
|
||
|
Assume.That(m_SecondInstance, Is.Not.Null);
|
||
|
m_SecondInstance.name = "Surface" + m_TestCounter + "PrefabInstanceClone";
|
||
|
|
||
|
var mainSurface = m_MainInstance.GetComponent<NavMeshSurface>();
|
||
|
Assume.That(mainSurface, Is.Not.Null);
|
||
|
yield return TestUtility.BakeNavMeshAsync(mainSurface, k_RedArea);
|
||
|
var mainNavMeshData = mainSurface.navMeshData;
|
||
|
|
||
|
TestNavMeshExistsAloneAtPosition(k_RedArea, m_MainInstance.transform.position);
|
||
|
|
||
|
// For when multiple instances of the same NavMesh prefab modify their data in playmode the behavior is currently undefined
|
||
|
if (runMode != RunMode.PlayMode)
|
||
|
{
|
||
|
var cloneSurface = m_SecondInstance.GetComponent<NavMeshSurface>();
|
||
|
|
||
|
Assert.IsTrue(cloneSurface.navMeshData != null, "The clone should still have NavMesh data.");
|
||
|
|
||
|
const int expectedAreaMask = 1 << k_PrefabDefaultArea;
|
||
|
Assert.IsTrue(HasNavMeshAtPosition(clonePosition, expectedAreaMask), "The clone should still reference the prefab's data.");
|
||
|
Assert.IsFalse(HasNavMeshAtPosition(clonePosition, ~expectedAreaMask));
|
||
|
}
|
||
|
|
||
|
AssetDatabase.OpenAsset(prefab);
|
||
|
var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
|
||
|
var prefabSurface = prefabStage.prefabContentsRoot.GetComponent<NavMeshSurface>();
|
||
|
var prefabNavMeshData = prefabSurface.navMeshData;
|
||
|
Assert.AreNotSame(mainNavMeshData, prefabNavMeshData);
|
||
|
|
||
|
if (runMode != RunMode.PlayMode)
|
||
|
{
|
||
|
var instanceCloneSurface = m_SecondInstance.GetComponent<NavMeshSurface>();
|
||
|
Assume.That(instanceCloneSurface, Is.Not.Null);
|
||
|
var instanceCloneNavMeshData = instanceCloneSurface.navMeshData;
|
||
|
Assert.AreNotSame(instanceCloneNavMeshData, mainNavMeshData);
|
||
|
Assert.That(instanceCloneNavMeshData, Is.EqualTo(prefabNavMeshData));
|
||
|
}
|
||
|
|
||
|
StageUtility.GoToMainStage();
|
||
|
|
||
|
if (EditorApplication.isPlaying)
|
||
|
yield return new ExitPlayMode();
|
||
|
|
||
|
yield return null;
|
||
|
}
|
||
|
|
||
|
[UnityTest]
|
||
|
public IEnumerator NavMeshSurfacePrefab_WhenInstanceCleared_InstanceHasEmptyNavMeshData()
|
||
|
{
|
||
|
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(m_PrefabPath);
|
||
|
m_MainInstance = TestUtility.InstantiatePrefab(prefab, "Surface" + m_TestCounter + "PrefabInstance");
|
||
|
|
||
|
var clonePosition = new Vector3(20, 0, 0);
|
||
|
m_SecondInstance = Object.Instantiate(m_MainInstance, clonePosition, Quaternion.identity);
|
||
|
Assume.That(m_SecondInstance, Is.Not.Null);
|
||
|
m_SecondInstance.name = "Surface" + m_TestCounter + "PrefabInstanceClone";
|
||
|
|
||
|
var instanceSurface = m_MainInstance.GetComponent<NavMeshSurface>();
|
||
|
Assume.That(instanceSurface, Is.Not.Null);
|
||
|
NavMeshAssetManager.instance.ClearSurfaces(new Object[] { instanceSurface });
|
||
|
|
||
|
const int expectedAreaMask = 1 << k_PrefabDefaultArea;
|
||
|
Assert.IsFalse(HasNavMeshAtPosition(Vector3.zero, expectedAreaMask));
|
||
|
|
||
|
Assert.IsTrue(HasNavMeshAtPosition(clonePosition, expectedAreaMask));
|
||
|
Assert.IsFalse(HasNavMeshAtPosition(clonePosition, ~expectedAreaMask));
|
||
|
|
||
|
var instanceCloneSurface = m_SecondInstance.GetComponent<NavMeshSurface>();
|
||
|
Assume.That(instanceCloneSurface, Is.Not.Null);
|
||
|
var instanceCloneNavMeshData = instanceCloneSurface.navMeshData;
|
||
|
|
||
|
AssetDatabase.OpenAsset(prefab);
|
||
|
var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
|
||
|
var prefabSurface = prefabStage.prefabContentsRoot.GetComponent<NavMeshSurface>();
|
||
|
var prefabNavMeshData = prefabSurface.navMeshData;
|
||
|
Assert.AreNotSame(prefabNavMeshData, instanceSurface.navMeshData);
|
||
|
Assert.AreNotSame(instanceCloneNavMeshData, instanceSurface.navMeshData);
|
||
|
Assert.AreSame(prefabNavMeshData, instanceCloneNavMeshData);
|
||
|
|
||
|
StageUtility.GoToMainStage();
|
||
|
|
||
|
yield return null;
|
||
|
}
|
||
|
|
||
|
[UnityTest]
|
||
|
public IEnumerator NavMeshSurfacePrefab_WhenInstanceCleared_PrefabKeepsNavMeshData()
|
||
|
{
|
||
|
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(m_PrefabPath);
|
||
|
m_MainInstance = TestUtility.InstantiatePrefab(prefab, "Surface" + m_TestCounter + "PrefabInstance");
|
||
|
|
||
|
var instanceSurface = m_MainInstance.GetComponent<NavMeshSurface>();
|
||
|
Assume.That(instanceSurface, Is.Not.Null);
|
||
|
var initialPrefabNavMeshData = instanceSurface.navMeshData;
|
||
|
NavMeshAssetManager.instance.ClearSurfaces(new Object[] { instanceSurface });
|
||
|
|
||
|
const int expectedAreaMask = 1 << k_PrefabDefaultArea;
|
||
|
Assert.IsFalse(HasNavMeshAtPosition(Vector3.zero, expectedAreaMask));
|
||
|
|
||
|
AssetDatabase.OpenAsset(prefab);
|
||
|
var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
|
||
|
var prefabSurface = prefabStage.prefabContentsRoot.GetComponent<NavMeshSurface>();
|
||
|
var prefabNavMeshData = prefabSurface.navMeshData;
|
||
|
Assert.IsTrue(prefabNavMeshData != null,
|
||
|
"NavMeshSurface in the prefab must still have NavMeshData even though the instance was cleared.");
|
||
|
Assert.AreSame(initialPrefabNavMeshData, prefabNavMeshData);
|
||
|
|
||
|
StageUtility.GoToMainStage();
|
||
|
|
||
|
yield return null;
|
||
|
}
|
||
|
|
||
|
[UnityTest]
|
||
|
public IEnumerator NavMeshSurfacePrefab_WhenRebakedButInstanceModified_DoesNotChangeDataReferencedByInstance(
|
||
|
[Values(RunMode.EditMode, RunMode.PlayMode)]
|
||
|
RunMode runMode)
|
||
|
{
|
||
|
if (runMode == RunMode.PlayMode)
|
||
|
yield return new EnterPlayMode();
|
||
|
|
||
|
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(m_PrefabPath);
|
||
|
m_MainInstance = TestUtility.InstantiatePrefab(prefab, "Surface" + m_TestCounter + "PrefabInstance");
|
||
|
|
||
|
var instanceSurface = m_MainInstance.GetComponent<NavMeshSurface>();
|
||
|
Assume.That(instanceSurface, Is.Not.Null);
|
||
|
yield return TestUtility.BakeNavMeshAsync(instanceSurface, k_RedArea);
|
||
|
var instanceNavMeshData = instanceSurface.navMeshData;
|
||
|
|
||
|
TestNavMeshExistsAloneAtPosition(k_RedArea, Vector3.zero);
|
||
|
|
||
|
AssetDatabase.OpenAsset(prefab);
|
||
|
var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
|
||
|
var prefabSurface = prefabStage.prefabContentsRoot.GetComponent<NavMeshSurface>();
|
||
|
var initialPrefabNavMeshData = prefabSurface.navMeshData;
|
||
|
yield return TestUtility.BakeNavMeshAsync(prefabSurface, k_GrayArea);
|
||
|
PrefabSavingUtil.SavePrefab(prefabStage);
|
||
|
StageUtility.GoToMainStage();
|
||
|
|
||
|
AssetDatabase.OpenAsset(prefab);
|
||
|
var prefabStageReopened = PrefabStageUtility.GetCurrentPrefabStage();
|
||
|
var prefabSurfaceReopened = prefabStageReopened.prefabContentsRoot.GetComponent<NavMeshSurface>();
|
||
|
var prefabNavMeshData = prefabSurfaceReopened.navMeshData;
|
||
|
Assert.IsTrue(prefabNavMeshData != null,
|
||
|
"NavMeshSurface in prefab must have NavMeshData after baking, saving, closing and reopening.");
|
||
|
Assert.AreNotSame(instanceNavMeshData, prefabNavMeshData);
|
||
|
Assert.AreNotSame(initialPrefabNavMeshData, prefabNavMeshData);
|
||
|
|
||
|
StageUtility.GoToMainStage();
|
||
|
Assert.AreSame(instanceNavMeshData, instanceSurface.navMeshData);
|
||
|
|
||
|
if (EditorApplication.isPlaying)
|
||
|
yield return new ExitPlayMode();
|
||
|
|
||
|
yield return null;
|
||
|
}
|
||
|
|
||
|
[UnityTest]
|
||
|
public IEnumerator NavMeshSurfacePrefab_WhenRebakedButNotSaved_RevertsToTheInitialNavMeshData()
|
||
|
{
|
||
|
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(m_PrefabPath);
|
||
|
AssetDatabase.OpenAsset(prefab);
|
||
|
var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
|
||
|
var prefabSurface = prefabStage.prefabContentsRoot.GetComponent<NavMeshSurface>();
|
||
|
var initialPrefabNavMeshData = prefabSurface.navMeshData;
|
||
|
var initialPrefabNavMeshAssetPath = AssetDatabase.GetAssetPath(initialPrefabNavMeshData);
|
||
|
yield return TestUtility.BakeNavMeshAsync(prefabSurface, k_GrayArea);
|
||
|
var rebuiltPrefabNavMeshData = prefabSurface.navMeshData;
|
||
|
Assert.IsTrue(rebuiltPrefabNavMeshData != null, "NavMeshSurface must have NavMeshData after baking.");
|
||
|
Assert.AreNotSame(initialPrefabNavMeshData, rebuiltPrefabNavMeshData);
|
||
|
|
||
|
prefabStage.ClearDirtiness();
|
||
|
StageUtility.GoToMainStage();
|
||
|
|
||
|
AssetDatabase.OpenAsset(prefab);
|
||
|
var prefabStageReopened = PrefabStageUtility.GetCurrentPrefabStage();
|
||
|
var prefabSurfaceReopened = prefabStageReopened.prefabContentsRoot.GetComponent<NavMeshSurface>();
|
||
|
var prefabNavMeshData = prefabSurfaceReopened.navMeshData;
|
||
|
Assert.AreSame(initialPrefabNavMeshData, prefabNavMeshData);
|
||
|
Assert.AreNotSame(rebuiltPrefabNavMeshData, prefabNavMeshData);
|
||
|
var prefabNavMeshAssetPath = AssetDatabase.GetAssetPath(prefabNavMeshData);
|
||
|
StringAssert.AreEqualIgnoringCase(initialPrefabNavMeshAssetPath, prefabNavMeshAssetPath,
|
||
|
"The NavMeshData asset referenced by the prefab should remain the same when exiting prefab mode without saving.");
|
||
|
|
||
|
StageUtility.GoToMainStage();
|
||
|
|
||
|
yield return null;
|
||
|
}
|
||
|
|
||
|
[UnityTest]
|
||
|
public IEnumerator NavMeshSurfacePrefab_WhenRebakedButNotSaved_TheRebakedAssetNoLongerExists()
|
||
|
{
|
||
|
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(m_PrefabPath);
|
||
|
AssetDatabase.OpenAsset(prefab);
|
||
|
var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
|
||
|
var prefabSurface = prefabStage.prefabContentsRoot.GetComponent<NavMeshSurface>();
|
||
|
yield return TestUtility.BakeNavMeshAsync(prefabSurface, k_GrayArea);
|
||
|
var rebakedAssetPath = AssetDatabase.GetAssetPath(prefabSurface.navMeshData);
|
||
|
|
||
|
Assert.IsTrue(File.Exists(rebakedAssetPath), "NavMeshData file must exist. ({0})", rebakedAssetPath);
|
||
|
|
||
|
prefabStage.ClearDirtiness();
|
||
|
StageUtility.GoToMainStage();
|
||
|
|
||
|
Assert.IsFalse(File.Exists(rebakedAssetPath), "NavMeshData file still exists after discarding the changes. ({0})", rebakedAssetPath);
|
||
|
|
||
|
yield return null;
|
||
|
}
|
||
|
|
||
|
[UnityTest]
|
||
|
public IEnumerator NavMeshSurfacePrefab_WhenRebaked_TheOldAssetExistsUntilSavingAndNotAfter()
|
||
|
{
|
||
|
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(m_PrefabPath);
|
||
|
AssetDatabase.OpenAsset(prefab);
|
||
|
var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
|
||
|
var prefabSurface = prefabStage.prefabContentsRoot.GetComponent<NavMeshSurface>();
|
||
|
var initialNavMeshData = prefabSurface.navMeshData;
|
||
|
var initialAssetPath = AssetDatabase.GetAssetPath(prefabSurface.navMeshData);
|
||
|
|
||
|
Assume.That(initialNavMeshData != null, "Prefab must have some NavMeshData.");
|
||
|
Assume.That(File.Exists(initialAssetPath), Is.True, "NavMeshData file must exist. ({0})", initialAssetPath);
|
||
|
|
||
|
yield return TestUtility.BakeNavMeshAsync(prefabSurface, k_GrayArea);
|
||
|
|
||
|
Assert.IsTrue(initialNavMeshData != null, "The initial NavMeshData must still exist immediately after prefab re-bake.");
|
||
|
Assert.IsTrue(File.Exists(initialAssetPath), "The initial NavMeshData file must exist after prefab re-bake. ({0})", initialAssetPath);
|
||
|
|
||
|
Assert.IsTrue(prefabSurface.navMeshData != null, "NavMeshSurface must have NavMeshData after baking.");
|
||
|
var unsavedRebakedNavMeshData = prefabSurface.navMeshData;
|
||
|
|
||
|
yield return TestUtility.BakeNavMeshAsync(prefabSurface, k_OrangeArea);
|
||
|
|
||
|
// Assert.IsNull would return a wrong result here (e.g. Expected: null But was: <null>)
|
||
|
Assert.IsTrue(unsavedRebakedNavMeshData == null,"An unsaved NavMeshData should not exist after a re-bake.");
|
||
|
Assert.IsTrue(prefabSurface.navMeshData != null, "NavMeshSurface must have NavMeshData after baking.");
|
||
|
|
||
|
PrefabSavingUtil.SavePrefab(prefabStage);
|
||
|
Assert.IsFalse(File.Exists(initialAssetPath), "NavMeshData file still exists after saving. ({0})", initialAssetPath);
|
||
|
Assert.IsTrue(initialNavMeshData == null, "The initial NavMeshData must no longer exist after saving the prefab.");
|
||
|
|
||
|
// This code is still reachable because initialNavMeshData has been affected by BakeNavMeshAsync()
|
||
|
StageUtility.GoToMainStage();
|
||
|
|
||
|
yield return null;
|
||
|
}
|
||
|
|
||
|
[UnityTest]
|
||
|
public IEnumerator NavMeshSurfacePrefab_WhenRebakedAndAutoSaved_InstanceHasTheNewNavMeshData()
|
||
|
{
|
||
|
var wasAutoSave = PrefabStageAutoSavingUtil.GetPrefabStageAutoSave();
|
||
|
PrefabStageAutoSavingUtil.SetPrefabStageAutoSave(true);
|
||
|
|
||
|
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(m_PrefabPath);
|
||
|
AssetDatabase.OpenAsset(prefab);
|
||
|
var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
|
||
|
var prefabSurface = prefabStage.prefabContentsRoot.GetComponent<NavMeshSurface>();
|
||
|
var initialPrefabNavMeshData = prefabSurface.navMeshData;
|
||
|
yield return TestUtility.BakeNavMeshAsync(prefabSurface, k_GrayArea);
|
||
|
var rebuiltPrefabNavMeshData = prefabSurface.navMeshData;
|
||
|
Assert.IsTrue(rebuiltPrefabNavMeshData != null, "NavMeshSurface must have NavMeshData after baking.");
|
||
|
Assert.AreNotSame(initialPrefabNavMeshData, rebuiltPrefabNavMeshData);
|
||
|
|
||
|
StageUtility.GoToMainStage();
|
||
|
|
||
|
AssetDatabase.OpenAsset(prefab);
|
||
|
var prefabStageReopened = PrefabStageUtility.GetCurrentPrefabStage();
|
||
|
var prefabSurfaceReopened = prefabStageReopened.prefabContentsRoot.GetComponent<NavMeshSurface>();
|
||
|
var prefabNavMeshData = prefabSurfaceReopened.navMeshData;
|
||
|
Assert.AreNotSame(initialPrefabNavMeshData, prefabNavMeshData);
|
||
|
Assert.AreSame(rebuiltPrefabNavMeshData, prefabNavMeshData);
|
||
|
|
||
|
StageUtility.GoToMainStage();
|
||
|
|
||
|
PrefabStageAutoSavingUtil.SetPrefabStageAutoSave(wasAutoSave);
|
||
|
|
||
|
yield return null;
|
||
|
}
|
||
|
|
||
|
[Ignore("Currently the deletion of the old asset must be done manually.")]
|
||
|
[UnityTest]
|
||
|
public IEnumerator NavMeshSurfacePrefab_AfterModifiedInstanceAppliedBack_TheOldAssetNoLongerExists()
|
||
|
{
|
||
|
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(m_PrefabPath);
|
||
|
m_MainInstance = TestUtility.InstantiatePrefab(prefab, "Surface" + m_TestCounter + "PrefabInstance");
|
||
|
TestNavMeshExistsAloneAtPosition(k_PrefabDefaultArea, Vector3.zero);
|
||
|
|
||
|
var instanceSurface = m_MainInstance.GetComponent<NavMeshSurface>();
|
||
|
Assume.That(instanceSurface, Is.Not.Null);
|
||
|
|
||
|
var initialInstanceAssetPath = AssetDatabase.GetAssetPath(instanceSurface.navMeshData);
|
||
|
|
||
|
Assert.IsTrue(File.Exists(initialInstanceAssetPath), "Prefab's NavMeshData file must exist. ({0})", initialInstanceAssetPath);
|
||
|
|
||
|
yield return TestUtility.BakeNavMeshAsync(instanceSurface, k_RedArea);
|
||
|
|
||
|
Assert.IsTrue(File.Exists(initialInstanceAssetPath),
|
||
|
"Prefab's NavMeshData file exists after the instance has changed. ({0})", initialInstanceAssetPath);
|
||
|
|
||
|
PrefabUtility.ApplyPrefabInstance(m_MainInstance, InteractionMode.AutomatedAction);
|
||
|
|
||
|
Assert.IsFalse(File.Exists(initialInstanceAssetPath),
|
||
|
"Prefab's NavMeshData file still exists after the changes from the instance have been applied back to the prefab. ({0})",
|
||
|
initialInstanceAssetPath);
|
||
|
|
||
|
yield return null;
|
||
|
}
|
||
|
|
||
|
[UnityTest]
|
||
|
public IEnumerator NavMeshSurfacePrefab_AfterModifiedInstanceAppliedBack_UpdatedAccordingToInstance()
|
||
|
{
|
||
|
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(m_PrefabPath);
|
||
|
m_MainInstance = TestUtility.InstantiatePrefab(prefab, "Surface" + m_TestCounter + "PrefabInstanceOne");
|
||
|
TestNavMeshExistsAloneAtPosition(k_PrefabDefaultArea, Vector3.zero);
|
||
|
|
||
|
m_SecondInstance = TestUtility.InstantiatePrefab(prefab, "Surface" + m_TestCounter + "PrefabInstanceTwo");
|
||
|
|
||
|
// reactivate the object to apply the change of position immediately
|
||
|
m_SecondInstance.SetActive(false);
|
||
|
m_SecondInstance.transform.position = new Vector3(20, 0, 0);
|
||
|
m_SecondInstance.SetActive(true);
|
||
|
|
||
|
var instanceOneSurface = m_MainInstance.GetComponent<NavMeshSurface>();
|
||
|
Assume.That(instanceOneSurface, Is.Not.Null);
|
||
|
|
||
|
yield return TestUtility.BakeNavMeshAsync(instanceOneSurface, k_RedArea);
|
||
|
|
||
|
TestNavMeshExistsAloneAtPosition(k_RedArea, Vector3.zero);
|
||
|
TestNavMeshExistsAloneAtPosition(k_PrefabDefaultArea, m_SecondInstance.transform.position);
|
||
|
|
||
|
PrefabUtility.ApplyPrefabInstance(m_MainInstance, InteractionMode.AutomatedAction);
|
||
|
|
||
|
TestNavMeshExistsAloneAtPosition(k_RedArea, m_SecondInstance.transform.position);
|
||
|
|
||
|
AssetDatabase.OpenAsset(prefab);
|
||
|
var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
|
||
|
var prefabSurface = prefabStage.prefabContentsRoot.GetComponent<NavMeshSurface>();
|
||
|
yield return TestUtility.BakeNavMeshAsync(prefabSurface, k_GrayArea);
|
||
|
PrefabSavingUtil.SavePrefab(prefabStage);
|
||
|
StageUtility.GoToMainStage();
|
||
|
|
||
|
TestNavMeshExistsAloneAtPosition(k_GrayArea, Vector3.zero);
|
||
|
TestNavMeshExistsAloneAtPosition(k_GrayArea, m_SecondInstance.transform.position);
|
||
|
|
||
|
yield return null;
|
||
|
}
|
||
|
|
||
|
[UnityTest]
|
||
|
public IEnumerator NavMeshSurfacePrefab_AfterClearedInstanceAppliedBack_HasEmptyData()
|
||
|
{
|
||
|
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(m_PrefabPath);
|
||
|
m_MainInstance = TestUtility.InstantiatePrefab(prefab, "Surface" + m_TestCounter + "PrefabInstance");
|
||
|
TestNavMeshExistsAloneAtPosition(k_PrefabDefaultArea, Vector3.zero);
|
||
|
|
||
|
var instanceSurface = m_MainInstance.GetComponent<NavMeshSurface>();
|
||
|
Assume.That(instanceSurface, Is.Not.Null);
|
||
|
|
||
|
NavMeshAssetManager.instance.ClearSurfaces(new Object[] { instanceSurface });
|
||
|
|
||
|
const int expectedAreaMask = 1 << k_PrefabDefaultArea;
|
||
|
Assert.IsFalse(HasNavMeshAtPosition(Vector3.zero, expectedAreaMask));
|
||
|
|
||
|
PrefabUtility.ApplyPrefabInstance(m_MainInstance, InteractionMode.AutomatedAction);
|
||
|
|
||
|
AssetDatabase.OpenAsset(prefab);
|
||
|
var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
|
||
|
var prefabSurface = prefabStage.prefabContentsRoot.GetComponent<NavMeshSurface>();
|
||
|
|
||
|
Assert.IsTrue(prefabSurface.navMeshData == null,
|
||
|
"Prefab should have empty NavMeshData when empty data has been applied back from the instance.");
|
||
|
|
||
|
StageUtility.GoToMainStage();
|
||
|
|
||
|
yield return null;
|
||
|
}
|
||
|
|
||
|
[UnityTest]
|
||
|
public IEnumerator NavMeshSurfacePrefab_WhenInstanceRevertsBack_InstanceIsLikePrefab()
|
||
|
{
|
||
|
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(m_PrefabPath);
|
||
|
m_MainInstance = TestUtility.InstantiatePrefab(prefab, "Surface" + m_TestCounter + "PrefabInstance");
|
||
|
TestNavMeshExistsAloneAtPosition(k_PrefabDefaultArea, Vector3.zero);
|
||
|
|
||
|
var instanceSurface = m_MainInstance.GetComponent<NavMeshSurface>();
|
||
|
Assume.That(instanceSurface, Is.Not.Null);
|
||
|
yield return TestUtility.BakeNavMeshAsync(instanceSurface, k_RedArea);
|
||
|
|
||
|
TestNavMeshExistsAloneAtPosition(k_RedArea, Vector3.zero);
|
||
|
|
||
|
PrefabUtility.RevertPrefabInstance(m_MainInstance, InteractionMode.AutomatedAction);
|
||
|
|
||
|
TestNavMeshExistsAloneAtPosition(k_PrefabDefaultArea, Vector3.zero);
|
||
|
|
||
|
yield return null;
|
||
|
}
|
||
|
|
||
|
[Ignore("Deletion of the old asset is expected to be done manually for the time being.")]
|
||
|
[UnityTest]
|
||
|
public IEnumerator NavMeshSurfacePrefab_WhenInstanceRevertsBack_TheInstanceAssetNoLongerExists()
|
||
|
{
|
||
|
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(m_PrefabPath);
|
||
|
m_MainInstance = TestUtility.InstantiatePrefab(prefab, "Surface" + m_TestCounter + "PrefabInstance");
|
||
|
TestNavMeshExistsAloneAtPosition(k_PrefabDefaultArea, Vector3.zero);
|
||
|
|
||
|
var instanceSurface = m_MainInstance.GetComponent<NavMeshSurface>();
|
||
|
Assume.That(instanceSurface, Is.Not.Null);
|
||
|
yield return TestUtility.BakeNavMeshAsync(instanceSurface, k_RedArea);
|
||
|
|
||
|
var instanceAssetPath = AssetDatabase.GetAssetPath(instanceSurface.navMeshData);
|
||
|
|
||
|
Assert.IsTrue(File.Exists(instanceAssetPath), "Instance's NavMeshData file must exist. ({0})", instanceAssetPath);
|
||
|
|
||
|
PrefabUtility.RevertPrefabInstance(m_MainInstance, InteractionMode.AutomatedAction);
|
||
|
|
||
|
Assert.IsFalse(File.Exists(instanceAssetPath), "Instance's NavMeshData file still exists after revert. ({0})", instanceAssetPath);
|
||
|
|
||
|
yield return null;
|
||
|
}
|
||
|
|
||
|
[Ignore("The expected behaviour has not been decided.")]
|
||
|
[UnityTest]
|
||
|
public IEnumerator NavMeshSurfacePrefab_WhenDeleted_InstancesMakeCopiesOfData(
|
||
|
[Values(RunMode.EditMode, RunMode.PlayMode)]
|
||
|
RunMode runMode)
|
||
|
{
|
||
|
yield return null;
|
||
|
Assert.Fail("not implemented yet");
|
||
|
}
|
||
|
|
||
|
[UnityTest]
|
||
|
public IEnumerator NavMeshSurfacePrefab_WhenBakingInPrefabModeScene_CollectsOnlyPrefabModeSceneObjects(
|
||
|
[Values(RunMode.EditMode, RunMode.PlayMode)]
|
||
|
RunMode runMode)
|
||
|
{
|
||
|
m_SecondInstance = GameObject.CreatePrimitive(PrimitiveType.Plane);
|
||
|
var goName = "MainScenePlane" + m_TestCounter;
|
||
|
m_SecondInstance.name = goName;
|
||
|
m_SecondInstance.transform.localScale = new Vector3(100, 1, 100);
|
||
|
|
||
|
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(m_PrefabPath);
|
||
|
AssetDatabase.OpenAsset(prefab);
|
||
|
|
||
|
if (runMode == RunMode.PlayMode)
|
||
|
yield return new EnterPlayMode();
|
||
|
|
||
|
var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
|
||
|
var prefabSurface = prefabStage.prefabContentsRoot.GetComponent<NavMeshSurface>();
|
||
|
|
||
|
prefabSurface.collectObjects = CollectObjects.All;
|
||
|
|
||
|
yield return TestUtility.BakeNavMeshAsync(prefabSurface, k_RedArea);
|
||
|
|
||
|
PrefabSavingUtil.SavePrefab(prefabStage);
|
||
|
StageUtility.GoToMainStage();
|
||
|
|
||
|
if (EditorApplication.isPlaying)
|
||
|
{
|
||
|
yield return new ExitPlayMode();
|
||
|
|
||
|
m_SecondInstance = GameObject.Find(goName);
|
||
|
prefab = AssetDatabase.LoadAssetAtPath<GameObject>(m_PrefabPath);
|
||
|
}
|
||
|
|
||
|
m_MainInstance = TestUtility.InstantiatePrefab(prefab, "PrefabInstance" + m_TestCounter);
|
||
|
|
||
|
TestNavMeshExistsAloneAtPosition(k_RedArea, Vector3.zero);
|
||
|
|
||
|
var posNearby = new Vector3(20, 0, 0);
|
||
|
Assert.IsFalse(HasNavMeshAtPosition(posNearby, 1 << k_RedArea),
|
||
|
"NavMesh with the prefab's area exists at position {1}, outside the prefab's plane. ({0})",
|
||
|
k_RedArea, posNearby);
|
||
|
|
||
|
yield return null;
|
||
|
}
|
||
|
|
||
|
public static bool HasNavMeshAtPosition(Vector3 pos, int areaMask = NavMesh.AllAreas, int agentTypeId = 0, float range = 0.1f)
|
||
|
{
|
||
|
var filter = new NavMeshQueryFilter
|
||
|
{
|
||
|
areaMask = areaMask,
|
||
|
agentTypeID = agentTypeId
|
||
|
};
|
||
|
var result = NavMesh.SamplePosition(pos, out _, range, filter);
|
||
|
return result;
|
||
|
}
|
||
|
}
|
||
|
}
|