예제 #1
0
    public void CalculateAllZonesMinMax(out Vector3 outMin, out Vector3 outMax)
    {
        Transform zonesRoot = GetZonesRoot();

        // set min to highest possible x,z initially and max to lowest possible x,z initially (y isn't set)
        outMin = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
        outMax = new Vector3(-float.MaxValue, -float.MaxValue, -float.MaxValue);

        Vector3 tempMin = new Vector3();
        Vector3 tempMax = new Vector3();

        // walk zones to generate the bounding box encompassing the entire level (all zones)
        foreach (Transform zone in zonesRoot.transform)
        {
            ZoneDescriptor.CalculateZoneMinAndMax(ref tempMin, ref tempMax, zone);

            outMin.x = tempMin.x < outMin.x ? tempMin.x : outMin.x;
            outMax.x = tempMax.x > outMax.x ? tempMax.x : outMax.x;

            outMin.y = tempMin.y < outMin.y ? tempMin.y : outMin.y;
            outMax.y = tempMax.y > outMax.y ? tempMax.y : outMax.y;

            outMin.z = tempMin.z < outMin.z ? tempMin.z : outMin.z;
            outMax.z = tempMax.z > outMax.z ? tempMax.z : outMax.z;
        }
    }
예제 #2
0
 void Awake()
 {
     _zoneDescriptor = gameObject.GetComponent <ZoneDescriptor>();
     if (transform != null && transform.parent != null && transform.parent.parent != null)
     {
         _helper = transform.parent.parent.gameObject.GetComponent <GridHelper>();
     }
 }
예제 #3
0
        // generate a nav mesh with one tile per zone
        protected void GenerateTilesForZones(AStarPathfindingWalkableArea[] walkAreas)
        {
            if (null == walkAreas || 0 == walkAreas.Length)
            {
                EB.Debug.LogWarning("GenerateTilesForZones: walkAreas is empty");
                return;
            }

            LevelHelper levelHelper = GameObject.FindObjectOfType(typeof(LevelHelper)) as LevelHelper;

            if (null == levelHelper)
            {
                EB.Debug.LogWarning("GenerateTilesForZones: LevelHelper not found");
                return;
            }

            Vector3 NavMeshBoundingBoxMin;
            Vector3 NavMeshBoundingBoxMax;

            levelHelper.CalculateAllZonesMinMax(out NavMeshBoundingBoxMin, out NavMeshBoundingBoxMax);

            // set the entire bounds and center of the recast graph
            forcedBoundsSize   = NavMeshBoundingBoxMax - NavMeshBoundingBoxMin;
            forcedBoundsCenter = NavMeshBoundingBoxMin + (forcedBoundsSize * 0.5f);

            tileSizeX = tileSizeZ = (int)(EditorVars.GridSize / cellSize);             // this line sets the tile size so that each tile will hold the size of a zone
            CalculateNumberOfTiles(ref tileXCount, ref tileZCount);

#if DEBUG
            int correctTilesXCount = (Mathf.CeilToInt(forcedBoundsSize.x / EditorVars.GridSize));             // this would fail if GridSize is less than 1f
            int correctTilesZCount = (Mathf.CeilToInt(forcedBoundsSize.z / EditorVars.GridSize));             // this would fail if GridSize is less than 1f
            if (correctTilesXCount != tileXCount || correctTilesZCount != tileZCount)
            {
                EB.Debug.LogError("Incorrect number of tiles generated");
            }
#endif
            tiles = new NavmeshTile[tileXCount * tileZCount];

            // ignore this setting
            scanEmptyGraph = false;

            Vector3 tempZoneMin = new Vector3();
            Vector3 tempZoneMax = new Vector3();

            // go over all the walkable areas and put there mesh into a tile
            foreach (AStarPathfindingWalkableArea walk in walkAreas)
            {
                ZoneDescriptor zoneDescriptor = (ZoneDescriptor)GameUtils.FindFirstComponentUpwards <ZoneDescriptor>(walk.transform);
                if (zoneDescriptor != null)
                {
                    ZoneDescriptor.CalculateZoneMinAndMax(ref tempZoneMin, ref tempZoneMax, zoneDescriptor.gameObject.transform);

                    // 1f is added to avoid floating point inacuracy (avoids 63.999/64 = 0, 64.99/64=1 which is correct)
                    int z = (int)(((tempZoneMin.z + 1f) - NavMeshBoundingBoxMin.z) / EditorVars.GridSize);
                    int x = (int)(((tempZoneMin.x + 1f) - NavMeshBoundingBoxMin.x) / EditorVars.GridSize);

                    MeshFilter meshFilter = walk.gameObject.GetComponent <MeshFilter>();
                    if (null != meshFilter.sharedMesh)
                    {
                        // the Vector3 vertices in the mesh need to be converted to the APP Int3 format
                        Int3[] Int3Verts = new Int3[meshFilter.sharedMesh.vertices.Length];
                        for (int i = 0; i < Int3Verts.Length; ++i)
                        {
                            Vector3 tempVert = new Vector3(meshFilter.sharedMesh.vertices[i].x, meshFilter.sharedMesh.vertices[i].y, meshFilter.sharedMesh.vertices[i].z);
                            tempVert = walk.transform.TransformPoint(tempVert);                             // get the world space position, rather than local space

                            // clamp the verts to the edges of the zone boundaries if they are close, this is so that the different tiles are linked together accurately
                            const float Tol = 0.01f;
                            tempVert.x = (tempVert.x <= tempZoneMin.x + Tol) ? tempZoneMin.x : tempVert.x;
                            tempVert.x = (tempVert.x >= tempZoneMax.x - Tol) ? tempZoneMax.x : tempVert.x;

                            tempVert.z = (tempVert.z <= tempZoneMin.z + Tol) ? tempZoneMin.z : tempVert.z;
                            tempVert.z = (tempVert.z >= tempZoneMax.z - Tol) ? tempZoneMax.z : tempVert.z;

                            Int3Verts[i] = (Int3)tempVert;
                        }
                        NavmeshTile tile = CreateTile(meshFilter.sharedMesh.triangles, Int3Verts, x, z);
                        tiles[Convert2DArrayCoordTo1DArrayCoord(x, z, tileXCount)] = tile;
                    }
                }
            }

            //Assign graph index to nodes
            uint graphIndex = (uint)AstarPath.active.astarData.GetGraphIndex(this);
            GraphNodeDelegateCancelable del = delegate(GraphNode n)
            {
                n.GraphIndex = graphIndex;
                return(true);
            };
            GetNodes(del);

            // connect each tile to one and other
            for (int z = 0; z < tileZCount; z++)
            {
                for (int x = 0; x < tileXCount; x++)
                {
                    // make sure all the tiles which might be considered, have tiles created
                    CreateAndAddEmptyTileIfNonExists(x, z);
                    CreateAndAddEmptyTileIfNonExists(x + 1, z);
                    CreateAndAddEmptyTileIfNonExists(x, z + 1);

                    if (x < tileXCount - 1)
                    {
                        ConnectTiles(tiles[Convert2DArrayCoordTo1DArrayCoord(x, z, tileXCount)], tiles[Convert2DArrayCoordTo1DArrayCoord(x + 1, z, tileXCount)]);
                    }
                    if (z < tileZCount - 1)
                    {
                        ConnectTiles(tiles[Convert2DArrayCoordTo1DArrayCoord(x, z, tileXCount)], tiles[Convert2DArrayCoordTo1DArrayCoord(x, z + 1, tileXCount)]);
                    }
                }
            }
        }