public ZoneDescriptor GetZoneForPosition(Vector3 position) { if (_zonesTransform == null) { EB.Debug.LogWarning("Could not find zones under level descriptor. Tracking may not work correctly."); return(null); } float x = Mathf.Floor(position.x / 64f) * 64f; float z = Mathf.Floor(position.z / 64f) * 64f; Vector3 zonePosition = new Vector3(x, 0, z); for (int i = 0; i < mZonechildCount; i++) { Transform t = mZoneChildTransform[i]; GlobalNavHelper navHelper = mZoneChildGlobalNavHelper[i]; if (navHelper != null) { continue; } if ((t.position - zonePosition).sqrMagnitude < 1f) { return(mZoneChildZoneDescriptor[i]); } } return(null); }
private void RenderGrid(bool isHorizontal = true) { // draw some debug lines (ridSize * EditorVars.GridSize @ 1 meter gaps) Vector3 cachedPosition = transform.position; Color color = Color.white; float gridSizeX = EditorVars.GridSize; float gridSizeZ = EditorVars.GridSize; GlobalNavHelper nav_helper = GetComponent <GlobalNavHelper>(); if (nav_helper != null) { gridSizeX = nav_helper.m_Range.x; gridSizeZ = nav_helper.m_Range.z; } for (int i = 0; i < (isHorizontal ? gridSizeZ + 1 : gridSizeX + 1); i++) { Vector3 src = new Vector3(isHorizontal? cachedPosition.x : cachedPosition.x + i, cachedPosition.y, isHorizontal? cachedPosition.z + i : cachedPosition.z); Vector3 dest = src + new Vector3(isHorizontal? gridSizeX : 0.0f, 0.0f, isHorizontal? 0.0f : gridSizeZ); if (i == 0 || i == gridSizeZ) { if (transform == EnvironmentHelper.ActiveZone) { color = _helper.activeGridColor; DrawGridLine(src, dest, color, isHorizontal, !isHorizontal); // DrawGridLine( src, dest, color, false, true ); } else { DrawGridLine(src, dest, _helper.gridBorderColor); } } else { if (transform == EnvironmentHelper.ActiveZone) { color = _helper.gridColor; } else { Color inactiveColor = _helper.gridColor; color = inactiveColor * 0.55f; } DrawGridLine(src, dest, color); } } }
// given a transform representing a zone, gives back the min and max extents of the zone public static void CalculateZoneMinAndMax(ref Vector3 refMin, ref Vector3 refMax, Transform zone) { float gridSizeX = EditorVars.GridSize; float gridSizeY = EditorVars.GridSize; float gridSizeZ = EditorVars.GridSize; GlobalNavHelper nav_helper = zone.GetComponent <GlobalNavHelper>(); if (nav_helper != null) { gridSizeX = nav_helper.m_Range.x; gridSizeY = nav_helper.m_Range.y; gridSizeZ = nav_helper.m_Range.z; } refMin.x = zone.position.x; refMin.y = zone.position.y - (gridSizeY / 2); refMin.z = zone.position.z; refMax.x = zone.position.x + gridSizeX; refMax.y = zone.position.y + (gridSizeY / 2); refMax.z = zone.position.z + gridSizeZ; }
void OnDrawGizmos() { if (_helper == null) { return; } _exitColorInner = _helper.exitColor * 0.75f; float gridSizeX = EditorVars.GridSize; float gridSizeZ = EditorVars.GridSize; GlobalNavHelper nav_helper = GetComponent <GlobalNavHelper>(); if (nav_helper != null) { gridSizeX = nav_helper.m_Range.x; gridSizeZ = nav_helper.m_Range.z; } if (showGrid == true && _helper != null) { // render horizontal lines RenderGrid(true); // render vertical lines RenderGrid(false); } if (_helper.showExits && _zoneDescriptor.zoneExits != 0) { float startX = 0.0f; float startZ = 0.0f; Gizmos.color = _helper.exitColor; // render exit gizmos if ((_zoneDescriptor.zoneExits & ZoneDescriptor.eZoneExit.North) != 0) { startX = ( float )(gridSizeX / 2) + transform.position.x; startZ = ( float )(gridSizeZ) + transform.position.z; Gizmos.color = _helper.exitColor; Gizmos.DrawCube(new Vector3(startX, 0.01f, startZ), new Vector3(EditorVars.GridSize / 8, 0.01f, 2.0f)); Gizmos.color = _exitColorInner; Gizmos.DrawCube(new Vector3(startX, 0.011f, startZ), new Vector3(EditorVars.GridSize / 8, 0.011f, 2.0f) * 0.75f); } if ((_zoneDescriptor.zoneExits & ZoneDescriptor.eZoneExit.South) != 0) { startX = ( float )(gridSizeX / 2) + transform.position.x; startZ = transform.position.z; Gizmos.color = _helper.exitColor; Gizmos.DrawCube(new Vector3(startX, 0.01f, startZ), new Vector3(EditorVars.GridSize / 8, 0.01f, 2.0f)); Gizmos.color = _exitColorInner; Gizmos.DrawCube(new Vector3(startX, 0.011f, startZ), new Vector3(EditorVars.GridSize / 8, 0.011f, 2.0f) * 0.75f); } if ((_zoneDescriptor.zoneExits & ZoneDescriptor.eZoneExit.West) != 0) { startX = transform.position.x; startZ = ( float )(gridSizeZ / 2) + transform.position.z; Gizmos.color = _helper.exitColor; Gizmos.DrawCube(new Vector3(startX, 0.01f, startZ), new Vector3(2.0f, 0.01f, EditorVars.GridSize / 8)); Gizmos.color = _exitColorInner; Gizmos.DrawCube(new Vector3(startX, 0.011f, startZ), new Vector3(2.0f, 0.011f, EditorVars.GridSize / 8) * 0.75f); } if ((_zoneDescriptor.zoneExits & ZoneDescriptor.eZoneExit.East) != 0) { startX = ( float )(gridSizeX) + transform.position.x; startZ = ( float )(gridSizeZ / 2) + transform.position.z; Gizmos.color = _helper.exitColor; Gizmos.DrawCube(new Vector3(startX, 0.01f, startZ), new Vector3(2.0f, 0.01f, EditorVars.GridSize / 8)); Gizmos.color = _exitColorInner; Gizmos.DrawCube(new Vector3(startX, 0.011f, startZ), new Vector3(2.0f, 0.011f, EditorVars.GridSize / 8) * 0.75f); } } // debug: render a sphere to indicate central rotation point // Gizmos.DrawSphere( new Vector3( transform.position.x + 32.0f, 0.0f, transform.position.z + 32.0f ), 1.0f ); }
// A star pathfinding pro (APP) static public bool CreateAPPNavMesh(bool multiTile, Transform singleZone, Transform zonesRootTransform, bool doActivateAndDeactivateGeoForGeneration, float navBoundsOffset, bool doScan) { if (AstarPath.active == null) { EB.Debug.LogError("LevelHelperEditor::ExportLevel AStar object not found!"); return(false); } AstarPath.active.graphs = new NavGraph[0]; // clear graphs GameObject zonesRoot = zonesRootTransform.gameObject; if (zonesRoot == null) { EB.Debug.LogError("LevelHelperEditor::Zones gameObject not found!"); return(false); } // re-init valid graph types in underlying AstarData object AstarPath.active.astarData.FindGraphTypes(); const float kBoundingBoxHeight = 100.0f; // this is an arbitrary amount, if there is ever a tall level, this can be increased RecastGraph recastGraph = null; float gridSizeX = EditorVars.GridSize; float gridSizeY = EditorVars.GridSize; float gridSizeZ = EditorVars.GridSize; if (null != singleZone) { recastGraph = (RecastGraph)AstarPath.active.astarData.AddGraph(typeof(RecastGraph)); GlobalNavHelper nav_helper = singleZone.GetComponent <GlobalNavHelper>(); if (nav_helper != null) { gridSizeX = nav_helper.m_Range.x; gridSizeY = nav_helper.m_Range.y; gridSizeZ = nav_helper.m_Range.z; } Vector3 center = new Vector3(singleZone.position.x + gridSizeX / 2.0f, 0.0f, singleZone.position.z + gridSizeZ / 2.0f); Vector3 boundingBox = Vector3.zero; if (multiTile) { // if it's multi tile, we create a bounding box which is three times the size of our zone, so that our zone will be placed in the center boundingBox = new Vector3(gridSizeX * 3f, gridSizeY * 3f, gridSizeZ * 3f); SetNavMeshDefaults(recastGraph, center, boundingBox, multiTile); recastGraph.tileSizeX = recastGraph.tileSizeZ = (int)(EditorVars.GridSize / recastGraph.cellSize); // this line sets the tile size so that each tile will hold the size of a zone recastGraph.useCenterTileOnly = true; } else { boundingBox = new Vector3(gridSizeX, gridSizeY, gridSizeZ); SetNavMeshDefaults(recastGraph, center, boundingBox, multiTile); } } else { // or geo can be tested to get the y extents Vector3 NavMeshBoundingBoxMin = new Vector3(float.MaxValue, -(kBoundingBoxHeight * 0.5f), float.MaxValue); Vector3 NavMeshBoundingBoxMax = new Vector3(-float.MaxValue, kBoundingBoxHeight * 0.5f, -float.MaxValue); // walk zones to generate the bounding box encompassing the entire level (all zones) foreach (Transform zone in zonesRoot.transform) { gridSizeX = EditorVars.GridSize; gridSizeY = EditorVars.GridSize; gridSizeZ = EditorVars.GridSize; GlobalNavHelper nav_helper = zone.GetComponent <GlobalNavHelper>(); if (nav_helper != null) { gridSizeX = nav_helper.m_Range.x; gridSizeY = nav_helper.m_Range.y; gridSizeZ = nav_helper.m_Range.z; } float zoneXMin = zone.position.x + navBoundsOffset; float zoneXMax = zone.position.x + gridSizeX + navBoundsOffset; float zoneZMin = zone.position.z + navBoundsOffset; float zoneZMax = zone.position.z + gridSizeZ + navBoundsOffset; NavMeshBoundingBoxMin.x = zoneXMin < NavMeshBoundingBoxMin.x ? zoneXMin : NavMeshBoundingBoxMin.x; NavMeshBoundingBoxMax.x = zoneXMax > NavMeshBoundingBoxMax.x ? zoneXMax : NavMeshBoundingBoxMax.x; NavMeshBoundingBoxMin.z = zoneZMin < NavMeshBoundingBoxMin.z ? zoneZMin : NavMeshBoundingBoxMin.z; NavMeshBoundingBoxMax.z = zoneZMax > NavMeshBoundingBoxMax.z ? zoneZMax : NavMeshBoundingBoxMax.z; } Vector3 NavMeshBoundingBoxCenter = Vector3.Lerp(NavMeshBoundingBoxMin, NavMeshBoundingBoxMax, 0.5f); Vector3 NavMeshBoundingBox = NavMeshBoundingBoxMax - NavMeshBoundingBoxMin; // one monolithic nav mesh to encompass all zones recastGraph = (RecastGraph)AstarPath.active.astarData.AddGraph(typeof(RecastGraph)); SetNavMeshDefaults(recastGraph, NavMeshBoundingBoxCenter, NavMeshBoundingBox, multiTile); recastGraph.useCenterTileOnly = false; } AstarPath.active.astarData.data_cachedStartup = null; AstarPath.active.astarData.cacheStartup = false; recastGraph.generateFromInputMesh = false; AstarPath.active.showNavGraphs = true; if (doScan) { LevelHelper.FusionMenuScan(doActivateAndDeactivateGeoForGeneration); // build navmeshes from recast graph } return(true); }