init
This commit is contained in:
commit
341a877b4a
2338 changed files with 1346408 additions and 0 deletions
8
Assets/NavMesh/Tests/Editor.meta
Normal file
8
Assets/NavMesh/Tests/Editor.meta
Normal file
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 276ab4071255d9f49931e6a8373248e1
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"name": "NavMeshComponentsTestsEditmode",
|
||||
"references": [
|
||||
"NavMeshComponents",
|
||||
"NavMeshComponentsEditor"
|
||||
],
|
||||
"optionalUnityReferences": [
|
||||
"TestAssemblies"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": []
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 794824b4a8f003f47a92875e8342f790
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,233 @@
|
|||
//#define KEEP_ARTIFACTS_FOR_INSPECTION
|
||||
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools;
|
||||
using NUnit.Framework;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEditor.AI;
|
||||
using UnityEditor.Experimental.SceneManagement;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEngine.AI;
|
||||
using UnityEngine.SceneManagement;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
[Category("PrefabsWithNavMeshModifierVolume")]
|
||||
public class NavMeshModifierVolumeInPrefabTests
|
||||
{
|
||||
const string k_AutoSaveKey = "AutoSave";
|
||||
const string k_ParentFolder = "Assets/Tests/Editor";
|
||||
const string k_TempFolderName = "TempPrefabAndModifiers";
|
||||
string m_TempFolder = k_ParentFolder + "/" + k_TempFolderName;
|
||||
string m_PrefabPath;
|
||||
string m_PreviousScenePath;
|
||||
string m_TempScenePath;
|
||||
int m_TestCounter;
|
||||
|
||||
const int k_PinkArea = 3;
|
||||
const int k_GreenArea = 4;
|
||||
const int k_RedArea = 18;
|
||||
|
||||
const int k_PrefabDefaultArea = k_GreenArea;
|
||||
|
||||
[OneTimeSetUp]
|
||||
public void OneTimeSetup()
|
||||
{
|
||||
AssetDatabase.DeleteAsset(m_TempFolder);
|
||||
|
||||
var folderGUID = AssetDatabase.CreateFolder(k_ParentFolder, k_TempFolderName);
|
||||
m_TempFolder = AssetDatabase.GUIDToAssetPath(folderGUID);
|
||||
|
||||
SessionState.SetBool(k_AutoSaveKey, PrefabStageAutoSavingUtil.GetPrefabStageAutoSave());
|
||||
PrefabStageAutoSavingUtil.SetPrefabStageAutoSave(false);
|
||||
StageUtility.GoToMainStage();
|
||||
|
||||
m_PreviousScenePath = SceneManager.GetActiveScene().path;
|
||||
m_TempScenePath = Path.Combine(m_TempFolder, "NavMeshModifierVolumePrefabTestsScene.unity");
|
||||
var tempScene = EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects, NewSceneMode.Single);
|
||||
EditorSceneManager.SaveScene(tempScene, m_TempScenePath);
|
||||
EditorSceneManager.OpenScene(m_TempScenePath);
|
||||
}
|
||||
|
||||
[OneTimeTearDown]
|
||||
public void OneTimeTearDown()
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
#if !KEEP_ARTIFACTS_FOR_INSPECTION
|
||||
AssetDatabase.DeleteAsset(m_TempFolder);
|
||||
#endif
|
||||
}
|
||||
|
||||
[UnitySetUp]
|
||||
public IEnumerator Setup()
|
||||
{
|
||||
var plane = GameObject.CreatePrimitive(PrimitiveType.Plane);
|
||||
plane.name = "SurfaceSeekingModVol" + (++m_TestCounter) + "Prefab";
|
||||
var surface = plane.AddComponent<NavMeshSurface>();
|
||||
surface.collectObjects = CollectObjects.All;
|
||||
|
||||
m_PrefabPath = Path.Combine(m_TempFolder, plane.name + ".prefab");
|
||||
PrefabUtility.SaveAsPrefabAsset(plane, m_PrefabPath);
|
||||
Object.DestroyImmediate(plane);
|
||||
|
||||
NavMesh.RemoveAllNavMeshData();
|
||||
|
||||
yield return null;
|
||||
}
|
||||
|
||||
[UnityTearDown]
|
||||
public IEnumerator TearDown()
|
||||
{
|
||||
StageUtility.GoToMainStage();
|
||||
|
||||
yield return null;
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator ModifierVolume_WhenInsidePrefabMode_ModifiesTheNavMeshInPrefab()
|
||||
{
|
||||
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(m_PrefabPath);
|
||||
var instance = PrefabUtility.InstantiatePrefab(prefab) as GameObject;
|
||||
Assert.IsNotNull(instance);
|
||||
instance.name = "SurfaceSeekingModVol" + m_TestCounter + "PrefabInstance";
|
||||
|
||||
NavMeshHit hit;
|
||||
var filter = new NavMeshQueryFilter { agentTypeID = 0, areaMask = NavMesh.AllAreas };
|
||||
NavMesh.SamplePosition(Vector3.zero, out hit, 0.1f, filter);
|
||||
Assert.That(hit.hit, Is.False, "Prefab should not have a NavMesh in the beginning.");
|
||||
|
||||
AssetDatabase.OpenAsset(prefab);
|
||||
var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
|
||||
var prefabSurface = prefabStage.prefabContentsRoot.GetComponent<NavMeshSurface>();
|
||||
var modifierVolume = prefabStage.prefabContentsRoot.AddComponent<NavMeshModifierVolume>();
|
||||
modifierVolume.area = k_RedArea;
|
||||
modifierVolume.center = Vector3.zero;
|
||||
modifierVolume.size = Vector3.one;
|
||||
yield return BakeNavMeshAsync(() => prefabSurface, k_PrefabDefaultArea);
|
||||
PrefabSavingUtil.SavePrefab(prefabStage);
|
||||
StageUtility.GoToMainStage();
|
||||
|
||||
NavMeshHit hitCenter;
|
||||
NavMesh.SamplePosition(Vector3.zero, out hitCenter, 0.1f, filter);
|
||||
Assert.That(hitCenter.hit, Is.True, "A NavMesh should have been baked in the center of the prefab.");
|
||||
Assert.That(hitCenter.mask, Is.EqualTo(1 << k_RedArea),
|
||||
"Area type (0x{0:x8}) found in the center should be 0x{1:x8}.", hitCenter.mask, 1 << k_RedArea);
|
||||
|
||||
NavMeshHit hitSides;
|
||||
NavMesh.SamplePosition(new Vector3(0.6f, 0, 0.6f), out hitSides, 0.1f, filter);
|
||||
Assert.That(hitSides.hit, Is.True, "A NavMesh should have been baked in the outer sides of the prefab.");
|
||||
Assert.That(hitSides.mask, Is.EqualTo(1 << k_PrefabDefaultArea),
|
||||
"Area type (0x{0:x8}) found on the sides should be 0x{1:x8}.", hitSides.mask, 1 << k_PrefabDefaultArea);
|
||||
|
||||
Assert.That(hitCenter.mask, Is.Not.EqualTo(hitSides.mask),
|
||||
"Area type (0x{0:x8}) in the center should be different than on the sides.", hitCenter.mask);
|
||||
|
||||
EditorSceneManager.SaveScene(SceneManager.GetActiveScene());
|
||||
|
||||
#if !KEEP_ARTIFACTS_FOR_INSPECTION
|
||||
Object.DestroyImmediate(instance);
|
||||
#endif
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator ModifierVolume_WhenInsidePrefabMode_DoesNotAffectTheNavMeshInMainScene()
|
||||
{
|
||||
var go = GameObject.CreatePrimitive(PrimitiveType.Plane);
|
||||
go.name = "SurfaceOutsidePrefab";
|
||||
var mainSceneSurface = go.AddComponent<NavMeshSurface>();
|
||||
mainSceneSurface.defaultArea = k_PinkArea;
|
||||
mainSceneSurface.agentTypeID = 0;
|
||||
mainSceneSurface.collectObjects = CollectObjects.All;
|
||||
|
||||
NavMeshHit hit;
|
||||
var filter = new NavMeshQueryFilter { agentTypeID = 0, areaMask = NavMesh.AllAreas };
|
||||
NavMesh.SamplePosition(Vector3.zero, out hit, 0.1f, filter);
|
||||
Assert.That(hit.hit, Is.False, "Prefab should not have a NavMesh in the beginning.");
|
||||
|
||||
EditorSceneManager.SaveScene(SceneManager.GetActiveScene());
|
||||
|
||||
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(m_PrefabPath);
|
||||
AssetDatabase.OpenAsset(prefab);
|
||||
var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
|
||||
var prefabModVol = prefabStage.prefabContentsRoot.AddComponent<NavMeshModifierVolume>();
|
||||
prefabModVol.area = k_PrefabDefaultArea;
|
||||
prefabModVol.center = Vector3.zero;
|
||||
prefabModVol.size = new Vector3(100, 100, 100);
|
||||
|
||||
// bake the NavMeshSurface from the main scene while the prefab mode is open
|
||||
yield return BakeNavMeshAsync(() => mainSceneSurface, mainSceneSurface.defaultArea);
|
||||
|
||||
PrefabSavingUtil.SavePrefab(prefabStage);
|
||||
EditorSceneManager.SaveScene(SceneManager.GetActiveScene());
|
||||
StageUtility.GoToMainStage();
|
||||
|
||||
NavMesh.SamplePosition(Vector3.zero, out hit, 0.1f, filter);
|
||||
Assert.That(hit.hit, Is.True, "A NavMesh should have been baked by the surface in the main scene.");
|
||||
Assert.That(hit.mask, Is.EqualTo(1 << mainSceneSurface.defaultArea),
|
||||
"NavMesh has the area type 0x{0:x8} instead of the expected 0x{1:x8}.", hit.mask, 1 << mainSceneSurface.defaultArea);
|
||||
|
||||
#if !KEEP_ARTIFACTS_FOR_INSPECTION
|
||||
Object.DestroyImmediate(go);
|
||||
#endif
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator ModifierVolume_WhenOutsidePrefabMode_DoesNotAffectTheNavMeshInPrefab()
|
||||
{
|
||||
var go = new GameObject("ModifierVolumeOutsidePrefab");
|
||||
var modifierVolume = go.AddComponent<NavMeshModifierVolume>();
|
||||
modifierVolume.area = k_RedArea;
|
||||
modifierVolume.center = Vector3.zero;
|
||||
modifierVolume.size = new Vector3(20, 20, 20);
|
||||
|
||||
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(m_PrefabPath);
|
||||
var instance = PrefabUtility.InstantiatePrefab(prefab) as GameObject;
|
||||
Assert.IsNotNull(instance);
|
||||
instance.name = "SurfaceSeekingModVol" + m_TestCounter + "PrefabInstance";
|
||||
|
||||
NavMeshHit hit;
|
||||
var filter = new NavMeshQueryFilter { agentTypeID = 0, areaMask = NavMesh.AllAreas };
|
||||
NavMesh.SamplePosition(Vector3.zero, out hit, 0.1f, filter);
|
||||
Assert.That(hit.hit, Is.False, "Prefab should not have a NavMesh in the beginning.");
|
||||
|
||||
EditorSceneManager.SaveScene(SceneManager.GetActiveScene());
|
||||
|
||||
AssetDatabase.OpenAsset(prefab);
|
||||
var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
|
||||
var prefabSurface = prefabStage.prefabContentsRoot.GetComponent<NavMeshSurface>();
|
||||
yield return BakeNavMeshAsync(() => prefabSurface, k_PrefabDefaultArea);
|
||||
PrefabSavingUtil.SavePrefab(prefabStage);
|
||||
StageUtility.GoToMainStage();
|
||||
|
||||
NavMesh.SamplePosition(Vector3.zero, out hit, 0.1f, filter);
|
||||
Assert.That(hit.hit, Is.True, "A NavMesh should have been baked in the prefab.");
|
||||
Assert.That(hit.mask, Is.EqualTo(1 << k_PrefabDefaultArea),
|
||||
"A different area type (0x{0:x8}) was found instead of the expected one (0x{1:x8}).", hit.mask, 1 << k_PrefabDefaultArea);
|
||||
|
||||
EditorSceneManager.SaveScene(SceneManager.GetActiveScene());
|
||||
|
||||
#if !KEEP_ARTIFACTS_FOR_INSPECTION
|
||||
Object.DestroyImmediate(go);
|
||||
Object.DestroyImmediate(instance);
|
||||
#endif
|
||||
}
|
||||
|
||||
static IEnumerator BakeNavMeshAsync(Func<NavMeshSurface> getSurface, int defaultArea)
|
||||
{
|
||||
var surface = getSurface();
|
||||
surface.defaultArea = defaultArea;
|
||||
NavMeshAssetManager.instance.StartBakingSurfaces(new Object[] { surface });
|
||||
yield return new WaitWhile(() => NavMeshAssetManager.instance.IsSurfaceBaking(surface));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: dd4d066d0a75d8446bc2852c3bc1d4bb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
824
Assets/NavMesh/Tests/Editor/NavMeshSurfaceInPrefabTests.cs
Normal file
824
Assets/NavMesh/Tests/Editor/NavMeshSurfaceInPrefabTests.cs
Normal file
|
@ -0,0 +1,824 @@
|
|||
//#define KEEP_ARTIFACTS_FOR_INSPECTION
|
||||
//#define ENABLE_TEST_LOGS
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using NUnit.Framework;
|
||||
using UnityEditor;
|
||||
using UnityEditor.AI;
|
||||
using UnityEditor.Experimental.SceneManagement;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AI;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEngine.TestTools;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
[Category("PrefabsWithNavMeshComponents")]
|
||||
public class NavMeshSurfaceInPrefabTests
|
||||
{
|
||||
const string k_AutoSaveKey = "AutoSave";
|
||||
const string k_ParentFolder = "Assets/Tests/Editor";
|
||||
const string k_TempFolderName = "TempPrefab";
|
||||
string m_TempFolder = k_ParentFolder + "/" + k_TempFolderName;
|
||||
string m_PrefabPath;
|
||||
string m_PreviousScenePath;
|
||||
string m_TempScenePath;
|
||||
int m_TestCounter;
|
||||
|
||||
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;
|
||||
|
||||
[OneTimeSetUp]
|
||||
public void OneTimeSetup()
|
||||
{
|
||||
AssetDatabase.DeleteAsset(m_TempFolder);
|
||||
|
||||
var folderGUID = AssetDatabase.CreateFolder(k_ParentFolder, k_TempFolderName);
|
||||
m_TempFolder = AssetDatabase.GUIDToAssetPath(folderGUID);
|
||||
|
||||
SessionState.SetBool(k_AutoSaveKey, PrefabStageAutoSavingUtil.GetPrefabStageAutoSave());
|
||||
PrefabStageAutoSavingUtil.SetPrefabStageAutoSave(false);
|
||||
StageUtility.GoToMainStage();
|
||||
|
||||
m_PreviousScenePath = SceneManager.GetActiveScene().path;
|
||||
m_TempScenePath = Path.Combine(m_TempFolder, "NavMeshSurfacePrefabTestsScene.unity");
|
||||
var tempScene = EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects, NewSceneMode.Single);
|
||||
EditorSceneManager.SaveScene(tempScene, m_TempScenePath);
|
||||
EditorSceneManager.OpenScene(m_TempScenePath);
|
||||
}
|
||||
|
||||
[OneTimeTearDown]
|
||||
public void OneTimeTearDown()
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
#if !KEEP_ARTIFACTS_FOR_INSPECTION
|
||||
AssetDatabase.DeleteAsset(m_TempFolder);
|
||||
#endif
|
||||
}
|
||||
|
||||
[UnitySetUp]
|
||||
public IEnumerator Setup()
|
||||
{
|
||||
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(m_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 BakeNavMeshAsync(() => prefabSurface, k_PrefabDefaultArea);
|
||||
PrefabSavingUtil.SavePrefab(prefabStage);
|
||||
StageUtility.GoToMainStage();
|
||||
|
||||
NavMesh.RemoveAllNavMeshData();
|
||||
|
||||
yield return null;
|
||||
}
|
||||
|
||||
[UnityTearDown]
|
||||
public IEnumerator TearDown()
|
||||
{
|
||||
var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
|
||||
if (prefabStage != null)
|
||||
prefabStage.ClearDirtiness();
|
||||
|
||||
StageUtility.GoToMainStage();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NavMeshSurfacePrefab_WhenOpenedInPrefabMode_DoesNotActivateItsNavMesh()
|
||||
{
|
||||
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(m_PrefabPath);
|
||||
AssetDatabase.OpenAsset(prefab);
|
||||
|
||||
NavMeshHit hit;
|
||||
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 under any circumstances.");
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator NavMeshSurfacePrefab_AfterBakingInPrefabMode_DoesNotActivateItsNavMesh()
|
||||
{
|
||||
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(m_PrefabPath);
|
||||
AssetDatabase.OpenAsset(prefab);
|
||||
var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
|
||||
var prefabSurface = prefabStage.prefabContentsRoot.GetComponent<NavMeshSurface>();
|
||||
NavMeshAssetManager.instance.ClearSurfaces(new Object[] { prefabSurface });
|
||||
PrefabSavingUtil.SavePrefab(prefabStage);
|
||||
|
||||
yield return BakeNavMeshAsync(() => prefabSurface, k_RedArea);
|
||||
|
||||
NavMeshHit hit;
|
||||
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.");
|
||||
|
||||
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.");
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator NavMeshSurfacePrefab_AfterBakingInPrefabMode_LeavesMainSceneUntouched()
|
||||
{
|
||||
Assert.IsFalse(HasNavMeshAtPosition(Vector3.zero));
|
||||
|
||||
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(m_PrefabPath);
|
||||
AssetDatabase.OpenAsset(prefab);
|
||||
var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
|
||||
Assert.IsNotNull(prefabStage);
|
||||
Assert.IsNotNull(prefabStage.prefabContentsRoot);
|
||||
|
||||
var prefabSurface = prefabStage.prefabContentsRoot.GetComponent<NavMeshSurface>();
|
||||
var initialPrefabNavMeshData = prefabSurface.navMeshData;
|
||||
yield return BakeNavMeshAsync(() => prefabSurface, k_RedArea);
|
||||
|
||||
Assert.AreNotSame(initialPrefabNavMeshData, prefabSurface.navMeshData);
|
||||
|
||||
PrefabSavingUtil.SavePrefab(prefabStage);
|
||||
StageUtility.GoToMainStage();
|
||||
|
||||
Assert.IsFalse(HasNavMeshAtPosition(Vector3.zero, NavMesh.AllAreas, 0, 1000.0f));
|
||||
|
||||
yield return null;
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator NavMeshSurfacePrefab_WhenInstantiated_ReferencesTheSameNavMeshData()
|
||||
{
|
||||
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(m_PrefabPath);
|
||||
var instance = PrefabUtility.InstantiatePrefab(prefab) as GameObject;
|
||||
Assert.IsNotNull(instance);
|
||||
instance.name = "Surface" + m_TestCounter + "PrefabInstance";
|
||||
TestNavMeshExistsAloneAtPosition(k_PrefabDefaultArea, Vector3.zero);
|
||||
|
||||
var instanceSurface = instance.GetComponent<NavMeshSurface>();
|
||||
Assert.IsNotNull(instanceSurface);
|
||||
var instanceNavMeshData = instanceSurface.navMeshData;
|
||||
|
||||
var clonePosition = new Vector3(20, 0, 0);
|
||||
var instanceClone = Object.Instantiate(instance, clonePosition, Quaternion.identity);
|
||||
Assert.IsNotNull(instanceClone);
|
||||
instanceClone.name = "Surface" + m_TestCounter + "PrefabInstanceClone";
|
||||
|
||||
var expectedAreaMask = 1 << k_PrefabDefaultArea;
|
||||
Assert.IsTrue(HasNavMeshAtPosition(clonePosition, expectedAreaMask));
|
||||
Assert.IsFalse(HasNavMeshAtPosition(clonePosition, ~expectedAreaMask));
|
||||
|
||||
var instanceCloneSurface = instanceClone.GetComponent<NavMeshSurface>();
|
||||
Assert.IsNotNull(instanceCloneSurface);
|
||||
var instanceCloneNavMeshData = instanceCloneSurface.navMeshData;
|
||||
|
||||
AssetDatabase.OpenAsset(prefab);
|
||||
var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
|
||||
Assert.IsNotNull(prefabStage);
|
||||
Assert.IsNotNull(prefabStage.prefabContentsRoot);
|
||||
|
||||
var prefabSurface = prefabStage.prefabContentsRoot.GetComponent<NavMeshSurface>();
|
||||
var prefabNavMeshData = prefabSurface.navMeshData;
|
||||
Assert.AreSame(prefabNavMeshData, instanceNavMeshData);
|
||||
Assert.AreSame(prefabNavMeshData, instanceCloneNavMeshData);
|
||||
|
||||
StageUtility.GoToMainStage();
|
||||
|
||||
#if !KEEP_ARTIFACTS_FOR_INSPECTION
|
||||
Object.DestroyImmediate(instance);
|
||||
Object.DestroyImmediate(instanceClone);
|
||||
#endif
|
||||
yield return null;
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator NavMeshSurfacePrefab_WhenEmptyAndInstantiated_InstanceHasEmptyNavMeshData()
|
||||
{
|
||||
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(m_PrefabPath);
|
||||
var instance = PrefabUtility.InstantiatePrefab(prefab) as GameObject;
|
||||
Assert.IsNotNull(instance);
|
||||
instance.name = "Surface" + m_TestCounter + "PrefabInstance";
|
||||
var instanceSurface = instance.GetComponent<NavMeshSurface>();
|
||||
Assert.IsTrue(instanceSurface.navMeshData != null, "NavMeshSurface in prefab instance must have NavMeshData.");
|
||||
|
||||
AssetDatabase.OpenAsset(prefab);
|
||||
var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
|
||||
var prefabSurface = prefabStage.prefabContentsRoot.GetComponent<NavMeshSurface>();
|
||||
NavMeshAssetManager.instance.ClearSurfaces(new Object[] { prefabSurface });
|
||||
PrefabSavingUtil.SavePrefab(prefabStage);
|
||||
|
||||
StageUtility.GoToMainStage();
|
||||
Assert.IsTrue(instanceSurface.navMeshData == null,
|
||||
"After the NavMeshSurface in the prefab has been cleared the prefab instance should no longer hold NavMeshData.");
|
||||
var expectedAreaMask = 1 << k_PrefabDefaultArea;
|
||||
Assert.IsFalse(HasNavMeshAtPosition(Vector3.zero, expectedAreaMask));
|
||||
|
||||
#if !KEEP_ARTIFACTS_FOR_INSPECTION
|
||||
Object.DestroyImmediate(instance);
|
||||
#endif
|
||||
yield return null;
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator NavMeshSurfacePrefab_WhenBakesNewNavMesh_UpdatesTheInstance()
|
||||
{
|
||||
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(m_PrefabPath);
|
||||
var instanceOne = PrefabUtility.InstantiatePrefab(prefab) as GameObject;
|
||||
Assert.IsNotNull(instanceOne);
|
||||
instanceOne.name = "Surface" + m_TestCounter + "PrefabInstanceOne";
|
||||
TestNavMeshExistsAloneAtPosition(k_PrefabDefaultArea, Vector3.zero);
|
||||
|
||||
AssetDatabase.OpenAsset(prefab);
|
||||
var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
|
||||
|
||||
TestNavMeshExistsAloneAtPosition(k_PrefabDefaultArea, Vector3.zero);
|
||||
var prefabSurface = prefabStage.prefabContentsRoot.GetComponent<NavMeshSurface>();
|
||||
yield return BakeNavMeshAsync(() => prefabSurface, k_RedArea);
|
||||
|
||||
PrefabSavingUtil.SavePrefab(prefabStage);
|
||||
|
||||
StageUtility.GoToMainStage();
|
||||
|
||||
TestNavMeshExistsAloneAtPosition(k_RedArea, Vector3.zero);
|
||||
|
||||
var instanceOneSurface = instanceOne.GetComponent<NavMeshSurface>();
|
||||
yield return BakeNavMeshAsync(() => instanceOneSurface, k_BrownArea);
|
||||
|
||||
var instanceTwo = PrefabUtility.InstantiatePrefab(prefab) as GameObject;
|
||||
Assert.IsNotNull(instanceTwo);
|
||||
instanceTwo.name = "Surface" + m_TestCounter + "PrefabInstanceTwo";
|
||||
// reactivate the object to apply the change of position immediately
|
||||
instanceTwo.SetActive(false);
|
||||
instanceTwo.transform.position = new Vector3(20, 0, 0);
|
||||
instanceTwo.SetActive(true);
|
||||
|
||||
TestNavMeshExistsAloneAtPosition(k_BrownArea, Vector3.zero);
|
||||
TestNavMeshExistsAloneAtPosition(k_RedArea, instanceTwo.transform.position);
|
||||
|
||||
#if !KEEP_ARTIFACTS_FOR_INSPECTION
|
||||
Object.DestroyImmediate(instanceOne);
|
||||
Object.DestroyImmediate(instanceTwo);
|
||||
#endif
|
||||
yield return null;
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator NavMeshSurfacePrefab_WhenInstanceRebaked_HasDifferentNavMeshData()
|
||||
{
|
||||
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(m_PrefabPath);
|
||||
var instance = PrefabUtility.InstantiatePrefab(prefab) as GameObject;
|
||||
Assert.IsNotNull(instance);
|
||||
instance.name = "Surface" + m_TestCounter + "PrefabInstance";
|
||||
|
||||
var clonePosition = new Vector3(20, 0, 0);
|
||||
var instanceClone = Object.Instantiate(instance, clonePosition, Quaternion.identity);
|
||||
Assert.IsNotNull(instanceClone);
|
||||
instanceClone.name = "Surface" + m_TestCounter + "PrefabInstanceClone";
|
||||
|
||||
var instanceSurface = instance.GetComponent<NavMeshSurface>();
|
||||
Assert.IsNotNull(instanceSurface);
|
||||
yield return BakeNavMeshAsync(() => instanceSurface, k_RedArea);
|
||||
var instanceNavMeshData = instanceSurface.navMeshData;
|
||||
|
||||
TestNavMeshExistsAloneAtPosition(k_RedArea, Vector3.zero);
|
||||
|
||||
var expectedAreaMask = 1 << k_PrefabDefaultArea;
|
||||
Assert.IsTrue(HasNavMeshAtPosition(clonePosition, expectedAreaMask));
|
||||
Assert.IsFalse(HasNavMeshAtPosition(clonePosition, ~expectedAreaMask));
|
||||
|
||||
var instanceCloneSurface = instanceClone.GetComponent<NavMeshSurface>();
|
||||
Assert.IsNotNull(instanceCloneSurface);
|
||||
var instanceCloneNavMeshData = instanceCloneSurface.navMeshData;
|
||||
|
||||
AssetDatabase.OpenAsset(prefab);
|
||||
var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
|
||||
var prefabSurface = prefabStage.prefabContentsRoot.GetComponent<NavMeshSurface>();
|
||||
var prefabNavMeshData = prefabSurface.navMeshData;
|
||||
Assert.AreNotSame(instanceNavMeshData, prefabNavMeshData);
|
||||
Assert.AreNotSame(instanceNavMeshData, instanceCloneNavMeshData);
|
||||
Assert.AreSame(prefabNavMeshData, instanceCloneNavMeshData);
|
||||
|
||||
StageUtility.GoToMainStage();
|
||||
|
||||
#if !KEEP_ARTIFACTS_FOR_INSPECTION
|
||||
Object.DestroyImmediate(instance);
|
||||
Object.DestroyImmediate(instanceClone);
|
||||
#endif
|
||||
yield return null;
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator NavMeshSurfacePrefab_WhenInstanceCleared_InstanceHasEmptyNavMeshData()
|
||||
{
|
||||
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(m_PrefabPath);
|
||||
var instance = PrefabUtility.InstantiatePrefab(prefab) as GameObject;
|
||||
Assert.IsNotNull(instance);
|
||||
instance.name = "Surface" + m_TestCounter + "PrefabInstance";
|
||||
|
||||
var clonePosition = new Vector3(20, 0, 0);
|
||||
var instanceClone = Object.Instantiate(instance, clonePosition, Quaternion.identity);
|
||||
Assert.IsNotNull(instanceClone);
|
||||
instanceClone.name = "Surface" + m_TestCounter + "PrefabInstanceClone";
|
||||
|
||||
var instanceSurface = instance.GetComponent<NavMeshSurface>();
|
||||
Assert.IsNotNull(instanceSurface);
|
||||
NavMeshAssetManager.instance.ClearSurfaces(new Object[] { instanceSurface });
|
||||
|
||||
var expectedAreaMask = 1 << k_PrefabDefaultArea;
|
||||
Assert.IsFalse(HasNavMeshAtPosition(Vector3.zero, expectedAreaMask));
|
||||
|
||||
Assert.IsTrue(HasNavMeshAtPosition(clonePosition, expectedAreaMask));
|
||||
Assert.IsFalse(HasNavMeshAtPosition(clonePosition, ~expectedAreaMask));
|
||||
|
||||
var instanceCloneSurface = instanceClone.GetComponent<NavMeshSurface>();
|
||||
Assert.IsNotNull(instanceCloneSurface);
|
||||
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();
|
||||
|
||||
#if !KEEP_ARTIFACTS_FOR_INSPECTION
|
||||
Object.DestroyImmediate(instance);
|
||||
Object.DestroyImmediate(instanceClone);
|
||||
#endif
|
||||
yield return null;
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator NavMeshSurfacePrefab_WhenInstanceCleared_PrefabKeepsNavMeshData()
|
||||
{
|
||||
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(m_PrefabPath);
|
||||
var instance = PrefabUtility.InstantiatePrefab(prefab) as GameObject;
|
||||
Assert.IsNotNull(instance);
|
||||
instance.name = "Surface" + m_TestCounter + "PrefabInstance";
|
||||
|
||||
var instanceSurface = instance.GetComponent<NavMeshSurface>();
|
||||
Assert.IsNotNull(instanceSurface);
|
||||
var initialPrefabNavMeshData = instanceSurface.navMeshData;
|
||||
NavMeshAssetManager.instance.ClearSurfaces(new Object[] { instanceSurface });
|
||||
|
||||
var 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();
|
||||
|
||||
#if !KEEP_ARTIFACTS_FOR_INSPECTION
|
||||
Object.DestroyImmediate(instance);
|
||||
#endif
|
||||
yield return null;
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator NavMeshSurfacePrefab_WhenRebakedButInstanceModified_DoesNotChangeInstance()
|
||||
{
|
||||
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(m_PrefabPath);
|
||||
var instance = PrefabUtility.InstantiatePrefab(prefab) as GameObject;
|
||||
Assert.IsNotNull(instance);
|
||||
instance.name = "Surface" + m_TestCounter + "PrefabInstance";
|
||||
|
||||
var instanceSurface = instance.GetComponent<NavMeshSurface>();
|
||||
Assert.IsNotNull(instanceSurface);
|
||||
yield return 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 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 !KEEP_ARTIFACTS_FOR_INSPECTION
|
||||
Object.DestroyImmediate(instance);
|
||||
#endif
|
||||
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 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 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);
|
||||
|
||||
// Assert.IsNull cannot verify correctly that an UnityEngine.Object is null
|
||||
Assert.IsTrue(initialNavMeshData != null, "Prefab must have some NavMeshData.");
|
||||
Assert.IsTrue(File.Exists(initialAssetPath), "NavMeshData file must exist. ({0})", initialAssetPath);
|
||||
|
||||
yield return 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 BakeNavMeshAsync(() => prefabSurface, k_OrangeArea);
|
||||
|
||||
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.");
|
||||
|
||||
// ReSharper disable once HeuristicUnreachableCode - initialNavMeshData is 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 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);
|
||||
var instance = PrefabUtility.InstantiatePrefab(prefab) as GameObject;
|
||||
Assert.IsNotNull(instance);
|
||||
instance.name = "Surface" + m_TestCounter + "PrefabInstance";
|
||||
TestNavMeshExistsAloneAtPosition(k_PrefabDefaultArea, Vector3.zero);
|
||||
|
||||
var instanceSurface = instance.GetComponent<NavMeshSurface>();
|
||||
Assert.IsNotNull(instanceSurface);
|
||||
|
||||
var initialInstanceAssetPath = AssetDatabase.GetAssetPath(instanceSurface.navMeshData);
|
||||
|
||||
Assert.IsTrue(File.Exists(initialInstanceAssetPath), "Prefab's NavMeshData file must exist. ({0})", initialInstanceAssetPath);
|
||||
|
||||
yield return BakeNavMeshAsync(() => instanceSurface, k_RedArea);
|
||||
|
||||
Assert.IsTrue(File.Exists(initialInstanceAssetPath),
|
||||
"Prefab's NavMeshData file exists after the instance has changed. ({0})", initialInstanceAssetPath);
|
||||
|
||||
PrefabUtility.ApplyPrefabInstance(instance, 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);
|
||||
|
||||
#if !KEEP_ARTIFACTS_FOR_INSPECTION
|
||||
Object.DestroyImmediate(instance);
|
||||
#endif
|
||||
yield return null;
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator NavMeshSurfacePrefab_AfterModifiedInstanceAppliedBack_UpdatedAccordingToInstance()
|
||||
{
|
||||
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(m_PrefabPath);
|
||||
var instanceOne = PrefabUtility.InstantiatePrefab(prefab) as GameObject;
|
||||
Assert.IsNotNull(instanceOne);
|
||||
instanceOne.name = "Surface" + m_TestCounter + "PrefabInstanceOne";
|
||||
TestNavMeshExistsAloneAtPosition(k_PrefabDefaultArea, Vector3.zero);
|
||||
|
||||
var instanceTwo = PrefabUtility.InstantiatePrefab(prefab) as GameObject;
|
||||
Assert.IsNotNull(instanceTwo);
|
||||
instanceTwo.name = "Surface" + m_TestCounter + "PrefabInstanceTwo";
|
||||
// reactivate the object to apply the change of position immediately
|
||||
instanceTwo.SetActive(false);
|
||||
instanceTwo.transform.position = new Vector3(20, 0, 0);
|
||||
instanceTwo.SetActive(true);
|
||||
|
||||
var instanceOneSurface = instanceOne.GetComponent<NavMeshSurface>();
|
||||
Assert.IsNotNull(instanceOneSurface);
|
||||
|
||||
yield return BakeNavMeshAsync(() => instanceOneSurface, k_RedArea);
|
||||
|
||||
TestNavMeshExistsAloneAtPosition(k_RedArea, Vector3.zero);
|
||||
TestNavMeshExistsAloneAtPosition(k_PrefabDefaultArea, instanceTwo.transform.position);
|
||||
|
||||
PrefabUtility.ApplyPrefabInstance(instanceOne, InteractionMode.AutomatedAction);
|
||||
|
||||
TestNavMeshExistsAloneAtPosition(k_RedArea, instanceTwo.transform.position);
|
||||
|
||||
AssetDatabase.OpenAsset(prefab);
|
||||
var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
|
||||
var prefabSurface = prefabStage.prefabContentsRoot.GetComponent<NavMeshSurface>();
|
||||
yield return BakeNavMeshAsync(() => prefabSurface, k_GrayArea);
|
||||
PrefabSavingUtil.SavePrefab(prefabStage);
|
||||
StageUtility.GoToMainStage();
|
||||
|
||||
TestNavMeshExistsAloneAtPosition(k_GrayArea, Vector3.zero);
|
||||
TestNavMeshExistsAloneAtPosition(k_GrayArea, instanceTwo.transform.position);
|
||||
|
||||
#if !KEEP_ARTIFACTS_FOR_INSPECTION
|
||||
Object.DestroyImmediate(instanceOne);
|
||||
Object.DestroyImmediate(instanceTwo);
|
||||
#endif
|
||||
yield return null;
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator NavMeshSurfacePrefab_AfterClearedInstanceAppliedBack_HasEmptyData()
|
||||
{
|
||||
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(m_PrefabPath);
|
||||
var instance = PrefabUtility.InstantiatePrefab(prefab) as GameObject;
|
||||
Assert.IsNotNull(instance);
|
||||
instance.name = "Surface" + m_TestCounter + "PrefabInstance";
|
||||
TestNavMeshExistsAloneAtPosition(k_PrefabDefaultArea, Vector3.zero);
|
||||
|
||||
var instanceSurface = instance.GetComponent<NavMeshSurface>();
|
||||
Assert.IsNotNull(instanceSurface);
|
||||
|
||||
NavMeshAssetManager.instance.ClearSurfaces(new Object[] { instanceSurface });
|
||||
|
||||
var expectedAreaMask = 1 << k_PrefabDefaultArea;
|
||||
Assert.IsFalse(HasNavMeshAtPosition(Vector3.zero, expectedAreaMask));
|
||||
|
||||
PrefabUtility.ApplyPrefabInstance(instance, 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();
|
||||
|
||||
#if !KEEP_ARTIFACTS_FOR_INSPECTION
|
||||
Object.DestroyImmediate(instance);
|
||||
#endif
|
||||
yield return null;
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator NavMeshSurfacePrefab_WhenInstanceRevertsBack_InstanceIsLikePrefab()
|
||||
{
|
||||
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(m_PrefabPath);
|
||||
var instance = PrefabUtility.InstantiatePrefab(prefab) as GameObject;
|
||||
Assert.IsNotNull(instance);
|
||||
instance.name = "Surface" + m_TestCounter + "PrefabInstance";
|
||||
TestNavMeshExistsAloneAtPosition(k_PrefabDefaultArea, Vector3.zero);
|
||||
|
||||
var instanceSurface = instance.GetComponent<NavMeshSurface>();
|
||||
Assert.IsNotNull(instanceSurface);
|
||||
yield return BakeNavMeshAsync(() => instanceSurface, k_RedArea);
|
||||
|
||||
TestNavMeshExistsAloneAtPosition(k_RedArea, Vector3.zero);
|
||||
|
||||
PrefabUtility.RevertPrefabInstance(instance, InteractionMode.AutomatedAction);
|
||||
|
||||
TestNavMeshExistsAloneAtPosition(k_PrefabDefaultArea, Vector3.zero);
|
||||
|
||||
#if !KEEP_ARTIFACTS_FOR_INSPECTION
|
||||
Object.DestroyImmediate(instance);
|
||||
#endif
|
||||
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);
|
||||
var instance = PrefabUtility.InstantiatePrefab(prefab) as GameObject;
|
||||
Assert.IsNotNull(instance);
|
||||
instance.name = "Surface" + m_TestCounter + "PrefabInstance";
|
||||
TestNavMeshExistsAloneAtPosition(k_PrefabDefaultArea, Vector3.zero);
|
||||
|
||||
var instanceSurface = instance.GetComponent<NavMeshSurface>();
|
||||
Assert.IsNotNull(instanceSurface);
|
||||
yield return 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(instance, InteractionMode.AutomatedAction);
|
||||
|
||||
Assert.IsFalse(File.Exists(instanceAssetPath), "Instance's NavMeshData file still exists after revert. ({0})", instanceAssetPath);
|
||||
|
||||
#if !KEEP_ARTIFACTS_FOR_INSPECTION
|
||||
Object.DestroyImmediate(instance);
|
||||
#endif
|
||||
yield return null;
|
||||
}
|
||||
|
||||
[Ignore("The expected behaviour has not been decided.")]
|
||||
[UnityTest]
|
||||
public IEnumerator NavMeshSurfacePrefab_WhenDeleted_InstancesMakeCopiesOfData()
|
||||
{
|
||||
yield return null;
|
||||
Assert.Fail("not implemented yet");
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator NavMeshSurfacePrefab_WhenBakingInPreviewScene_CollectsOnlyPreviewSceneObjects()
|
||||
{
|
||||
var mainScenePlane = GameObject.CreatePrimitive(PrimitiveType.Plane);
|
||||
mainScenePlane.transform.localScale = new Vector3(100, 1, 100);
|
||||
|
||||
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(m_PrefabPath);
|
||||
AssetDatabase.OpenAsset(prefab);
|
||||
var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
|
||||
var prefabSurface = prefabStage.prefabContentsRoot.GetComponent<NavMeshSurface>();
|
||||
|
||||
prefabSurface.collectObjects = CollectObjects.All;
|
||||
yield return BakeNavMeshAsync(() => prefabSurface, k_RedArea);
|
||||
|
||||
PrefabSavingUtil.SavePrefab(prefabStage);
|
||||
StageUtility.GoToMainStage();
|
||||
|
||||
var instance = PrefabUtility.InstantiatePrefab(prefab) as GameObject;
|
||||
Assert.IsNotNull(instance);
|
||||
|
||||
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);
|
||||
|
||||
#if !KEEP_ARTIFACTS_FOR_INSPECTION
|
||||
Object.DestroyImmediate(instance);
|
||||
Object.DestroyImmediate(mainScenePlane);
|
||||
#endif
|
||||
yield return null;
|
||||
}
|
||||
|
||||
public static bool HasNavMeshAtPosition(Vector3 pos, int areaMask = NavMesh.AllAreas, int agentTypeId = 0, float range = 0.1f)
|
||||
{
|
||||
NavMeshHit hit;
|
||||
var filter = new NavMeshQueryFilter
|
||||
{
|
||||
areaMask = areaMask,
|
||||
agentTypeID = agentTypeId
|
||||
};
|
||||
return NavMesh.SamplePosition(pos, out hit, range, filter);
|
||||
}
|
||||
|
||||
static IEnumerator BakeNavMeshAsync(Func<NavMeshSurface> getSurface, int defaultArea)
|
||||
{
|
||||
var surface = getSurface();
|
||||
surface.defaultArea = defaultArea;
|
||||
NavMeshAssetManager.instance.StartBakingSurfaces(new Object[] { surface });
|
||||
yield return new WaitWhile(() => NavMeshAssetManager.instance.IsSurfaceBaking(surface));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 8e570ad5b9d660a4bbeebf9f8b872eb4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,232 @@
|
|||
//#define KEEP_ARTIFACTS_FOR_INSPECTION
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using NUnit.Framework;
|
||||
using UnityEditor;
|
||||
using UnityEditor.AI;
|
||||
using UnityEditor.Experimental.SceneManagement;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AI;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEngine.TestTools;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
[Category("PrefabsWithNavMeshComponents")]
|
||||
public class NavMeshSurfaceInPrefabVariantTests
|
||||
{
|
||||
const string k_AutoSaveKey = "AutoSave";
|
||||
const string k_ParentFolder = "Assets/Tests/Editor";
|
||||
const string k_TempFolderName = "TempPrefabVariants";
|
||||
string m_TempFolder = k_ParentFolder + "/" + k_TempFolderName;
|
||||
string m_PrefabPath;
|
||||
string m_PrefabVariantPath;
|
||||
string m_PreviousScenePath;
|
||||
string m_TempScenePath;
|
||||
int m_TestCounter;
|
||||
|
||||
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;
|
||||
|
||||
[OneTimeSetUp]
|
||||
public void OneTimeSetup()
|
||||
{
|
||||
AssetDatabase.DeleteAsset(m_TempFolder);
|
||||
|
||||
var folderGUID = AssetDatabase.CreateFolder(k_ParentFolder, k_TempFolderName);
|
||||
m_TempFolder = AssetDatabase.GUIDToAssetPath(folderGUID);
|
||||
|
||||
SessionState.SetBool(k_AutoSaveKey, PrefabStageAutoSavingUtil.GetPrefabStageAutoSave());
|
||||
PrefabStageAutoSavingUtil.SetPrefabStageAutoSave(false);
|
||||
StageUtility.GoToMainStage();
|
||||
|
||||
m_PreviousScenePath = SceneManager.GetActiveScene().path;
|
||||
m_TempScenePath = Path.Combine(m_TempFolder, "NavMeshSurfacePrefabVariantTestsScene.unity");
|
||||
var tempScene = EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects, NewSceneMode.Single);
|
||||
EditorSceneManager.SaveScene(tempScene, m_TempScenePath);
|
||||
EditorSceneManager.OpenScene(m_TempScenePath);
|
||||
}
|
||||
|
||||
[OneTimeTearDown]
|
||||
public void OneTimeTearDown()
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
#if !KEEP_ARTIFACTS_FOR_INSPECTION
|
||||
AssetDatabase.DeleteAsset(m_TempFolder);
|
||||
#endif
|
||||
}
|
||||
|
||||
[UnitySetUp]
|
||||
public IEnumerator Setup()
|
||||
{
|
||||
var plane = GameObject.CreatePrimitive(PrimitiveType.Plane);
|
||||
plane.name = "NavMeshSurfacePrefab" + (++m_TestCounter);
|
||||
var surface = plane.AddComponent<NavMeshSurface>();
|
||||
surface.collectObjects = CollectObjects.Children;
|
||||
|
||||
m_PrefabPath = Path.Combine(m_TempFolder, plane.name + ".prefab");
|
||||
m_PrefabVariantPath = Path.Combine(m_TempFolder, plane.name + "Variant.prefab");
|
||||
|
||||
var planePrefab = PrefabUtility.SaveAsPrefabAsset(plane, m_PrefabPath);
|
||||
Object.DestroyImmediate(plane);
|
||||
|
||||
AssetDatabase.OpenAsset(planePrefab);
|
||||
var theOriginalPrefabStage = PrefabStageUtility.GetCurrentPrefabStage();
|
||||
var theOriginalPrefabSurface = theOriginalPrefabStage.prefabContentsRoot.GetComponent<NavMeshSurface>();
|
||||
yield return BakeNavMeshAsync(() => theOriginalPrefabSurface, k_PrefabDefaultArea);
|
||||
PrefabSavingUtil.SavePrefab(theOriginalPrefabStage);
|
||||
StageUtility.GoToMainStage();
|
||||
|
||||
var instanceForVariant = PrefabUtility.InstantiatePrefab(planePrefab) as GameObject;
|
||||
PrefabUtility.SaveAsPrefabAsset(instanceForVariant, m_PrefabVariantPath);
|
||||
|
||||
#if !KEEP_ARTIFACTS_FOR_INSPECTION
|
||||
Object.DestroyImmediate(instanceForVariant);
|
||||
#endif
|
||||
NavMesh.RemoveAllNavMeshData();
|
||||
|
||||
yield return null;
|
||||
}
|
||||
|
||||
[UnityTearDown]
|
||||
public IEnumerator TearDown()
|
||||
{
|
||||
StageUtility.GoToMainStage();
|
||||
|
||||
yield return null;
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator NavMeshSurfacePrefabVariant_WhenFreshAndRebaked_ParentAssetUnchanged()
|
||||
{
|
||||
var theOriginalPrefab = AssetDatabase.LoadAssetAtPath<GameObject>(m_PrefabPath);
|
||||
AssetDatabase.OpenAsset(theOriginalPrefab);
|
||||
var theOriginalPrefabStage = PrefabStageUtility.GetCurrentPrefabStage();
|
||||
var theOriginalPrefabSurface = theOriginalPrefabStage.prefabContentsRoot.GetComponent<NavMeshSurface>();
|
||||
var theOriginalPrefabNavMeshData = theOriginalPrefabSurface.navMeshData;
|
||||
var theOriginalPrefabAssetPath = AssetDatabase.GetAssetPath(theOriginalPrefabSurface.navMeshData);
|
||||
|
||||
Assert.IsTrue(theOriginalPrefabNavMeshData != null, "Original prefab must have some NavMeshData.");
|
||||
Assert.IsTrue(File.Exists(theOriginalPrefabAssetPath), "NavMeshData file must exist for the original prefab. ({0})", theOriginalPrefabAssetPath);
|
||||
|
||||
var prefabVariant = AssetDatabase.LoadAssetAtPath<GameObject>(m_PrefabVariantPath);
|
||||
AssetDatabase.OpenAsset(prefabVariant);
|
||||
var prefabVariantStage = PrefabStageUtility.GetCurrentPrefabStage();
|
||||
var prefabVariantSurface = prefabVariantStage.prefabContentsRoot.GetComponent<NavMeshSurface>();
|
||||
var initialVariantNavMeshData = prefabVariantSurface.navMeshData;
|
||||
var initialVariantAssetPath = AssetDatabase.GetAssetPath(prefabVariantSurface.navMeshData);
|
||||
|
||||
Assert.AreEqual(theOriginalPrefabNavMeshData, initialVariantNavMeshData, "Fresh variant must have the same NavMeshData as the original prefab.");
|
||||
|
||||
Assert.IsTrue(initialVariantNavMeshData != null, "Prefab must have some NavMeshData.");
|
||||
Assert.IsTrue(File.Exists(initialVariantAssetPath), "NavMeshData file must exist. ({0})", initialVariantAssetPath);
|
||||
|
||||
yield return BakeNavMeshAsync(() => prefabVariantSurface, k_GrayArea);
|
||||
|
||||
Assert.IsTrue(initialVariantNavMeshData != null, "The initial NavMeshData (from original prefab) must still exist immediately after prefab variant re-bake.");
|
||||
Assert.IsTrue(File.Exists(initialVariantAssetPath), "The initial NavMeshData file (from original prefab) must exist after prefab variant re-bake. ({0})", initialVariantAssetPath);
|
||||
|
||||
Assert.IsTrue(prefabVariantSurface.navMeshData != null, "NavMeshSurface must have NavMeshData after baking.");
|
||||
var unsavedRebakedNavMeshData = prefabVariantSurface.navMeshData;
|
||||
|
||||
yield return BakeNavMeshAsync(() => prefabVariantSurface, k_BrownArea);
|
||||
|
||||
Assert.IsTrue(unsavedRebakedNavMeshData == null, "An unsaved NavMeshData should not exist after a re-bake.");
|
||||
Assert.IsTrue(prefabVariantSurface.navMeshData != null, "NavMeshSurface must have NavMeshData after baking.");
|
||||
|
||||
PrefabSavingUtil.SavePrefab(prefabVariantStage);
|
||||
|
||||
var theNewVariantNavMeshData = prefabVariantSurface.navMeshData;
|
||||
var theNewVariantAssetPath = AssetDatabase.GetAssetPath(theNewVariantNavMeshData);
|
||||
|
||||
Assert.IsTrue(File.Exists(theNewVariantAssetPath), "Variant's own NavMeshData exists in a file after saving. ({0})", theNewVariantAssetPath);
|
||||
Assert.IsTrue(File.Exists(theOriginalPrefabAssetPath), "NavMeshData file of the original prefab still exists after saving the variant. ({0})", theOriginalPrefabAssetPath);
|
||||
Assert.IsTrue(theOriginalPrefabNavMeshData != null, "Original prefab must still have NavMeshData.");
|
||||
|
||||
StageUtility.GoToMainStage();
|
||||
|
||||
yield return null;
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator NavMeshSurfacePrefabVariant_WhenCustomizedAndRebaked_OldAssetDiscardedAndParentAssetUnchanged()
|
||||
{
|
||||
var prefabVariant = AssetDatabase.LoadAssetAtPath<GameObject>(m_PrefabVariantPath);
|
||||
var theOriginalPrefabPath = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(prefabVariant);
|
||||
var theOriginalPrefab = AssetDatabase.LoadAssetAtPath<GameObject>(theOriginalPrefabPath);
|
||||
|
||||
AssetDatabase.OpenAsset(theOriginalPrefab);
|
||||
var theOriginalPrefabStage = PrefabStageUtility.GetCurrentPrefabStage();
|
||||
var theOriginalPrefabSurface = theOriginalPrefabStage.prefabContentsRoot.GetComponent<NavMeshSurface>();
|
||||
var theOriginalPrefabNavMeshData = theOriginalPrefabSurface.navMeshData;
|
||||
var theOriginalPrefabAssetPath = AssetDatabase.GetAssetPath(theOriginalPrefabSurface.navMeshData);
|
||||
|
||||
Assert.IsTrue(theOriginalPrefabNavMeshData != null, "Original prefab must have some NavMeshData.");
|
||||
Assert.IsTrue(File.Exists(theOriginalPrefabAssetPath), "NavMeshData file must exist for the original prefab. ({0})", theOriginalPrefabAssetPath);
|
||||
|
||||
AssetDatabase.OpenAsset(prefabVariant);
|
||||
var prefabVariantStage = PrefabStageUtility.GetCurrentPrefabStage();
|
||||
var prefabVariantSurface = prefabVariantStage.prefabContentsRoot.GetComponent<NavMeshSurface>();
|
||||
|
||||
yield return BakeNavMeshAsync(() => prefabVariantSurface, k_GrayArea);
|
||||
PrefabSavingUtil.SavePrefab(prefabVariantStage);
|
||||
|
||||
var modifiedVariantNavMeshData = prefabVariantSurface.navMeshData;
|
||||
var modifiedVariantAssetPath = AssetDatabase.GetAssetPath(prefabVariantSurface.navMeshData);
|
||||
|
||||
Assert.IsTrue(modifiedVariantNavMeshData != null, "Prefab must have some NavMeshData.");
|
||||
Assert.IsTrue(File.Exists(modifiedVariantAssetPath), "NavMeshData file for modifier variant must exist. ({0})", modifiedVariantAssetPath);
|
||||
Assert.AreNotEqual(theOriginalPrefabNavMeshData, modifiedVariantNavMeshData, "Modified variant must have a NavMeshData different than that of the original prefab.");
|
||||
|
||||
yield return BakeNavMeshAsync(() => prefabVariantSurface, k_OrangeArea);
|
||||
|
||||
Assert.IsTrue(modifiedVariantNavMeshData != null, "The initial NavMeshData of a modified variant must still exist immediately after prefab variant re-bake.");
|
||||
Assert.IsTrue(File.Exists(modifiedVariantAssetPath), "The initial NavMeshData file of a modified variant must exist after prefab variant re-bake. ({0})", modifiedVariantAssetPath);
|
||||
|
||||
Assert.IsTrue(prefabVariantSurface.navMeshData != null, "NavMeshSurface must have NavMeshData after baking.");
|
||||
var unsavedRebakedNavMeshData = prefabVariantSurface.navMeshData;
|
||||
|
||||
yield return BakeNavMeshAsync(() => prefabVariantSurface, k_RedArea);
|
||||
Assert.IsTrue(unsavedRebakedNavMeshData == null, "An unsaved NavMeshData should not exist after a re-bake.");
|
||||
Assert.IsTrue(prefabVariantSurface.navMeshData != null, "NavMeshSurface must have NavMeshData after baking.");
|
||||
|
||||
PrefabSavingUtil.SavePrefab(prefabVariantStage);
|
||||
var theNewVariantNavMeshData = prefabVariantSurface.navMeshData;
|
||||
var theNewVariantAssetPath = AssetDatabase.GetAssetPath(theNewVariantNavMeshData);
|
||||
|
||||
Assert.IsTrue(modifiedVariantNavMeshData == null, "Initial NavMeshData of the modified variant must no longer exist after saving the variant.");
|
||||
// ReSharper disable once HeuristicUnreachableCode - modifiedVariantNavMeshData is affected by BakeNavMeshAsync()
|
||||
Assert.IsFalse(File.Exists(modifiedVariantAssetPath), "Initial NavMeshData file of the modified and saved variant must no longer exist after saving the variant. ({0})", modifiedVariantAssetPath);
|
||||
Assert.IsTrue(File.Exists(theNewVariantAssetPath), "Variant's own NavMeshData exists in a file after saving. ({0})", theNewVariantAssetPath);
|
||||
Assert.IsTrue(File.Exists(theOriginalPrefabAssetPath), "NavMeshData file of the original prefab still exists after saving the variant. ({0})", theOriginalPrefabAssetPath);
|
||||
Assert.AreNotEqual(theOriginalPrefabNavMeshData, theNewVariantNavMeshData, "Re-baked modified variant must have a NavMeshData different than that of the original prefab.");
|
||||
|
||||
StageUtility.GoToMainStage();
|
||||
|
||||
yield return null;
|
||||
}
|
||||
|
||||
static IEnumerator BakeNavMeshAsync(Func<NavMeshSurface> getSurface, int defaultArea)
|
||||
{
|
||||
var surface = getSurface();
|
||||
surface.defaultArea = defaultArea;
|
||||
NavMeshAssetManager.instance.StartBakingSurfaces(new Object[] { surface });
|
||||
yield return new WaitWhile(() => NavMeshAssetManager.instance.IsSurfaceBaking(surface));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 84d904f3fbe3c1b4c8daab917453682f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
18
Assets/NavMesh/Tests/Editor/PrefabSavingUtil.cs
Normal file
18
Assets/NavMesh/Tests/Editor/PrefabSavingUtil.cs
Normal file
|
@ -0,0 +1,18 @@
|
|||
using System;
|
||||
using System.Reflection;
|
||||
using UnityEditor.Experimental.SceneManagement;
|
||||
|
||||
public class PrefabSavingUtil {
|
||||
|
||||
public static void SavePrefab(PrefabStage prefabStage)
|
||||
{
|
||||
if (prefabStage == null)
|
||||
throw new ArgumentNullException();
|
||||
|
||||
var savePrefabMethod = prefabStage.GetType().GetMethod("SavePrefab", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
if (savePrefabMethod == null)
|
||||
throw new InvalidOperationException();
|
||||
|
||||
savePrefabMethod.Invoke(prefabStage, null);
|
||||
}
|
||||
}
|
11
Assets/NavMesh/Tests/Editor/PrefabSavingUtil.cs.meta
Normal file
11
Assets/NavMesh/Tests/Editor/PrefabSavingUtil.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4de45126199b4c84dbc8b9620cf3263d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
44
Assets/NavMesh/Tests/Editor/PrefabStageAutoSavingUtil.cs
Normal file
44
Assets/NavMesh/Tests/Editor/PrefabStageAutoSavingUtil.cs
Normal file
|
@ -0,0 +1,44 @@
|
|||
using System;
|
||||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
|
||||
public static class PrefabStageAutoSavingUtil
|
||||
{
|
||||
public static bool GetPrefabStageAutoSave()
|
||||
{
|
||||
var stageNavMgrInstance = GetStageNavigationManagerInstance();
|
||||
var autoSaveProperty = GetAutoSaveProperty(stageNavMgrInstance);
|
||||
return (bool)autoSaveProperty.GetValue(stageNavMgrInstance, null);
|
||||
}
|
||||
|
||||
public static void SetPrefabStageAutoSave(bool value)
|
||||
{
|
||||
var stageNavMgrInstance = GetStageNavigationManagerInstance();
|
||||
var autoSaveProperty = GetAutoSaveProperty(stageNavMgrInstance);
|
||||
autoSaveProperty.SetValue(stageNavMgrInstance, value, null);
|
||||
}
|
||||
|
||||
static object GetStageNavigationManagerInstance()
|
||||
{
|
||||
var editorAssemblyName = typeof(EditorWindow).Assembly.FullName;
|
||||
var t = Type.GetType("UnityEditor.SceneManagement.StageNavigationManager, " + editorAssemblyName, true, true);
|
||||
if (t == null)
|
||||
throw new ArgumentException();
|
||||
|
||||
var instanceProperty = t.GetProperty("instance", BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy);
|
||||
if (instanceProperty == null)
|
||||
throw new ArgumentException();
|
||||
|
||||
var stageNavMgrInstance = instanceProperty.GetValue(null, null);
|
||||
return stageNavMgrInstance;
|
||||
}
|
||||
|
||||
static PropertyInfo GetAutoSaveProperty(object stageNavigationManagerInstance)
|
||||
{
|
||||
var autoSaveProperty = stageNavigationManagerInstance.GetType().GetProperty("autoSave", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
if (autoSaveProperty == null)
|
||||
throw new ArgumentException();
|
||||
|
||||
return autoSaveProperty;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9cd905de8fe98d94a82de074adbd499d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
16
Assets/NavMesh/Tests/NavMeshComponentsTestsPlaymode.asmdef
Normal file
16
Assets/NavMesh/Tests/NavMeshComponentsTestsPlaymode.asmdef
Normal file
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"name": "NavMeshComponentsTestsPlaymode",
|
||||
"references": [
|
||||
"NavMeshComponents"
|
||||
],
|
||||
"optionalUnityReferences": [
|
||||
"TestAssemblies"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": []
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 455cd750f394b1c41b963b3335eae29c
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
102
Assets/NavMesh/Tests/NavMeshSurfaceAgentTests.cs
Normal file
102
Assets/NavMesh/Tests/NavMeshSurfaceAgentTests.cs
Normal file
|
@ -0,0 +1,102 @@
|
|||
#if UNITY_EDITOR || UNITY_STANDALONE
|
||||
using UnityEngine;
|
||||
using UnityEngine.AI;
|
||||
using UnityEngine.TestTools;
|
||||
using NUnit.Framework;
|
||||
using System.Collections;
|
||||
|
||||
public class NavMeshSurfaceAgentTests
|
||||
{
|
||||
NavMeshSurface m_Surface;
|
||||
NavMeshAgent m_Agent;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
m_Surface = GameObject.CreatePrimitive(PrimitiveType.Plane).AddComponent<NavMeshSurface>();
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
Object.DestroyImmediate(m_Agent.gameObject);
|
||||
Object.DestroyImmediate(m_Surface.gameObject);
|
||||
m_Agent = null;
|
||||
m_Surface = null;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AgentIdentifiesSurfaceOwner()
|
||||
{
|
||||
m_Surface.BuildNavMesh();
|
||||
|
||||
m_Agent = new GameObject("Agent").AddComponent<NavMeshAgent>();
|
||||
Assert.AreEqual(m_Surface, m_Agent.navMeshOwner);
|
||||
Assert.IsTrue(m_Agent.isOnNavMesh);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Ignore("1012991 : Missing functionality for notifying the NavMeshAgent about the removal of the NavMesh.")]
|
||||
public void AgentDetachesAndAttachesToSurface()
|
||||
{
|
||||
m_Surface.BuildNavMesh();
|
||||
|
||||
m_Agent = new GameObject("Agent").AddComponent<NavMeshAgent>();
|
||||
Assert.AreEqual(m_Surface, m_Agent.navMeshOwner);
|
||||
Assert.IsTrue(m_Agent.isOnNavMesh);
|
||||
|
||||
m_Surface.enabled = false;
|
||||
Assert.IsNull(m_Agent.navMeshOwner);
|
||||
Assert.IsFalse(m_Agent.isOnNavMesh);
|
||||
|
||||
m_Surface.enabled = true;
|
||||
Assert.AreEqual(m_Surface, m_Agent.navMeshOwner);
|
||||
Assert.IsTrue(m_Agent.isOnNavMesh);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[Test]
|
||||
public void AgentIsOnNavMeshWhenMatchingAgentTypeID()
|
||||
{
|
||||
m_Surface.agentTypeID = 1234;
|
||||
m_Surface.BuildNavMesh();
|
||||
|
||||
m_Agent = new GameObject("Agent").AddComponent<NavMeshAgent>();
|
||||
Assert.IsFalse(m_Agent.isOnNavMesh);
|
||||
|
||||
m_Agent.agentTypeID = 1234;
|
||||
Assert.IsTrue(m_Agent.isOnNavMesh);
|
||||
}
|
||||
*/
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator AgentAlignsToSurfaceNextFrame()
|
||||
{
|
||||
m_Surface.transform.rotation = new Quaternion(-0.679622f, 0.351242f, -0.373845f, 0.524388f);
|
||||
m_Surface.BuildNavMesh();
|
||||
|
||||
m_Agent = new GameObject("Agent").AddComponent<NavMeshAgent>();
|
||||
|
||||
yield return null;
|
||||
|
||||
var residual = m_Surface.transform.up - m_Agent.transform.up;
|
||||
Assert.IsTrue(residual.magnitude < 0.01f);
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator AgentDoesNotAlignToSurfaceNextFrame()
|
||||
{
|
||||
m_Surface.transform.rotation = new Quaternion(-0.679622f, 0.351242f, -0.373845f, 0.524388f);
|
||||
m_Surface.BuildNavMesh();
|
||||
|
||||
m_Agent = new GameObject("Agent").AddComponent<NavMeshAgent>();
|
||||
m_Agent.updateUpAxis = false;
|
||||
|
||||
yield return null;
|
||||
|
||||
var residual = Vector3.up - m_Agent.transform.up;
|
||||
Assert.IsTrue(residual.magnitude < 0.01f);
|
||||
}
|
||||
}
|
||||
#endif
|
12
Assets/NavMesh/Tests/NavMeshSurfaceAgentTests.cs.meta
Normal file
12
Assets/NavMesh/Tests/NavMeshSurfaceAgentTests.cs.meta
Normal file
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 45e898f1334e740678c21331ac30d746
|
||||
timeCreated: 1490606318
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
145
Assets/NavMesh/Tests/NavMeshSurfaceLinkTests.cs
Normal file
145
Assets/NavMesh/Tests/NavMeshSurfaceLinkTests.cs
Normal file
|
@ -0,0 +1,145 @@
|
|||
#if UNITY_EDITOR || UNITY_STANDALONE
|
||||
using UnityEngine;
|
||||
using UnityEngine.AI;
|
||||
using UnityEngine.TestTools;
|
||||
using NUnit.Framework;
|
||||
using System.Collections;
|
||||
|
||||
[TestFixture]
|
||||
public class NavMeshSurfaceLinkTests
|
||||
{
|
||||
public GameObject plane1, plane2;
|
||||
public NavMeshLink link;
|
||||
public NavMeshSurface surface;
|
||||
|
||||
[SetUp]
|
||||
public void CreatesPlanesAndLink()
|
||||
{
|
||||
plane1 = GameObject.CreatePrimitive(PrimitiveType.Plane);
|
||||
plane2 = GameObject.CreatePrimitive(PrimitiveType.Plane);
|
||||
plane1.transform.position = 11.0f * Vector3.right;
|
||||
|
||||
surface = new GameObject().AddComponent<NavMeshSurface>();
|
||||
surface.BuildNavMesh();
|
||||
|
||||
Assert.IsFalse(HasPathConnecting(plane1, plane2));
|
||||
Assert.IsFalse(HasPathConnecting(plane2, plane1));
|
||||
|
||||
link = new GameObject().AddComponent<NavMeshLink>();
|
||||
link.startPoint = plane1.transform.position;
|
||||
link.endPoint = plane2.transform.position;
|
||||
|
||||
Assert.IsTrue(HasPathConnecting(plane1, plane2));
|
||||
Assert.IsTrue(HasPathConnecting(plane2, plane1));
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void DestroyPlanesAndLink()
|
||||
{
|
||||
GameObject.DestroyImmediate(surface.gameObject);
|
||||
GameObject.DestroyImmediate(link.gameObject);
|
||||
GameObject.DestroyImmediate(plane1);
|
||||
GameObject.DestroyImmediate(plane2);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NavMeshLinkCanConnectTwoSurfaces()
|
||||
{
|
||||
Assert.IsTrue(HasPathConnecting(plane1, plane2));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DisablingBidirectionalMakesTheLinkOneWay()
|
||||
{
|
||||
link.bidirectional = false;
|
||||
Assert.IsTrue(HasPathConnecting(plane1, plane2));
|
||||
Assert.IsFalse(HasPathConnecting(plane2, plane1));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ChangingAreaTypeCanBlockPath()
|
||||
{
|
||||
var areaMask = ~(1 << 4);
|
||||
Assert.IsTrue(HasPathConnecting(plane1, plane2, areaMask));
|
||||
|
||||
link.area = 4;
|
||||
Assert.IsFalse(HasPathConnecting(plane1, plane2, areaMask));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void EndpointsMoveRelativeToLinkOnUpdate()
|
||||
{
|
||||
link.transform.position += Vector3.forward;
|
||||
Assert.IsFalse(HasPathConnectingViaPoint(plane1, plane2, plane1.transform.position + Vector3.forward));
|
||||
Assert.IsFalse(HasPathConnectingViaPoint(plane1, plane2, plane2.transform.position + Vector3.forward));
|
||||
|
||||
link.UpdateLink();
|
||||
|
||||
Assert.IsTrue(HasPathConnectingViaPoint(plane1, plane2, plane1.transform.position + Vector3.forward));
|
||||
Assert.IsTrue(HasPathConnectingViaPoint(plane1, plane2, plane2.transform.position + Vector3.forward));
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator EndpointsMoveRelativeToLinkNextFrameWhenAutoUpdating()
|
||||
{
|
||||
link.transform.position += Vector3.forward;
|
||||
link.autoUpdate = true;
|
||||
|
||||
Assert.IsFalse(HasPathConnectingViaPoint(plane1, plane2, plane1.transform.position + Vector3.forward));
|
||||
Assert.IsFalse(HasPathConnectingViaPoint(plane1, plane2, plane2.transform.position + Vector3.forward));
|
||||
|
||||
yield return null;
|
||||
|
||||
Assert.IsTrue(HasPathConnectingViaPoint(plane1, plane2, plane1.transform.position + Vector3.forward));
|
||||
Assert.IsTrue(HasPathConnectingViaPoint(plane1, plane2, plane2.transform.position + Vector3.forward));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ChangingCostModifierAffectsRoute()
|
||||
{
|
||||
var link1 = link;
|
||||
link1.startPoint = plane1.transform.position;
|
||||
link1.endPoint = plane2.transform.position + Vector3.forward;
|
||||
|
||||
var link2 = link.gameObject.AddComponent<NavMeshLink>();
|
||||
link2.startPoint = plane1.transform.position;
|
||||
link2.endPoint = plane2.transform.position - Vector3.forward;
|
||||
|
||||
link1.costModifier = -1;
|
||||
link2.costModifier = 100;
|
||||
Assert.IsTrue(HasPathConnectingViaPoint(plane1, plane2, link1.endPoint));
|
||||
Assert.IsFalse(HasPathConnectingViaPoint(plane1, plane2, link2.endPoint));
|
||||
|
||||
link1.costModifier = 100;
|
||||
link2.costModifier = -1;
|
||||
Assert.IsFalse(HasPathConnectingViaPoint(plane1, plane2, link1.endPoint));
|
||||
Assert.IsTrue(HasPathConnectingViaPoint(plane1, plane2, link2.endPoint));
|
||||
}
|
||||
|
||||
public static bool HasPathConnecting(GameObject a, GameObject b, int areaMask = NavMesh.AllAreas, int agentTypeID = 0)
|
||||
{
|
||||
var path = new NavMeshPath();
|
||||
var filter = new NavMeshQueryFilter();
|
||||
filter.areaMask = areaMask;
|
||||
filter.agentTypeID = agentTypeID;
|
||||
NavMesh.CalculatePath(a.transform.position, b.transform.position, filter, path);
|
||||
return path.status == NavMeshPathStatus.PathComplete;
|
||||
}
|
||||
|
||||
public static bool HasPathConnectingViaPoint(GameObject a, GameObject b, Vector3 point, int areaMask = NavMesh.AllAreas, int agentTypeID = 0)
|
||||
{
|
||||
var path = new NavMeshPath();
|
||||
var filter = new NavMeshQueryFilter();
|
||||
filter.areaMask = areaMask;
|
||||
filter.agentTypeID = agentTypeID;
|
||||
NavMesh.CalculatePath(a.transform.position, b.transform.position, filter, path);
|
||||
if (path.status != NavMeshPathStatus.PathComplete)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < path.corners.Length; ++i)
|
||||
if (Vector3.Distance(path.corners[i], point) < 0.1f)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
12
Assets/NavMesh/Tests/NavMeshSurfaceLinkTests.cs.meta
Normal file
12
Assets/NavMesh/Tests/NavMeshSurfaceLinkTests.cs.meta
Normal file
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 264ca61ae1b6e4c16bcfc55f84300402
|
||||
timeCreated: 1490606318
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
112
Assets/NavMesh/Tests/NavMeshSurfaceModifierTests.cs
Normal file
112
Assets/NavMesh/Tests/NavMeshSurfaceModifierTests.cs
Normal file
|
@ -0,0 +1,112 @@
|
|||
#if UNITY_EDITOR || UNITY_STANDALONE
|
||||
using UnityEngine;
|
||||
using UnityEngine.AI;
|
||||
using UnityEngine.TestTools;
|
||||
using NUnit.Framework;
|
||||
using System.Collections;
|
||||
|
||||
[TestFixture]
|
||||
public class NavMeshSurfaceModifierTests
|
||||
{
|
||||
NavMeshSurface surface;
|
||||
NavMeshModifier modifier;
|
||||
|
||||
[SetUp]
|
||||
public void CreatePlaneWithModifier()
|
||||
{
|
||||
var plane = GameObject.CreatePrimitive(PrimitiveType.Plane);
|
||||
surface = plane.AddComponent<NavMeshSurface>();
|
||||
modifier = plane.AddComponent<NavMeshModifier>();
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void DestroyPlaneWithModifier()
|
||||
{
|
||||
GameObject.DestroyImmediate(modifier.gameObject);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ModifierIgnoreAffectsSelf()
|
||||
{
|
||||
modifier.ignoreFromBuild = true;
|
||||
|
||||
surface.BuildNavMesh();
|
||||
|
||||
Assert.IsFalse(NavMeshSurfaceTests.HasNavMeshAtOrigin());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ModifierIgnoreAffectsChild()
|
||||
{
|
||||
modifier.ignoreFromBuild = true;
|
||||
modifier.GetComponent<MeshRenderer>().enabled = false;
|
||||
|
||||
var childPlane = GameObject.CreatePrimitive(PrimitiveType.Plane);
|
||||
childPlane.transform.SetParent(modifier.transform);
|
||||
|
||||
surface.BuildNavMesh();
|
||||
|
||||
Assert.IsFalse(NavMeshSurfaceTests.HasNavMeshAtOrigin());
|
||||
GameObject.DestroyImmediate(childPlane);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ModifierIgnoreDoesNotAffectSibling()
|
||||
{
|
||||
modifier.ignoreFromBuild = true;
|
||||
modifier.GetComponent<MeshRenderer>().enabled = false;
|
||||
|
||||
var siblingPlane = GameObject.CreatePrimitive(PrimitiveType.Plane);
|
||||
|
||||
surface.BuildNavMesh();
|
||||
|
||||
Assert.IsTrue(NavMeshSurfaceTests.HasNavMeshAtOrigin());
|
||||
GameObject.DestroyImmediate(siblingPlane);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ModifierOverrideAreaAffectsSelf()
|
||||
{
|
||||
modifier.area = 4;
|
||||
modifier.overrideArea = true;
|
||||
|
||||
surface.BuildNavMesh();
|
||||
|
||||
var expectedAreaMask = 1 << 4;
|
||||
Assert.IsTrue(NavMeshSurfaceTests.HasNavMeshAtOrigin(expectedAreaMask));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ModifierOverrideAreaAffectsChild()
|
||||
{
|
||||
modifier.area = 4;
|
||||
modifier.overrideArea = true;
|
||||
modifier.GetComponent<MeshRenderer>().enabled = false;
|
||||
|
||||
var childPlane = GameObject.CreatePrimitive(PrimitiveType.Plane);
|
||||
childPlane.transform.SetParent(modifier.transform);
|
||||
|
||||
surface.BuildNavMesh();
|
||||
|
||||
var expectedAreaMask = 1 << 4;
|
||||
Assert.IsTrue(NavMeshSurfaceTests.HasNavMeshAtOrigin(expectedAreaMask));
|
||||
GameObject.DestroyImmediate(childPlane);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ModifierOverrideAreaDoesNotAffectSibling()
|
||||
{
|
||||
modifier.area = 4;
|
||||
modifier.overrideArea = true;
|
||||
modifier.GetComponent<MeshRenderer>().enabled = false;
|
||||
|
||||
var siblingPlane = GameObject.CreatePrimitive(PrimitiveType.Plane);
|
||||
|
||||
surface.BuildNavMesh();
|
||||
|
||||
var expectedAreaMask = 1;
|
||||
Assert.IsTrue(NavMeshSurfaceTests.HasNavMeshAtOrigin(expectedAreaMask));
|
||||
GameObject.DestroyImmediate(siblingPlane);
|
||||
}
|
||||
}
|
||||
#endif
|
12
Assets/NavMesh/Tests/NavMeshSurfaceModifierTests.cs.meta
Normal file
12
Assets/NavMesh/Tests/NavMeshSurfaceModifierTests.cs.meta
Normal file
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f9fe5cff05af44c0fb71a8dcc44efc41
|
||||
timeCreated: 1490606318
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
71
Assets/NavMesh/Tests/NavMeshSurfaceModifierVolumeTests.cs
Normal file
71
Assets/NavMesh/Tests/NavMeshSurfaceModifierVolumeTests.cs
Normal file
|
@ -0,0 +1,71 @@
|
|||
#if UNITY_EDITOR || UNITY_STANDALONE
|
||||
using UnityEngine;
|
||||
using UnityEngine.AI;
|
||||
using UnityEngine.TestTools;
|
||||
using NUnit.Framework;
|
||||
using System.Collections;
|
||||
|
||||
[TestFixture]
|
||||
public class NavMeshSurfaceModifierVolumeTests
|
||||
{
|
||||
NavMeshSurface surface;
|
||||
NavMeshModifierVolume modifier;
|
||||
|
||||
[SetUp]
|
||||
public void CreatePlaneAndModifierVolume()
|
||||
{
|
||||
var go = GameObject.CreatePrimitive(PrimitiveType.Plane);
|
||||
surface = go.AddComponent<NavMeshSurface>();
|
||||
|
||||
modifier = new GameObject().AddComponent<NavMeshModifierVolume>();
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void DestroyPlaneAndModifierVolume()
|
||||
{
|
||||
GameObject.DestroyImmediate(surface.gameObject);
|
||||
GameObject.DestroyImmediate(modifier.gameObject);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AreaAffectsNavMeshOverlapping()
|
||||
{
|
||||
modifier.center = Vector3.zero;
|
||||
modifier.size = Vector3.one;
|
||||
modifier.area = 4;
|
||||
|
||||
surface.BuildNavMesh();
|
||||
|
||||
var expectedAreaMask = 1 << 4;
|
||||
Assert.IsTrue(NavMeshSurfaceTests.HasNavMeshAtOrigin(expectedAreaMask));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AreaDoesNotAffectsNavMeshWhenNotOverlapping()
|
||||
{
|
||||
modifier.center = 1.1f * Vector3.right;
|
||||
modifier.size = Vector3.one;
|
||||
modifier.area = 4;
|
||||
|
||||
surface.BuildNavMesh();
|
||||
|
||||
var expectedAreaMask = 1;
|
||||
Assert.IsTrue(NavMeshSurfaceTests.HasNavMeshAtOrigin(expectedAreaMask));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void BuildUsesOnlyIncludedModifierVolume()
|
||||
{
|
||||
modifier.center = Vector3.zero;
|
||||
modifier.size = Vector3.one;
|
||||
modifier.area = 4;
|
||||
modifier.gameObject.layer = 7;
|
||||
|
||||
surface.layerMask = ~(1 << 7);
|
||||
surface.BuildNavMesh();
|
||||
|
||||
var expectedAreaMask = 1;
|
||||
Assert.IsTrue(NavMeshSurfaceTests.HasNavMeshAtOrigin(expectedAreaMask));
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f5d873c779b014234ba92f3cb7476da6
|
||||
timeCreated: 1490606318
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
202
Assets/NavMesh/Tests/NavMeshSurfaceTests.cs
Normal file
202
Assets/NavMesh/Tests/NavMeshSurfaceTests.cs
Normal file
|
@ -0,0 +1,202 @@
|
|||
#if UNITY_EDITOR || UNITY_STANDALONE
|
||||
using UnityEngine;
|
||||
using UnityEngine.AI;
|
||||
using UnityEngine.TestTools;
|
||||
using NUnit.Framework;
|
||||
using System.Collections;
|
||||
|
||||
[TestFixture]
|
||||
public class NavMeshSurfaceTests
|
||||
{
|
||||
GameObject plane;
|
||||
NavMeshSurface surface;
|
||||
|
||||
[SetUp]
|
||||
public void CreatePlaneWithSurface()
|
||||
{
|
||||
plane = GameObject.CreatePrimitive(PrimitiveType.Plane);
|
||||
surface = new GameObject().AddComponent<NavMeshSurface>();
|
||||
Assert.IsFalse(HasNavMeshAtOrigin());
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void DestroyPlaneWithSurface()
|
||||
{
|
||||
GameObject.DestroyImmediate(plane);
|
||||
GameObject.DestroyImmediate(surface.gameObject);
|
||||
Assert.IsFalse(HasNavMeshAtOrigin());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NavMeshIsAvailableAfterBuild()
|
||||
{
|
||||
surface.BuildNavMesh();
|
||||
Assert.IsTrue(HasNavMeshAtOrigin());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NavMeshCanBeRemovedAndAdded()
|
||||
{
|
||||
surface.BuildNavMesh();
|
||||
Assert.IsTrue(HasNavMeshAtOrigin());
|
||||
|
||||
surface.RemoveData();
|
||||
Assert.IsFalse(HasNavMeshAtOrigin());
|
||||
|
||||
surface.AddData();
|
||||
Assert.IsTrue(HasNavMeshAtOrigin());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NavMeshIsNotAvailableWhenDisabled()
|
||||
{
|
||||
surface.BuildNavMesh();
|
||||
|
||||
surface.enabled = false;
|
||||
Assert.IsFalse(HasNavMeshAtOrigin());
|
||||
|
||||
surface.enabled = true;
|
||||
Assert.IsTrue(HasNavMeshAtOrigin());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CanBuildWithCustomArea()
|
||||
{
|
||||
surface.defaultArea = 4;
|
||||
var expectedAreaMask = 1 << 4;
|
||||
|
||||
surface.BuildNavMesh();
|
||||
Assert.IsTrue(HasNavMeshAtOrigin(expectedAreaMask));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CanBuildWithCustomAgentTypeID()
|
||||
{
|
||||
surface.agentTypeID = 1234;
|
||||
surface.BuildNavMesh();
|
||||
|
||||
Assert.IsTrue(HasNavMeshAtOrigin(NavMesh.AllAreas, 1234));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CanBuildCollidersAndIgnoreRenderMeshes()
|
||||
{
|
||||
plane.GetComponent<MeshRenderer>().enabled = false;
|
||||
|
||||
surface.useGeometry = NavMeshCollectGeometry.PhysicsColliders;
|
||||
surface.BuildNavMesh();
|
||||
Assert.IsTrue(HasNavMeshAtOrigin());
|
||||
|
||||
surface.useGeometry = NavMeshCollectGeometry.RenderMeshes;
|
||||
surface.BuildNavMesh();
|
||||
Assert.IsFalse(HasNavMeshAtOrigin());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CanBuildRenderMeshesAndIgnoreColliders()
|
||||
{
|
||||
plane.GetComponent<Collider>().enabled = false;
|
||||
|
||||
surface.useGeometry = NavMeshCollectGeometry.PhysicsColliders;
|
||||
surface.BuildNavMesh();
|
||||
Assert.IsFalse(HasNavMeshAtOrigin());
|
||||
|
||||
surface.useGeometry = NavMeshCollectGeometry.RenderMeshes;
|
||||
surface.BuildNavMesh();
|
||||
Assert.IsTrue(HasNavMeshAtOrigin());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void BuildIgnoresGeometryOutsideBounds()
|
||||
{
|
||||
surface.collectObjects = CollectObjects.Volume;
|
||||
surface.center = new Vector3(20, 0, 0);
|
||||
surface.size = new Vector3(10, 10, 10);
|
||||
|
||||
surface.BuildNavMesh();
|
||||
Assert.IsFalse(HasNavMeshAtOrigin());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void BuildIgnoresGeometrySiblings()
|
||||
{
|
||||
surface.collectObjects = CollectObjects.Children;
|
||||
|
||||
surface.BuildNavMesh();
|
||||
Assert.IsFalse(HasNavMeshAtOrigin());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void BuildUsesOnlyIncludedLayers()
|
||||
{
|
||||
plane.layer = 4;
|
||||
surface.layerMask = ~(1 << 4);
|
||||
|
||||
surface.BuildNavMesh();
|
||||
Assert.IsFalse(HasNavMeshAtOrigin());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DefaultSettingsMatchBuiltinSettings()
|
||||
{
|
||||
var bs = surface.GetBuildSettings();
|
||||
Assert.AreEqual(NavMesh.GetSettingsByIndex(0), bs);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ActiveSurfacesContainsOnlyActiveAndEnabledSurface()
|
||||
{
|
||||
Assert.IsTrue(NavMeshSurface.activeSurfaces.Contains(surface));
|
||||
Assert.AreEqual(1, NavMeshSurface.activeSurfaces.Count);
|
||||
|
||||
surface.enabled = false;
|
||||
Assert.IsFalse(NavMeshSurface.activeSurfaces.Contains(surface));
|
||||
Assert.AreEqual(0, NavMeshSurface.activeSurfaces.Count);
|
||||
|
||||
surface.enabled = true;
|
||||
surface.gameObject.SetActive(false);
|
||||
Assert.IsFalse(NavMeshSurface.activeSurfaces.Contains(surface));
|
||||
Assert.AreEqual(0, NavMeshSurface.activeSurfaces.Count);
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator NavMeshMovesToSurfacePositionNextFrame()
|
||||
{
|
||||
plane.transform.position = new Vector3(100, 0, 0);
|
||||
surface.transform.position = new Vector3(100, 0, 0);
|
||||
surface.BuildNavMesh();
|
||||
Assert.IsFalse(HasNavMeshAtOrigin());
|
||||
|
||||
surface.transform.position = Vector3.zero;
|
||||
Assert.IsFalse(HasNavMeshAtOrigin());
|
||||
|
||||
yield return null;
|
||||
|
||||
Assert.IsTrue(HasNavMeshAtOrigin());
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator UpdatingAndAddingNavMesh()
|
||||
{
|
||||
var navmeshData = new NavMeshData();
|
||||
var oper = surface.UpdateNavMesh(navmeshData);
|
||||
Assert.IsFalse(HasNavMeshAtOrigin());
|
||||
|
||||
do { yield return null; } while (!oper.isDone);
|
||||
surface.RemoveData();
|
||||
surface.navMeshData = navmeshData;
|
||||
surface.AddData();
|
||||
|
||||
Assert.IsTrue(HasNavMeshAtOrigin());
|
||||
}
|
||||
|
||||
public static bool HasNavMeshAtOrigin(int areaMask = NavMesh.AllAreas, int agentTypeID = 0)
|
||||
{
|
||||
var hit = new NavMeshHit();
|
||||
var filter = new NavMeshQueryFilter();
|
||||
filter.areaMask = areaMask;
|
||||
filter.agentTypeID = agentTypeID;
|
||||
return NavMesh.SamplePosition(Vector3.zero, out hit, 0.1f, filter);
|
||||
}
|
||||
}
|
||||
#endif
|
12
Assets/NavMesh/Tests/NavMeshSurfaceTests.cs.meta
Normal file
12
Assets/NavMesh/Tests/NavMeshSurfaceTests.cs.meta
Normal file
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 925111c157b314873b97f89e0f03d570
|
||||
timeCreated: 1490606318
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Loading…
Add table
Add a link
Reference in a new issue