Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Cipher_Ultra · Sep 04, 2014 at 05:23 PM · javascriptprogrammingbeginnerproceduralmap

Procedural Terrain - Diamond Square Algorithm

Hi,

I've been trying for the last 5 days to produce a simple procedural terrain in unity using the diamond square algorithm.

Unfortunately every example (12 at my last count) that I've found online is too complicated or has some kind of error in Unity. (i note that apparently the 'Java' in Unity is not the same as actual Java code).

My last attempt is from scratch and tries to emulate the example here My code below starts with 4 corners, then finds the middle point and height, followed by the 'sides' (north, east, south, west). After the first iteration it is supposed to 'reset' and find the middle & sides of 4 smaller squares.

As you can see in the picture, the first iteration works ok.

alt text

But, I can't get the 'reset' (which moves to the next level of detail) or 'next' (which moves to the next square) to actually change their values and start the iteration again.

Can anyone please help or advise?

Code is in JAVA.

 function Start () {
     // map size
     var res = 65;
     var step = (res-1);
     var tData = GetComponent(Terrain).terrainData;
     tData.heightmapResolution = res;
      
     var heights = new float[res, res];
     // bumpyness
     var bumpyness = 0.03;
     
     var width = res;
     var length = res;
     var reset = 0;
     var next = 1;
 
       //square
     
         
             //if(reset == 0){
              //heights[x,y] = Random.Range(0.1-bumpyness, 0.1+bumpyness);
              //}
              if(reset == 0){
              heights[0,0] = Random.Range(0.1-bumpyness, 0.1+bumpyness);
              heights[step,0] = Random.Range(0.1-bumpyness, 0.1+bumpyness);
              heights[0,step] = Random.Range(0.1-bumpyness, 0.1+bumpyness);
              heights[step,step] = Random.Range(0.1-bumpyness, 0.1+bumpyness);
              }
              
          
          for(next = 1; step*next < res; next++)
          {
              
              
              
                  var x = step*next;
                  var y = step*next;
                  
                  
                  var A = heights[x-step, y-step];
                  var B = heights[x, y-step];
                  var C = heights[x-step, y];
                  var D = heights[x, y];
              
                  var Middle = (A+B+C+D)/4 + Random.Range(-bumpyness,bumpyness);
                  heights[x-step/2, y-step/2] = Middle;
              
             
                  var N = (A+B)/2 + Random.Range(-bumpyness,bumpyness);
                  heights[x-step/2, y-step] = N;
                  var E = (B+D)/2 + Random.Range(-bumpyness,bumpyness);
                  heights[x, y-step/2] = E;
                  var S = (C+D)/2 + Random.Range(-bumpyness,bumpyness);
                  heights[x-step/2, y] = S;
                  var W = (A+C)/2 + Random.Range(-bumpyness,bumpyness);
                  heights[x-step, y-step/2] = W;
                  
                  
                  
                  print(next);
              
 
              
         }
         
         for(reset = 1; step*next >= res && reset < 3; reset++){
              
           print(reset); step = step/2; x = 0; y = 0; next = 1;
         
          
          }
          
          
                                               
      tData.SetHeights (0, 0, heights);
 
    }
 
   


procedural.jpg (311.8 kB)
Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image HuskyPanda213 · Sep 05, 2014 at 10:07 PM 0
Share

Please don't say the code is in JAVA, it is clearly not in java. Java, JavaScript, and UnityScript (unity javascript) are all different.

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by AlucardJay · Sep 04, 2014 at 08:30 PM

I had a look at the code derived from Notchs Ludum Dare entry, but could not get it to work, so am unable to help with your current code :(

However, here is an implementation using code derived from : http://stackoverflow.com/questions/2755750/diamond-square-algorithm

This generates a new terrain every time it is run, but is really hard to control what type of terrain will be generated as it uses a random value for 'bumpiness'. Press space while running to generate a new terrain :

 #pragma strict
 
 
 public var terrain : Terrain;
 public var size : int = 513;
 
 var dataArray : float[,];
 
 
 function Start() 
 {
     DiamondSquareDataArray();
 }
 
 
 function Update() 
 {
     if ( Input.GetKeyDown( KeyCode.Space ) )
         DiamondSquareDataArray();
 }
 
 
 // http://stackoverflow.com/questions/2755750/diamond-square-algorithm
 
 function DiamondSquareDataArray() 
 {
     // declare the data array
     dataArray = new float[ size, size ];
     
     // set the 4 corners
     dataArray[ 0, 0 ] = 1;
     dataArray[ size - 1, 0 ] = 1;
     dataArray[ 0, size - 1 ] = 1;
     dataArray[ size - 1, size - 1 ] = 1;
     
     
     var val : float;
     var rnd : float;
     
     var h : float = 0.5;
     
     var sideLength : int;
     var x : int;
     var y : int;
     
     var halfSide : int;
     
     
     for ( sideLength = size - 1; sideLength >= 2; sideLength /= 2 )
     {
         halfSide = sideLength / 2;
         
         // square values
         for ( x = 0; x < size - 1; x += sideLength )
         {
             for ( y = 0; y < size - 1; y += sideLength )
             {
                 val = dataArray[ x, y ];
                 val += dataArray[ x + sideLength, y ];
                 val += dataArray[ x, y + sideLength ];
                 val += dataArray[ x + sideLength, y + sideLength ];
                 
                 val /= 4.0;
                 
                 // add random
                 rnd = ( Random.value * 2.0 * h ) - h;
                 val = Mathf.Clamp01( val + rnd );
                 
                 dataArray[ x + halfSide, y + halfSide ] = val;
             }
         }
         
         // diamond values
         for ( x = 0; x < size - 1; x += halfSide )
         {
             for ( y = ( x + halfSide ) % sideLength; y < size - 1; y += sideLength )
             {
                 val = dataArray[ ( x - halfSide + size - 1 ) % ( size - 1 ), y ];
                 val += dataArray[ ( x + halfSide ) % ( size - 1 ), y ];
                 val += dataArray[ x, ( y + halfSide ) % ( size - 1 ) ];
                 val += dataArray[ x, ( y - halfSide + size - 1 ) % ( size - 1 ) ];
                 
                 val /= 4.0;
                 
                 // add random
                 rnd = ( Random.value * 2.0 * h ) - h;
                 val = Mathf.Clamp01( val + rnd );
                 
                 dataArray[ x, y ] = val;
                 
                 if ( x == 0 ) dataArray[ size - 1, y ] = val;
                   if ( y == 0 ) dataArray[ x, size - 1 ] = val;
             }
         }
         
         
         h /= 2.0; // cannot include this in for loop (dont know how in uJS)
     }
     
     
     Debug.Log( "DiamondSquareDataArray completed" );
     
     // Generate Terrain using dataArray as height values
     GenerateTerrain();
 }
 
 
 function GenerateTerrain() 
 {
     if ( !terrain )
         return;
     
     if ( terrain.terrainData.heightmapResolution != size )
         terrain.terrainData.heightmapResolution = size;
     
     terrain.terrainData.SetHeights( 0, 0, dataArray );
 }


Alternative :

If you are looking at creating fractal looking terrain, have you considered using Perlin Noise? You have much more control with the terrain generated. Modify the variables in the inspector while running then press space to generate a new terrain :

 #pragma strict
 
 
 public var terrain : Terrain;
 public var size : int = 513;
 
 public var offset : Vector2 = Vector2.zero; // where does the sample start?
 public var octaves : int = 8; // how many iteration for fractal?
 public var frq : float = 100.0; // how smooth/rough? (low = rough, high = smooth)
 public var amp : float = 0.5; // how strong? (0.5 is ideal)
 
 var dataArray : float[,];
 
 
 function Start() 
 {
     PerlinFractalDataArray();
 }
 
 
 function Update() 
 {
     if ( Input.GetKeyDown( KeyCode.Space ) )
         PerlinFractalDataArray();
 }
 
 
 function PerlinFractalDataArray() 
 {
     // declare the data array
     dataArray = new float[ size, size ];
     
     // variables used in calculations
     var noise : float;
     var gain : float;
     
     var x : int;
     var y : int;
     var i : int;
     
     var sample : Vector2;
     
     // generate noise
     for ( y = 0; y < size; y ++ )
     {
         for ( x = 0; x < size; x ++ )
         {
             noise = 0.0;
             gain = 1.0;
             
             for ( i = 0; i < octaves; i ++ )
             {
                 sample.x = offset.x + ( parseFloat( x ) * ( gain / frq ) );
                 sample.y = offset.y + ( parseFloat( y ) * ( gain / frq ) );
                 
                 noise += Mathf.PerlinNoise( sample.x, sample.y ) * ( amp / gain );
                 gain *= 2.0;
             }
 
             dataArray[ x, y ] = noise;
         }
     }
     
     
     Debug.Log( "PerlinFractalDataArray completed" );
     
     // Generate Terrain using dataArray as height values
     GenerateTerrain();
 }
 
 
 function GenerateTerrain() 
 {
     if ( !terrain )
         return;
     
     if ( terrain.terrainData.heightmapResolution != size )
         terrain.terrainData.heightmapResolution = size;
     
     terrain.terrainData.SetHeights( 0, 0, dataArray );
 }




Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Cipher_Ultra · Sep 05, 2014 at 08:13 AM 0
Share

Hi,

Thanks for your help. I managed to get $$anonymous$$e to work in the end. It was an issue with global variables causing the problems. Although I'll have a look at the two you suggested and see how they look.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

Multiple Cars not working 1 Answer

Simple 2D procedural galaxy map 2 Answers

Creating a Pacman style game, would appreciate help.,My first real game, pac-man inspired. Appreciate help. 1 Answer

Is this a good source to learn javascript? 1 Answer

In-depth Animation and Audio guide for Enemy AI? 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges