static string GetAndEnsureTargetPath(NavMeshSurfaceNBLD surface) { // Create directory for the asset if it does not exist yet. var activeScenePath = surface.gameObject.scene.path; var targetPath = "Assets"; if (!string.IsNullOrEmpty(activeScenePath)) { targetPath = Path.Combine(Path.GetDirectoryName(activeScenePath), Path.GetFileNameWithoutExtension(activeScenePath)); } else { var prefabStage = PrefabStageUtility.GetPrefabStage(surface.gameObject); var isPartOfPrefab = prefabStage != null && prefabStage.IsPartOfPrefabContents(surface.gameObject); if (isPartOfPrefab && !string.IsNullOrEmpty(prefabStage.prefabAssetPath)) { var prefabDirectoryName = Path.GetDirectoryName(prefabStage.prefabAssetPath); if (!string.IsNullOrEmpty(prefabDirectoryName)) { targetPath = prefabDirectoryName; } } } if (!Directory.Exists(targetPath)) { Directory.CreateDirectory(targetPath); } return(targetPath); }
void DeleteStoredPrefabNavMeshDataAsset(NavMeshSurfaceNBLD surface) { for (var i = m_PrefabNavMeshDataAssets.Count - 1; i >= 0; i--) { var storedAssetInfo = m_PrefabNavMeshDataAssets[i]; if (storedAssetInfo.surface == surface) { var storedNavMeshData = storedAssetInfo.navMeshData; if (storedNavMeshData != null && storedNavMeshData != surface.navMeshData) { var assetPath = AssetDatabase.GetAssetPath(storedNavMeshData); AssetDatabase.DeleteAsset(assetPath); } m_PrefabNavMeshDataAssets.RemoveAt(i); break; } } if (m_PrefabNavMeshDataAssets.Count == 0) { PrefabStage.prefabSaving -= DeleteStoredNavMeshDataAssetsForOwnedSurfaces; PrefabStage.prefabStageClosing -= ForgetUnsavedNavMeshDataChanges; } }
static void SetNavMeshData(NavMeshSurfaceNBLD navSurface, NavMeshData navMeshData) { var so = new SerializedObject(navSurface); var navMeshDataProperty = so.FindProperty("m_NavMeshData"); navMeshDataProperty.objectReferenceValue = navMeshData; so.ApplyModifiedPropertiesWithoutUndo(); }
static NavMeshData InitializeBakeData(NavMeshSurfaceNBLD surface) { var emptySources = new List <NavMeshBuildSource>(); var emptyBounds = new Bounds(); return(UnityEngine.AI.NavMeshBuilder.BuildNavMeshData(surface.GetBuildSettings(), emptySources, emptyBounds , surface.transform.position, surface.transform.rotation)); }
static void CreateNavMeshAsset(NavMeshSurfaceNBLD surface) { var targetPath = GetAndEnsureTargetPath(surface); var combinedAssetPath = Path.Combine(targetPath, "NavMesh-" + surface.name + ".asset"); combinedAssetPath = AssetDatabase.GenerateUniqueAssetPath(combinedAssetPath); AssetDatabase.CreateAsset(surface.navMeshData, combinedAssetPath); }
static void RenderBoxGizmoNotSelected(NavMeshSurfaceNBLD navSurface, GizmoType gizmoType) { if (NavMeshVisualizationSettings.showNavigation > 0) { RenderBoxGizmo(navSurface, gizmoType, false); } else { Gizmos.DrawIcon(navSurface.transform.position, "NavMeshSurface Icon", true); } }
bool IsCurrentPrefabNavMeshDataStored(NavMeshSurfaceNBLD surface) { if (surface == null) { return(false); } foreach (var storedAssetInfo in m_PrefabNavMeshDataAssets) { if (storedAssetInfo.surface == surface) { return(storedAssetInfo.navMeshData == surface.navMeshData); } } return(false); }
static void RenderBoxGizmo(NavMeshSurfaceNBLD navSurface, GizmoType gizmoType, bool selected) { var color = selected ? s_HandleColorSelected : s_HandleColor; if (!navSurface.enabled) { color = s_HandleColorDisabled; } var oldColor = Gizmos.color; var oldMatrix = Gizmos.matrix; // Use the unscaled matrix for the NavMeshSurface var localToWorld = Matrix4x4.TRS(navSurface.transform.position, navSurface.transform.rotation, Vector3.one); Gizmos.matrix = localToWorld; if (navSurface.collectObjects == CollectObjectsNBLD.Volume) { Gizmos.color = color; Gizmos.DrawWireCube(navSurface.center, navSurface.size); if (selected && navSurface.enabled) { var colorTrans = new Color(color.r * 0.75f, color.g * 0.75f, color.b * 0.75f, color.a * 0.15f); Gizmos.color = colorTrans; Gizmos.DrawCube(navSurface.center, navSurface.size); } } else { if (navSurface.navMeshData != null) { var bounds = navSurface.navMeshData.sourceBounds; Gizmos.color = Color.grey; Gizmos.DrawWireCube(bounds.center, bounds.size); } } Gizmos.matrix = oldMatrix; Gizmos.color = oldColor; Gizmos.DrawIcon(navSurface.transform.position, "NavMeshSurface Icon", true); }
void ClearSurface(NavMeshSurfaceNBLD navSurface) { var hasNavMeshData = navSurface.navMeshData != null; StoreNavMeshDataIfInPrefab(navSurface); var assetToDelete = GetNavMeshAssetToDelete(navSurface); navSurface.RemoveData(); if (hasNavMeshData) { SetNavMeshData(navSurface, null); EditorSceneManager.MarkSceneDirty(navSurface.gameObject.scene); } if (assetToDelete) { AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(assetToDelete)); } }
void StoreNavMeshDataIfInPrefab(NavMeshSurfaceNBLD surfaceToStore) { var prefabStage = PrefabStageUtility.GetPrefabStage(surfaceToStore.gameObject); var isPartOfPrefab = prefabStage != null && prefabStage.IsPartOfPrefabContents(surfaceToStore.gameObject); if (!isPartOfPrefab) { return; } // check if data has already been stored for this surface foreach (var storedAssetInfo in m_PrefabNavMeshDataAssets) { if (storedAssetInfo.surface == surfaceToStore) { return; } } if (m_PrefabNavMeshDataAssets.Count == 0) { PrefabStage.prefabSaving -= DeleteStoredNavMeshDataAssetsForOwnedSurfaces; PrefabStage.prefabSaving += DeleteStoredNavMeshDataAssetsForOwnedSurfaces; PrefabStage.prefabStageClosing -= ForgetUnsavedNavMeshDataChanges; PrefabStage.prefabStageClosing += ForgetUnsavedNavMeshDataChanges; } var isDataOwner = true; if (PrefabUtility.IsPartOfPrefabInstance(surfaceToStore) && !PrefabUtility.IsPartOfModelPrefab(surfaceToStore)) { var basePrefabSurface = PrefabUtility.GetCorrespondingObjectFromSource(surfaceToStore) as NavMeshSurfaceNBLD; isDataOwner = basePrefabSurface == null || surfaceToStore.navMeshData != basePrefabSurface.navMeshData; } m_PrefabNavMeshDataAssets.Add(new SavedPrefabNavMeshData { surface = surfaceToStore, navMeshData = isDataOwner ? surfaceToStore.navMeshData : null }); }
public bool IsSurfaceBaking(NavMeshSurfaceNBLD surface) { if (surface == null) { return(false); } foreach (var oper in m_BakeOperations) { if (oper.surface == null || oper.bakeOperation == null) { continue; } if (oper.surface == surface) { return(true); } } return(false); }
NavMeshData GetNavMeshAssetToDelete(NavMeshSurfaceNBLD navSurface) { if (PrefabUtility.IsPartOfPrefabInstance(navSurface) && !PrefabUtility.IsPartOfModelPrefab(navSurface)) { // Don't allow deleting the asset belonging to the prefab parent var parentSurface = PrefabUtility.GetCorrespondingObjectFromSource(navSurface) as NavMeshSurfaceNBLD; if (parentSurface && navSurface.navMeshData == parentSurface.navMeshData) { return(null); } } // Do not delete the NavMeshData asset referenced from a prefab until the prefab is saved var prefabStage = PrefabStageUtility.GetPrefabStage(navSurface.gameObject); var isPartOfPrefab = prefabStage != null && prefabStage.IsPartOfPrefabContents(navSurface.gameObject); if (isPartOfPrefab && IsCurrentPrefabNavMeshDataStored(navSurface)) { return(null); } return(navSurface.navMeshData); }
void ForgetUnsavedNavMeshDataChanges(PrefabStage prefabStage) { // Debug.Log("On prefab closing - forget about this object's surfaces and stop caring about prefab saving"); if (prefabStage == null) { return; } var allSurfacesInPrefab = prefabStage.prefabContentsRoot.GetComponentsInChildren <NavMeshSurfaceNBLD>(true); NavMeshSurfaceNBLD surfaceInPrefab = null; var index = 0; do { if (allSurfacesInPrefab.Length > 0) { surfaceInPrefab = allSurfacesInPrefab[index]; } for (var i = m_PrefabNavMeshDataAssets.Count - 1; i >= 0; i--) { var storedPrefabInfo = m_PrefabNavMeshDataAssets[i]; if (storedPrefabInfo.surface == null) { // Debug.LogFormat("A surface from the prefab got deleted after it has baked a new NavMesh but it hasn't saved it. Now the unsaved asset gets deleted. ({0})", storedPrefabInfo.navMeshData); // surface got deleted, thus delete its initial NavMeshData asset if (storedPrefabInfo.navMeshData != null) { var assetPath = AssetDatabase.GetAssetPath(storedPrefabInfo.navMeshData); AssetDatabase.DeleteAsset(assetPath); } m_PrefabNavMeshDataAssets.RemoveAt(i); } else if (surfaceInPrefab != null && storedPrefabInfo.surface == surfaceInPrefab) { //Debug.LogFormat("The surface {0} from the prefab was storing the original navmesh data and now will be forgotten", surfaceInPrefab); var baseSurface = PrefabUtility.GetCorrespondingObjectFromSource(surfaceInPrefab) as NavMeshSurfaceNBLD; if (baseSurface == null || surfaceInPrefab.navMeshData != baseSurface.navMeshData) { var assetPath = AssetDatabase.GetAssetPath(surfaceInPrefab.navMeshData); AssetDatabase.DeleteAsset(assetPath); //Debug.LogFormat("The surface {0} from the prefab has baked new NavMeshData but did not save this change so the asset has been now deleted. ({1})", // surfaceInPrefab, assetPath); } m_PrefabNavMeshDataAssets.RemoveAt(i); } } } while (++index < allSurfacesInPrefab.Length); if (m_PrefabNavMeshDataAssets.Count == 0) { PrefabStage.prefabSaving -= DeleteStoredNavMeshDataAssetsForOwnedSurfaces; PrefabStage.prefabStageClosing -= ForgetUnsavedNavMeshDataChanges; } }
static void RenderBoxGizmoSelected(NavMeshSurfaceNBLD navSurface, GizmoType gizmoType) { RenderBoxGizmo(navSurface, gizmoType, true); }