Search Unity

Question Probuilder flatten terrain over time

Discussion in 'World Building' started by stychu, Feb 10, 2021.

  1. stychu

    stychu

    Joined:
    May 9, 2016
    Posts:
    62
    Hello there,

    I'm trying to make some kind of animation for flattening the terrain over some x period of time.
    But unfortunately, my terrain flattens almost at a constant speed regardless of the time it should take.

    So pretty much no matter what duration I set it flattens really quick and I have to wait for the Debug.log to fire rest of the time. Whereas I would like it to flatten at the speed of duration so it really takes some x seconds before it's flattened

    My code:

    Code (CSharp):
    1. IEnumerator FlattenTerrain(float duration) {
    2.     float time = 0;
    3.     Vertex[] vertices = m_Mesh.GetVertices();
    4.  
    5.    // lerp vertices to 0 over time
    6.     while (time < duration) {
    7.       foreach (Vertex vertex in vertices) {
    8.         if (vertex.position.y <= Mathf.Epsilon)
    9.           continue;
    10.  
    11.         Vector3 newPosition = vertex.position;
    12.         newPosition.y = Mathf.Lerp(vertex.position.y, 0, time / duration);
    13.  
    14.         vertex.position = newPosition;
    15.       }
    16.  
    17.       time += Time.deltaTime;
    18.  
    19.       m_Mesh.SetVertices(vertices);
    20.       m_Mesh.ToMesh();
    21.       m_Mesh.Refresh();
    22.  
    23.       yield return null;
    24.     }
    25.  
    26.   // set vertices exactly to 0 because of overshoot
    27.     Vertex[] flattenedVertices = m_Mesh.GetVertices()
    28.      .Select(
    29.         vertex => {
    30.           Vector3 pos = vertex.position;
    31.           vertex.position = new Vector3(pos.x, 0, pos.z);
    32.  
    33.           return vertex;
    34.         }
    35.       )
    36.      .ToArray();
    37.  
    38.     m_Mesh.SetVertices(flattenedVertices);
    39.     m_Mesh.ToMesh();
    40.     m_Mesh.Refresh();
    41.  
    42.     MeshUtility.CollapseSharedVertices(m_Mesh.GetComponent<MeshFilter>().sharedMesh);
    43.     Debug.Log("VAR");
    44.   }

    Attached gif -> 2 seconds duration and terrain flattens crazy fast instead over time
    UdYa7LxzPX.gif
     
  2. stychu

    stychu

    Joined:
    May 9, 2016
    Posts:
    62
    I got something better but still I don't know how to incorporate Time into the flattening. Now I can flatten at some speed but can't figure out how to add time variable here so It would really take some X time to flatten..


    Code (CSharp):
    1.   private IEnumerator FlattenTerrain(float flattenSpeed) {
    2.     float time = 0;
    3.     float verticesLeft = float.MaxValue;
    4.  
    5.     Vertex[] vertices = m_Mesh.GetVertices();
    6.  
    7.     while (verticesLeft >= Mathf.Epsilon) {
    8.       foreach (Vertex vertex in vertices) {
    9.         if (vertex.position.y <= Mathf.Epsilon)
    10.           continue;
    11.  
    12.         Vector3 startPos = vertex.position;
    13.         Vector3 endPos = new Vector3(startPos.x, 0, startPos.z);
    14.  
    15.         float distCovered = time * flattenSpeed;
    16.         float fractionOfJourney = distCovered / Vector3.Distance(startPos, endPos);
    17.  
    18.         vertex.position = Vector3.Lerp(startPos, endPos, fractionOfJourney);
    19.       }
    20.  
    21.       time += Time.deltaTime;
    22.  
    23.       m_Mesh.SetVertices(vertices);
    24.       m_Mesh.ToMesh();
    25.       m_Mesh.Refresh();
    26.  
    27.       yield return null;
    28.  
    29.       verticesLeft = vertices.Sum(vertex => vertex.position.y);
    30.     }
    31.  
    32.     Vertex[] flattenedVertices = m_Mesh.GetVertices()
    33.      .Select(
    34.         vertex => {
    35.           Vector3 pos = vertex.position;
    36.           vertex.position = new Vector3(pos.x, 0, pos.z);
    37.  
    38.           return vertex;
    39.         }
    40.       )
    41.      .ToArray();
    42.  
    43.     m_Mesh.SetVertices(flattenedVertices);
    44.     m_Mesh.ToMesh();
    45.     m_Mesh.Refresh();
    46.  
    47.     MeshUtility.CollapseSharedVertices(m_Mesh.GetComponent<MeshFilter>().sharedMesh);
    48.  
    49.     StopCoroutine(flattenRoutine);
    50.   }
    51. }