Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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 Bjosor · Apr 13, 2017 at 03:19 PM · terrainterraindata

terrainData.SetHeightsDelayLOD seem to have no effect and i dont know why.

I have multiple unity terrains next to each other that i want to seamlessly erode. my current problem is how to set heights across terrain borders. The current approach is to set single heightsamples when the SetHeightsDelayLOD array would go out of bounds. Basically i provide SetHeightsDelayLOD with a [1,1] array with a single heightsample. This is expensive so I'm having it set larger arrays at a time when not crossing borders. Sadly these larger arrays seem to do nothing, event though they use the same exact function only with a larger array. Any other suggestions to improve this code are welcome, I'm still learning.

Here is the function that sets the heights. pos is the coordinates for the middle of the array. yMod and xMod is used to offset this to either access neighbouring samples or find the base coords of the array.

 public void setHeight(Vector2 pos, float[,] heights, int yMod = 0, int xMod = 0)
     {
         pos = new Vector2(pos.x + xMod, pos.y + yMod);
         Vector2 chunkPos = TerrainSettings.worldToChunk(pos);
         Vector2 heightPos = TerrainSettings.worldToHeightMap(pos);
         chunks[(int)chunkPos.x, (int)chunkPos.y].terrain.terrainData.SetHeightsDelayLOD((int)heightPos.x, 
         (int)heightPos.y, heights);
         if(!chunksToUpdate.Contains(chunks[(int)chunkPos.x, (int)chunkPos.y]))
             chunksToUpdate.Enqueue(chunks[(int)chunkPos.x, (int)chunkPos.y]);
     }

Here is the function calculating mass to erode which then calls setHeights. It works fine when sending single samples, but when i try the larger array no changes are visible.

 public static Drop takeSediment(Map map, Drop drop, float heightDif)
      //calculates the amount of mass to take from the surrounding area
         {
             float[,] array = new float[radius * 2 + 1, radius * 2 +1];
             float[,] heights = new float [2,2];
             bool multiChunk = false;
     
             //Debug.Log("takes " + Mathf.Min((drop.capacity - drop.sediment) * 
             erosion, heightDif * -1));
             float takeAmount = Mathf.Min((drop.capacity - drop.sediment) * 
             erosion, (heightDif * -1)*radius);
             drop.sediment += takeAmount;
             float totalWeight = 0;
     
             for (int x = -radius; x <= radius; x++)
             {
                 for (int y = -radius; y <= radius; y++)
                 {
                     array[x + radius, y + radius] = Mathf.Max(0, radius - 
                     (Vector2.Distance(drop.posOld, new 
                     Vector2(drop.posOld.x + x, drop.posOld.y + y))));
                     totalWeight += Mathf.Max(0, radius - 
                     (Vector2.Distance(drop.posOld, new 
                     Vector2(drop.posOld.x + x, drop.posOld.y + y))));
                 }
             }
     
             for (int x = -radius; x <= radius; x++)
             {
                 for (int y = -radius; y <= radius; y++)
                 {
                     
                     if(TerrainSettings.worldToHeightMap(drop.posOld).x 
                         + radius > TerrainSettings.HeightmapResolution
                     || TerrainSettings.worldToHeightMap(drop.posOld).y 
                         + radius > 
                          TerrainSettings.HeightmapResolution
                     || TerrainSettings.worldToHeightMap(drop.posOld).x
                          - radius < 0
                     || TerrainSettings.worldToHeightMap(drop.posOld).y 
                          - radius < 0)
                     {
                        //if it intersects the border use single samples
                         float test = map.getHeight(drop.posOld, y, x);
                         multiChunk = true;
                         float[,] tempArray = new float[1, 1] { { 
                         map.getHeight(drop.posOld, y, x) - ((array[x + radius, 
                         y + radius] / totalWeight) * takeAmount) } };
                         map.setHeight(drop.posOld, tempArray, y, x);
                     }
                     else
                     {
                        //does not intersect border, send whole array at once
                         multiChunk = false;
                         heights = map.getHeights(drop.posOld, radius);
                         float test = heights[x + radius, y + radius];
                         heights[x + radius, y + radius] = 
                         heights[x + radius, y + radius] -
                         ((array[x + radius, y + radius] / totalWeight) * takeAmount);
                         
     
                     }
                 }
             }
             if (!multiChunk)
             {
                     //this is the call that doesn't do anything
                     map.setHeight(drop.posOld, heights, -radius, -radius);
                 
             }
                 
     
             return drop;
         }
 





Comment
Add comment
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

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by Bjosor · Apr 25, 2017 at 05:04 AM

So this turned out to be an easy fix. I looked at it for so long and couldn't see what was wrong. Then i came back after a week and solved it in 15 seconds...

apparently its a bad idea to call getheights within a loop as i only want to get the heights once.

 for (int x = -radius; x <= radius; x++)
              {
                  for (int y = -radius; y <= radius; y++)
                  {
                      
                      if(TerrainSettings.worldToHeightMap(drop.posOld).x 
                          + radius > TerrainSettings.HeightmapResolution
                      || TerrainSettings.worldToHeightMap(drop.posOld).y 
                          + radius > 
                           TerrainSettings.HeightmapResolution
                      || TerrainSettings.worldToHeightMap(drop.posOld).x
                           - radius < 0
                      || TerrainSettings.worldToHeightMap(drop.posOld).y 
                           - radius < 0)
                      {
                         
                          float test = map.getHeight(drop.posOld, y, x);
                          multiChunk = true;
                          float[,] tempArray = new float[1, 1] { { 
                          map.getHeight(drop.posOld, y, x) - ((array[x + radius, 
                          y + radius] / totalWeight) * takeAmount) } };
                          map.setHeight(drop.posOld, tempArray, y, x);
                      }
                      else
                      {
                         
                          multiChunk = false;
 
                          //Moved this one out of the loop. Fixed it
                          heights = map.getHeights(drop.posOld, radius);
 
 
                          float test = heights[x + radius, y + radius];
                          heights[x + radius, y + radius] = 
                          heights[x + radius, y + radius] -
                          ((array[x + radius, y + radius] / totalWeight) * takeAmount);
                          
      
                      }
                  }
Comment
Add comment · 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

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

3 People are following this question.

avatar image avatar image avatar image

Related Questions

Why do smaller terrains have higher triangle count? 0 Answers

terrain の detail について (About Terrain Detail),terrain の detail について (About Terrain Detail) 0 Answers

terrainData.heightmapTexture float value range 2 Answers

Convert terrain map coordinates (GetDetailLayer) into world position 0 Answers

Edit Terrain at runtime 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