示例#1
0
        public void Populate()
        {
#if UNITY_EDITOR
            if (Debuger_K.useProfiler)
            {
                profiler = new NavmeshProfiler(gridPosition.x, gridPosition.z);
                profiler.StartProfile();
            }
#endif
            //getting target space
            YRangeInt chunkSize = GetChunkSizes();
            chunkData = new ChunkData(gridPosition.x, gridPosition.z, chunkSize.min, chunkSize.max);
            GetInitialValues();   //getting all public values to support further work
            PopulateCollectors(); //getting colliders to make navmesh from them
        }
        //all things here are used in UNITY main thread so things here can use unity API

        /// <summary>
        /// Function to populate template with further information. Here goes information about colliders and also usage of compute shaders if it enabled
        /// </summary>
        public void PopulateTemplate()
        {
#if UNITY_EDITOR
            if (Debuger_K.useProfiler)
            {
                profiler = new NavmeshProfiler(gridPosition.x, gridPosition.z);
                profiler.StartProfile();
            }
#endif

            //getting target space
            YRangeInt chunkSize = GetChunkSizes();                                                   //get chunk height size
            chunkData = new ChunkData(gridPosition.x, gridPosition.z, chunkSize.min, chunkSize.max); //create chunk data so further code are a bit more readable
            GetInitialValues();                                                                      //getting all public values listed on top to support further work
            PopulateCollectors();                                                                    //getting colliders to make navmesh from them
        }
        /// <summary>
        ///check if chunk size already defined. if true then return it. if not then it uses unity API to get it
        /// </summary>
        /// <returns>chunk Y range divided by grid size</returns>
        private YRangeInt GetChunkSizes()
        {
            YRangeInt result;

            //if this chunk data already exist then return it
            lock (chunkRange) {
                if (chunkRange.TryGetValue(gridPosition, out result))
                {
                    return(result);
                }
            }
            //if not then create it

            //guessing height if not provided
            float   gridSize = PathFinder.gridSize;
            float   e        = gridSize * 0.5f;
            Vector3 v3e      = new Vector3(e, e, e);

            float currentX = gridPosition.x * gridSize + e;
            float currentZ = gridPosition.z * gridSize + e;

            float cyrMinY      = PathFinder.gridLowest * gridSize;
            float cyrMaxY      = PathFinder.gridHighest * gridSize;
            float castDistance = Math.Abs(cyrMaxY - cyrMinY);

            Vector3 sMax = new Vector3(currentX, cyrMaxY, currentZ);

            LayerMask mask = properties.includedLayers;
            int       minY, maxY;

            RaycastHit[] hits = Physics.BoxCastAll(sMax, v3e, Vector3.down, Quaternion.identity, castDistance, mask);

            if (hits.Length > 0)
            {
                float highest = hits[0].point.y;
                float lowest  = hits[0].point.y;

                if (hits.Length > 1)
                {
                    for (int i = 1; i < hits.Length; i++)
                    {
                        if (hits[i].point.y > highest)
                        {
                            highest = hits[i].point.y;
                        }

                        if (hits[i].point.y < lowest)
                        {
                            lowest = hits[i].point.y;
                        }
                    }
                }

                minY = (int)(lowest / gridSize) - 1;
                maxY = (int)(highest / gridSize);
            }
            else
            {
                minY = 0;
                maxY = 0;
            }

            result = new YRangeInt(minY, maxY);

            lock (chunkRange)
                chunkRange[gridPosition] = result;

            return(result);
        }
 public bool Equals(YRangeInt other)
 {
     return(other == this);
 }
 public ChunkData(XZPosInt pos, YRangeInt range) : this(pos.x, pos.z, range.min, range.max)
 {
 }
        public static void Deserialize(SerializedNavmesh target, AgentProperties properties)
        {
            //remove all data if it exist
            lock (_chunkData) {
                List <XZPosInt> removeList = new List <XZPosInt>();
                foreach (var graph in _chunkData.Values)
                {
                    if (graph.properties == properties)
                    {
                        removeList.Add(graph.gridPosition);
                    }
                }
                foreach (var pos in removeList)
                {
                    _chunkData.Remove(new GeneralXZData(pos, properties));
                }

                NavmeshLayerDeserializer deserializer = new NavmeshLayerDeserializer(target, properties);
                var deserializedStuff = deserializer.Deserialize();

                //create chunk if needed and clamp size if it outside
                foreach (var deserialized in deserializedStuff)
                {
                    XZPosInt  pos = deserialized.chunkPosition;
                    YRangeInt curRange;
                    if (_chunkRange.TryGetValue(pos, out curRange))
                    {
                        _chunkRange[pos] = new YRangeInt(
                            Mathf.Min(curRange.min, deserialized.chunkMinY),
                            Mathf.Max(curRange.max, deserialized.chunkMaxY));
                    }
                    else
                    {
                        _chunkRange.Add(pos, new YRangeInt(deserialized.chunkMinY, deserialized.chunkMaxY));
                    }
                }

                List <Graph> graphs = new List <Graph>();
                //put graphs inside chunks
                foreach (var deserialized in deserializedStuff)
                {
                    //Chunk chunk = _chunkData[deserialized.chunkPosition];

                    XZPosInt  pos = deserialized.chunkPosition;
                    YRangeInt ran = _chunkRange[pos];

                    Graph graph = deserialized.graph;
                    graph.SetChunkAndProperties(new ChunkData(pos, ran), properties);
                    _chunkData[new GeneralXZData(pos, properties)] = graph;
                    graph.SetAsCanBeUsed();
                    graphs.Add(graph);
                }

                //connect chunks
                foreach (var graph in graphs)
                {
                    for (int i = 0; i < 4; i++)
                    {
                        Graph neighbour;
                        if (TryGetGraphFrom(graph.gridPosition, (Directions)i, properties, out neighbour))
                        {
                            graph.SetNeighbour((Directions)i, neighbour);
                        }
                    }
#if UNITY_EDITOR
                    if (Debuger_K.doDebug)
                    {
                        graph.DebugGraph();
                    }
#endif
                }
            }
        }