Ejemplo n.º 1
0
        public JobHandle OnUpdate(JobHandle inputDeps)
        {
            if (CrowdController != null)
            {
                inputDeps = CrowdController.OnUpdate(AiNavSystem, inputDeps);
            }


            if (!Building)
            {
                if (TilesSavedStatus[0] == 1)
                {
                    TilesSavedStatus[0] = 0;
                    OnBuildCompleted?.Invoke(Config.SurfaceId);
                }

                if (Builder.HasTilesToBuild)
                {
                    Watch    = System.Diagnostics.Stopwatch.StartNew();
                    Building = true;
                    Builder.GetDirtyTileBounds(TilesToBuild);
                    Builder.ClearTilesToBuild();
                    RebuiltTiles.Clear();
                    UnityEngine.Debug.LogFormat("Building {0} tiles", TilesToBuild.Count);
                }

                if (!Building)
                {
                    HandlesToWaitFor.Clear();
                }

                return(inputDeps);
            }

            int status = CurrentTileStatus[0];

            // No tiles building
            if (status == 0)
            {
                for (int i = 0; i < Config.BatchSize; i++)
                {
                    if (TilesToBuild.TryDequeue(out NavMeshTileBounds tileBounds))
                    {
                        tileBounds.Bounds.min.y = -1024f;
                        tileBounds.Bounds.max.y = 1024f;
                        tileBounds.Bounds.Expand(2f);

                        NavMeshNativeInputBuilder inputBuilder = new NavMeshNativeInputBuilder(tileBounds);

                        if (Config.IncludeUnityPhysicsGeometry)
                        {
                            CollectGeometryJob collectGeometryJob = new CollectGeometryJob
                            {
                                IncludeMask    = Config.IncludeMask,
                                BoxFilters     = BoxFilters,
                                TileBounds     = tileBounds,
                                InputBuilder   = inputBuilder,
                                GeometryFilter = Config.GeometryFilter
                            };
                            inputDeps = collectGeometryJob.ScheduleSingle(AiNavSystem, inputDeps);
                        }


                        CollectFromMeshSourcesJob collectFromMeshSources = new CollectFromMeshSourcesJob
                        {
                            IncludeMask       = Config.IncludeMask,
                            MeshSourceMap     = MeshSourceMap,
                            TileBounds        = tileBounds,
                            InputBuilder      = inputBuilder,
                            SharedMeshSources = AiNavSystem.MeshDatas
                        };
                        inputDeps = collectFromMeshSources.Schedule(inputDeps);

                        CurrentInputBuilders.Add(inputBuilder);
                        CurrentTileStatus[0] = 1;
                    }
                }

                if (CurrentInputBuilders.Count == 0)
                {
                    if (Building)
                    {
                        CurrentTileStatus[0] = 0;

                        if (RebuiltTiles.Count > 0)
                        {
                            var handle = JobHandle.CombineDependencies(HandlesToWaitFor);
                            handle.Complete();

                            foreach (NavMeshTile rebuiltTile in RebuiltTiles.Values)
                            {
                                Tiles[rebuiltTile.Coord] = rebuiltTile;
                                NavMesh.AddOrReplaceTile(rebuiltTile.Data);
                            }

                            SaveTilesJob saveTilesJob = new SaveTilesJob
                            {
                                TilesSavedStatus = TilesSavedStatus,
                                SurfaceId        = Config.SurfaceId,
                                TilesPtr         = TilesPtr
                            };
                            inputDeps = saveTilesJob.Schedule(inputDeps);
                        }

                        Watch.Stop();
                        UnityEngine.Debug.LogFormat("Build finished in {0} tilecount {1}", Watch.ElapsedMilliseconds, RebuiltTiles.Count);
                        RebuiltTiles.Clear();
                        Building = false;
                    }
                }

                return(inputDeps);
            }

            // collection done, build
            if (status == 1)
            {
                foreach (var inputBuilder in CurrentInputBuilders)
                {
                    if (inputBuilder.Vertices.Length > 0)
                    {
                        BuildInputs.Enqueue(inputBuilder.ToBuildInput());
                    }
                }

                BuildTileJob buildTileJob = new BuildTileJob
                {
                    AgentSettings   = Builder.AgentSettings,
                    BuildSettings   = Builder.BuildSettings,
                    BuildInputs     = BuildInputs,
                    RebuiltTilesPtr = RebuiltTilesPtr,
                    SurfaceId       = Config.SurfaceId
                };
                inputDeps = buildTileJob.Schedule(inputDeps);

                CurrentTileStatus[0] = 2;
                return(inputDeps);
            }

            // Tile builds finished
            if (status == 2)
            {
                foreach (var inputBuilder in CurrentInputBuilders)
                {
                    inputBuilder.Dispose();
                }
                CurrentInputBuilders.Clear();
                CurrentTileStatus[0] = 0;
            }

            return(inputDeps);
        }