Search Unity

Adding self-constructed diamond-square algorithm to the GameObject->3D Object->Terrain

Discussion in 'Scripting' started by BrainOverFlow, Aug 20, 2017.

  1. BrainOverFlow

    BrainOverFlow

    Joined:
    Jul 26, 2017
    Posts:
    15
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class DiamondSquare : MonoBehaviour {
    6.  
    7.     public TerrainData TerrainData;
    8.  
    9.     Mesh m;
    10.  
    11.     // Length of the square
    12.     public float length;
    13.     // Num of vertices in one side
    14.     public int vertNum;
    15.     // Max height
    16.     public float height;
    17.  
    18.     Vector3[] vertices;
    19.  
    20.     void Start () {
    21.         m = GetComponent<MeshFilter>().mesh;
    22.         CreateTerrian();
    23.     }
    24.    
    25.     void CreateTerrian () {
    26.  
    27.         m.name = "Terrian";
    28.  
    29.         // Num of the phase
    30.         int division = vertNum - 1;
    31.  
    32.         float halfLength = length / 2;
    33.  
    34.         // The length of the smallest square
    35.         float singleLength = length / division;
    36.  
    37.         int vertCount = vertNum * vertNum;
    38.  
    39.         // All the vertices of the terrian
    40.         vertices = new Vector3[vertCount];
    41.  
    42.         Vector2[] uvs = new Vector2[vertCount];
    43.  
    44.         // Index of all the triangles
    45.         int[] triVertex = new int[vertNum * vertNum * 6];
    46.         int triIndex = 0;
    47.  
    48.         for (int i = 0; i < vertNum; i++) {
    49.             for (int j = 0; j < vertNum; j++) {
    50.  
    51.                 vertices[i * vertNum + j] = new Vector3(-halfLength + singleLength * j, 0, halfLength - singleLength * i);
    52.                 uvs[i * vertNum + j] = new Vector2((float)i / division, (float)j / division);
    53.  
    54.                 if (i < division && j < division) {
    55.                     int topLeft = i * vertNum + j;
    56.                     int botLeft = (i + 1) * vertNum + j;
    57.                     int topRight = i * vertNum + j + 1;
    58.                     int botRight = (i + 1) * vertNum + j + 1;
    59.  
    60.                     // Topright tri
    61.                     triVertex[triIndex++] = topLeft;
    62.                     triVertex[triIndex++] = topRight;
    63.                     triVertex[triIndex++] = botRight;
    64.                     // Botleft tri
    65.                     triVertex[triIndex++] = topLeft;
    66.                     triVertex[triIndex++] = botRight;
    67.                     triVertex[triIndex++] = botLeft;
    68.                 }
    69.             }
    70.         }
    71.  
    72.         vertices[0].y = Random.Range(-height, height);
    73.         vertices[division].y = Random.Range(-height, height);
    74.         vertices[vertCount - 1].y = Random.Range(-height, height);
    75.         vertices[vertCount - division - 1].y = Random.Range(-height, height);
    76.            
    77.         int iteration = (int)Mathf.Log(division, 2);
    78.         int numSquare = 1;
    79.         int squareSize = division;
    80.  
    81.         for (int i = 0; i < iteration; i++) {
    82.             int row = 0;
    83.             for (int j = 0; j < numSquare; j++) {
    84.                 int column = 0;
    85.                 for (int k = 0; k < numSquare; k++) {
    86.                     diamondSquare(row, column, squareSize, height);
    87.                     column += squareSize;
    88.                 }
    89.                 row += squareSize;
    90.             }
    91.             squareSize /= 2;
    92.             numSquare *= 2;
    93.             height *= 0.5f;
    94.         }
    95.  
    96.         m.vertices = vertices;
    97.         m.uv = uvs;
    98.         m.triangles = triVertex;
    99.         m.RecalculateBounds();
    100.         m.RecalculateNormals();
    101.     }
    102.  
    103.     void diamondSquare (int row, int column, int squareSize, float height) {
    104.  
    105.         int halfSize = squareSize / 2;
    106.         int topLeft = row * vertNum + column;
    107.         int topRight = topLeft + squareSize;
    108.         int botLeft = topLeft + vertNum * squareSize;
    109.         int botRight = botLeft + squareSize;
    110.         int topMid = (topLeft + topRight) / 2;
    111.         int botMid = (botLeft + botRight) / 2;
    112.         int leftMid = (topLeft + botLeft) / 2;
    113.         int rightMid = (topRight + botRight) / 2;
    114.         int mid = (topLeft + botRight) / 2;
    115.  
    116.         vertices[mid].y = (vertices[topLeft].y + vertices[topRight].y + vertices[botLeft].y + vertices[botRight].y) * 0.25f + Random.Range(-height, height);
    117.  
    118.         vertices[topMid].y = (vertices[topLeft].y + vertices[topRight].y + vertices[mid].y) / 3 + Random.Range(-height, height);
    119.         vertices[botMid].y = (vertices[botLeft].y + vertices[botRight].y + vertices[mid].y) / 3 + Random.Range(-height, height);
    120.         vertices[leftMid].y = (vertices[topLeft].y + vertices[botLeft].y + vertices[mid].y) / 3 + Random.Range(-height, height);
    121.         vertices[rightMid].y = (vertices[topRight].y + vertices[botRight].y + vertices[mid].y) / 3 + Random.Range(-height, height);
    122.     }
    123.    
    124. }
    125.  
    This is my own diamond-square algorithm attached to a GameObject->EmptyGameObject

    I just want to attach it with the Terrain type Object and make use of it. I have difficulty modify the code to suit the type Terrain given by unity. Could any one can help me with this?
     
  2. BrainOverFlow

    BrainOverFlow

    Joined:
    Jul 26, 2017
    Posts:
    15
    The code itself basicly just create a empty squre-form area and randomly generate the moutrain like terrain. But for the Terrain type given by unity, the empty squre-form area is already a given. I just need to make use the function void diamondSquare (int row, int column, int squareSize, float height); But I don't know how to appply it.:(