Ejemplo n.º 1
0
        /// <summary>
        /// Checks if a chunk is nearby to or has a road.
        /// </summary>
        /// <param name="startProgress">Start progress.</param>
        public void CheckForRoad(float startProgress)
        {
            _hasCheckedForRoad = true;
            Road           road            = WorldManager.Instance.Road;
            DynamicTerrain terrain         = DynamicTerrain.Instance;
            Vector3        chunkPos        = transform.position;
            float          chunkSize       = WorldManager.Instance.ChunkSize;
            float          checkResolution = (1f - startProgress) * WorldManager.Instance.RoadPathCheckResolution;

            // Set boundaries for "near road" consideration
            Vector2 nearMin = new Vector2(chunkPos.x - chunkSize, chunkPos.z - chunkSize);
            Vector2 nearMax = new Vector2(chunkPos.x + chunkSize * 2f, chunkPos.z + chunkSize * 2f);

            // Set boundaries for "has road" consideration
            Vector2 hasMin = new Vector2(chunkPos.x, chunkPos.z);
            Vector2 hasMax = new Vector2(chunkPos.x + chunkSize, chunkPos.z + chunkSize);

            float progress = startProgress;

            while (progress <= 1f)
            {
                // Sample road and check distance to chunk
                Vector3 sample = road.GetPoint(progress);
                if (sample.x >= nearMin.x && sample.x <= nearMax.x &&
                    sample.z >= nearMin.y && sample.z <= nearMax.y)
                {
                    if (!_nearRoad)
                    {
                        gameObject.name += "|nearRoad";
                        terrain.AddCloseToRoadChunk(this);
                    }
                    _nearRoad = true;

                    // If near road, check if has road
                    if (sample.x >= hasMin.x && sample.x <= hasMax.x &&
                        sample.z >= hasMin.y && sample.z <= hasMax.y)
                    {
                        terrain.AddRoadChunk(this);
                        gameObject.name += "|hasRoad";
                        _grassEmitter.SetActive(false);
                        _hasRoad = true;
                        return;
                    }
                }
                progress += 1f / checkResolution;
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Resets necessary variables after de-pooling a chunk.
        /// </summary>
        public void Reuse(int x, int y)
        {
            DynamicTerrain terrain   = DynamicTerrain.Instance;
            VertexMap      vmap      = terrain.VertexMap;
            float          chunkSize = WorldManager.Instance.ChunkSize;

            // Update vars
            _x = x;
            _y = y;

            // Move chunk to appropriate position
            transform.position = new Vector3(x * chunkSize - chunkSize / 2f, 0f, y * chunkSize - chunkSize / 2f);

            // Update chunk name
            gameObject.name = "Chunk (" + x + "," + y + ") Position:" + transform.position.ToString();

            _priority = 0f;

            // Clear decoration list
            _decorations.Clear();

            // Register all vertices with vertex map
            // Move vertices, generate normals/colors
            for (int i = 0; i < _numVerts; i++)
            {
                // Get VMap coords
                IntVector2 coord = IntToV2(i);
                _coords[i] = coord;

                // Get corresponding vertex
                _mapVerts[i] = vmap.VertexAt(coord, true);

                // Get height from vertex
                UpdateVertex(i, _mapVerts[i].Height);
            }

            _hasCheckedForRoad = false;

            UpdateCollider();
        }
Ejemplo n.º 3
0
        public void SetHeight(float h)
        {
            // Skip locked vertices
            if (_locked || h == _height)
            {
                return;
            }

            _loaded = true;

            // Set height
            _height = h;

            _color.a = 0f;

            /*Vertex l = map.VertexAt(x-1,y);
             * color.a += (l != null ? Mathf.Abs (h - l.height) : 0f);
             *
             * Vertex r = map.VertexAt(x+1,y);
             * color.a += (r != null ? Mathf.Abs (h - r.height) : 0f);
             *
             * Vertex u = map.VertexAt(x,y+1);
             * color.a += (u != null ? Mathf.Abs (h - u.height) : 0f);
             *
             * Vertex d = map.VertexAt(x,y-1);
             * color.a += (d != null ? Mathf.Abs (h - d.height) : 0f);
             *
             * color.a /= (WorldManager.Instance.heightScale/10f);
             * color.a = Mathf.Clamp01(color.a);*/

            CalculateBlend2();

            int            index;
            DynamicTerrain terrain = DynamicTerrain.Instance;

            if (IsEdge(_x))
            {
                // Corner
                if (IsEdge(_y))
                {
                    Chunk ul = terrain.ChunkAt(ChunkMin(_x), ChunkMax(_y));
                    if (ul != null)
                    {
                        index = CoordToIndex(ul.X, ul.Y);
                        ul.UpdateVertex(index, _height, true);
                        ul.UpdateColor(index, _color);
                    }

                    Chunk ur = terrain.ChunkAt(ChunkMax(_x), ChunkMax(_y));
                    if (ur != null)
                    {
                        index = CoordToIndex(ur.X, ur.Y);
                        ur.UpdateVertex(index, _height, true);
                        ur.UpdateColor(index, _color);
                    }

                    Chunk dl = terrain.ChunkAt(ChunkMin(_x), ChunkMin(_y));
                    if (dl != null)
                    {
                        index = CoordToIndex(dl.X, dl.Y);
                        dl.UpdateVertex(index, _height, true);
                        dl.UpdateColor(index, _color);
                    }

                    Chunk dr = terrain.ChunkAt(ChunkMax(_x), ChunkMin(_y));
                    if (dr != null)
                    {
                        index = CoordToIndex(dr.X, dr.Y);
                        dr.UpdateVertex(index, _height, true);
                        dr.UpdateColor(index, _color);
                    }

                    // X edge
                }
                else
                {
                    Chunk left = terrain.ChunkAt(ChunkMin(_x), ChunkAt(_y));
                    if (left != null)
                    {
                        index = CoordToIndex(left.X, left.Y);
                        left.UpdateVertex(index, _height, true);
                        left.UpdateColor(index, _color);
                    }

                    Chunk right = terrain.ChunkAt(ChunkMax(_x), ChunkAt(_y));
                    if (right != null)
                    {
                        index = CoordToIndex(right.X, right.Y);
                        right.UpdateVertex(index, _height, true);
                        right.UpdateColor(index, _color);
                    }
                }

                // Y edge
            }
            else if (IsEdge(_y))
            {
                Chunk bottom = terrain.ChunkAt(ChunkAt(_x), ChunkMin(_y));
                if (bottom != null)
                {
                    index = CoordToIndex(bottom.X, bottom.Y);
                    bottom.UpdateVertex(index, _height, true);
                    bottom.UpdateColor(index, _color);
                }

                Chunk top = terrain.ChunkAt(ChunkAt(_x), ChunkMax(_y));
                if (top != null)
                {
                    index = CoordToIndex(top.X, top.Y);
                    top.UpdateVertex(index, _height, true);
                    top.UpdateColor(index, _color);
                }

                // No edge
            }
            else
            {
                Chunk chunk = terrain.ChunkAt(ChunkAt(_x), ChunkAt(_y));
                if (chunk != null)
                {
                    index = CoordToIndex(chunk.X, chunk.Y);
                    chunk.UpdateVertex(index, _height, false);
                    chunk.UpdateColor(index, _color);
                }
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Coroutine to update the vertices of a chunk.
        /// </summary>
        /// <returns>The verts.</returns>
        private IEnumerator UpdateVerts()
        {
            if (!GameManager.Instance.IsLoaded)
            {
                yield break;
            }

            _isUpdatingVerts = true;
            float          margin    = WorldManager.Instance.ChunkSize / 2;
            float          startTime = Time.realtimeSinceStartup;
            Vector3        playerPos = PlayerMovement.Instance.transform.position;
            Vector3        chunkPos  = transform.position;
            DynamicTerrain terrain   = DynamicTerrain.Instance;
            VertexMap      vmap      = terrain.VertexMap;

            int v = 0;

            for (; v < _numVerts; v++)
            {
                // Get VMap coordinates
                IntVector2 coord = _coords[v];

                // Get coresponding vertex
                Vertex vert = _mapVerts[v];

                // Update vertex height
                UpdateVertex(v, vert.Height);

                if (terrain.FreqData == null)
                {
                    yield break;
                }

                // If vertex is not locked and there is frequency data to use
                if (!vert.Locked)
                {
                    // Distance between player and vertex
                    Vector3 vertPos  = chunkPos + _verts[v];
                    float   distance = Vector3.Distance(vertPos, playerPos);

                    // If vertex is close enough
                    if (CheckDist(distance, WorldManager.Instance.VertexUpdateDistance, margin))
                    {
                        // Calculate new height
                        Vector3 angleVector = vertPos - playerPos;
                        float   angle       = Vector3.Angle(Vector3.right, angleVector);
                        float   linIntInput = angle / 360f;
                        float   newY        = terrain.FreqData.GetDataPoint(linIntInput) *
                                              WorldManager.Instance.HeightScale;

                        // If new height, set it
                        //if (newY != vmap.VertexAt(coord, false).height) vmap.SetHeight (coord, newY);
                        if (newY != 0f)
                        {
                            vmap.AddHeight(coord, newY);
                        }
                    }
                }

                if (v == _numVerts - 1)
                {
                    _isUpdatingVerts = false;
                    yield break;
                }
                else if (Time.realtimeSinceStartup - startTime > GameManager.TargetDeltaTime)
                {
                    yield return(null);

                    startTime = Time.realtimeSinceStartup;
                }
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Initializes a brand new chunk at x and y.
        /// </summary>
        public void Initialize(int x, int y)
        {
            DynamicTerrain terrain = DynamicTerrain.Instance;

            // Init vars
            _x = x;
            _y = y;

            VertexMap vmap      = terrain.VertexMap;
            int       chunkRes  = WorldManager.Instance.ChunkResolution;
            float     chunkSize = WorldManager.Instance.ChunkSize;

            // Generate vertices
            _verts    = CreateUniformVertexArray(chunkRes);
            _numVerts = _verts.Length;

            // Generate triangles
            _triangles = CreateSquareArrayTriangles(chunkRes);

            // Init normals
            _normals = new Vector3[_numVerts];

            // Generate UVs
            _uvs = CreateUniformUVArray(chunkRes);

            // Init colors
            _colors = new Color[_numVerts];

            // Init coords and mapVerts
            _coords   = new IntVector2[_numVerts];
            _mapVerts = new Vertex[_numVerts];

            // Build initial chunk mesh
            _mesh = CreateChunkMesh();

            // Assign mesh
            GetComponent <MeshFilter>().mesh = _mesh;

            // Move GameObject to appropriate position
            transform.position = new Vector3(x * chunkSize - chunkSize / 2f, 0f, y * chunkSize - chunkSize / 2f);

            // Initialize name
            gameObject.name = "Chunk (" + x + "," + y + ") Position:" + transform.position.ToString();

            // Init decorations list
            _decorations = new List <GameObject>();

            // Register all vertices with vertex map
            // Move vertices, generate normals/colors
            for (int i = 0; i < _numVerts; i++)
            {
                // Init normal/color
                _normals[i] = Vector3.up;
                _colors[i]  = Color.white;

                // Get VMap coords
                IntVector2 coord = IntToV2(i);
                _coords[i] = coord;

                // Get corresponding vertex
                _mapVerts[i] = vmap.VertexAt(coord, true);

                // If vertex exists, get height
                UpdateVertex(i, _mapVerts[i].Height);
                UpdateColor(i, _mapVerts[i].Color);
            }

            // Assign material
            MeshRenderer renderer = GetComponent <MeshRenderer>();

            renderer.sharedMaterial       = WorldManager.Instance.TerrainMaterial;
            renderer.shadowCastingMode    = UnityEngine.Rendering.ShadowCastingMode.On;
            renderer.reflectionProbeUsage = UnityEngine.Rendering.ReflectionProbeUsage.Off;

            // Assign collision mesh
            MeshCollider collider = GetComponent <MeshCollider>();

            collider.sharedMesh = _mesh;
            collider.convex     = false;

            // Init rigidbody
            Rigidbody rigidbody = GetComponent <Rigidbody>();

            rigidbody.freezeRotation = true;
            rigidbody.isKinematic    = true;
            rigidbody.useGravity     = false;
            rigidbody.constraints    = RigidbodyConstraints.FreezeAll;

            // Add grass system
            _grassEmitter = GameObject.Instantiate(WorldManager.Instance.GrassEmitterPrefab);
            _grassEmitter.transform.parent        = transform;
            _grassEmitter.transform.localPosition = Vector3.zero;

            // Randomize grass density
            ParticleSystem sys = _grassEmitter.GetComponent <ParticleSystem>();

            sys.maxParticles = UnityEngine.Random.Range(0, WorldManager.Instance.GrassPerChunk);
            sys.playOnAwake  = true;

            // Assign particle system emission shape
            ParticleSystem.ShapeModule shape = sys.shape;
            shape.mesh = _mesh;

            // Assign particle system emission rate
            ParticleSystem.EmissionModule emit = sys.emission;
            emit.rate = new ParticleSystem.MinMaxCurve(WorldManager.Instance.DecorationsPerStep);

            UpdateCollider();
        }