Advertisement
Guest User

Untitled

a guest
Dec 18th, 2017
118
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 9.27 KB | None | 0 0
  1. /// <summary>
  2. /// Dvornik
  3. ///kostiantyn-dvornik.blogspot.com/2013/12/unity-split-terrain-script.html
  4. /// </summary>
  5. using UnityEngine;
  6. using UnityEditor;
  7. using System.IO;
  8. using System.Runtime.Serialization;
  9. using System.Runtime.Serialization.Formatters.Binary;
  10. using System.Collections.Generic;
  11.  
  12. /// <summary>
  13. /// Split terrain.
  14. /// </summary>
  15. public class SplitTerrain : EditorWindow {
  16.        
  17.     string num = "4";
  18.  
  19.     List<TerrainData> terrainData = new List<TerrainData>();
  20.     List<GameObject> terrainGo = new List<GameObject>();
  21.    
  22.     Terrain parentTerrain;
  23.    
  24.     static int terrainsCount = 4;      
  25.    
  26.     // Add submenu
  27.     [MenuItem("Terrain/Split Terrain")]
  28.     static void Init()
  29.     {
  30.        
  31.         // Get existing open window or if none, make a new one:
  32.         SplitTerrain window = (SplitTerrain)EditorWindow.GetWindow(typeof(SplitTerrain));
  33.        
  34.         window.minSize =  new Vector2( 100f,100f );    
  35.         window.maxSize =  new Vector2( 200f,200f );    
  36.        
  37.         window.autoRepaintOnSceneChange = true;
  38.         window.title = "Resize terrain";
  39.         window.Show();
  40.                            
  41.            
  42.     }
  43.    
  44.     /// <summary>
  45.     /// Determines whether this instance is power of two the specified x.
  46.     /// </summary>
  47.     /// <returns>
  48.     /// <c>true</c> if this instance is power of two the specified x; otherwise, <c>false</c>.
  49.     /// </returns>
  50.     /// <param name='x'>
  51.     /// If set to <c>true</c> x.
  52.     /// </param>
  53.     bool IsPowerOfTwo(int x)
  54.     {
  55.         return (x & (x - 1)) == 0;
  56.     }
  57.            
  58.     void SplitIt()
  59.     {
  60.        
  61.         if ( Selection.activeGameObject == null )
  62.         {
  63.             Debug.LogWarning("No terrain was selected");
  64.             return;
  65.         }
  66.        
  67.        
  68.         parentTerrain = Selection.activeGameObject.GetComponent(typeof(Terrain)) as Terrain;       
  69.        
  70.         if ( parentTerrain == null )
  71.         {
  72.             Debug.LogWarning("Current selection is not a terrain");
  73.             return;
  74.         }
  75.                        
  76.         //Split terrain
  77.         for ( int i=0; i< terrainsCount; i++)
  78.         {                                      
  79.            
  80.             EditorUtility.DisplayProgressBar("Split terrain","Process " + i, (float) i / terrainsCount );
  81.                                
  82.             TerrainData td = new TerrainData();
  83.             GameObject tgo = Terrain.CreateTerrainGameObject( td );
  84.        
  85.             tgo.name = parentTerrain.name + " " + i;
  86.            
  87.             terrainData.Add( td );
  88.             terrainGo.Add ( tgo );
  89.            
  90.             Terrain genTer = tgo.GetComponent(typeof(Terrain)) as Terrain;                             
  91.             genTer.terrainData = td;
  92.  
  93.             AssetDatabase.CreateAsset(td, "Assets/" + genTer.name+ ".asset");
  94.  
  95.            
  96.             // Assign splatmaps
  97.             genTer.terrainData.splatPrototypes = parentTerrain.terrainData.splatPrototypes;
  98.            
  99.             // Assign detail prototypes
  100.             genTer.terrainData.detailPrototypes = parentTerrain.terrainData.detailPrototypes;
  101.                        
  102.             // Assign tree information
  103.             genTer.terrainData.treePrototypes = parentTerrain.terrainData.treePrototypes;
  104.            
  105.                                    
  106.             // Copy parent terrain propeties
  107.             #region parent properties
  108.             genTer.basemapDistance = parentTerrain.basemapDistance;        
  109.             genTer.castShadows = parentTerrain.castShadows;
  110.             genTer.detailObjectDensity = parentTerrain.detailObjectDensity;
  111.             genTer.detailObjectDistance = parentTerrain.detailObjectDistance;
  112.             genTer.heightmapMaximumLOD = parentTerrain.heightmapMaximumLOD;
  113.             genTer.heightmapPixelError = parentTerrain.heightmapPixelError;
  114.             genTer.treeBillboardDistance = parentTerrain.treeBillboardDistance;
  115.             genTer.treeCrossFadeLength = parentTerrain.treeCrossFadeLength;
  116.             genTer.treeDistance = parentTerrain.treeDistance;
  117.             genTer.treeMaximumFullLODCount = parentTerrain.treeMaximumFullLODCount;
  118.            
  119.             #endregion
  120.            
  121.             //Start processing it          
  122.                        
  123.             // Translate peace to position
  124.             #region translate peace to right position
  125.            
  126.             Vector3 parentPosition = parentTerrain.GetPosition();
  127.            
  128.             int terraPeaces = (int) Mathf.Sqrt( terrainsCount );
  129.            
  130.             float spaceShiftX = parentTerrain.terrainData.size.z / terraPeaces;
  131.             float spaceShiftY = parentTerrain.terrainData.size.x / terraPeaces;
  132.            
  133.             float xWShift = (i % terraPeaces ) * spaceShiftX;
  134.             float zWShift = ( i / terraPeaces ) * spaceShiftY;
  135.                        
  136.             tgo.transform.position = new Vector3( tgo.transform.position.x + zWShift,
  137.                                                   tgo.transform.position.y,
  138.                                                   tgo.transform.position.z + xWShift );    
  139.            
  140.             // Shift last position
  141.             tgo.transform.position = new Vector3( tgo.transform.position.x + parentPosition.x,
  142.                                                   tgo.transform.position.y + parentPosition.y,
  143.                                                   tgo.transform.position.z + parentPosition.z
  144.                                                  );
  145.            
  146.            
  147.            
  148.             #endregion
  149.            
  150.             // Split height
  151.             #region split height
  152.            
  153.             Debug.Log ( "Split height" );
  154.            
  155.             //Copy heightmap                                           
  156.             td.heightmapResolution = parentTerrain.terrainData.heightmapResolution /  terraPeaces;                         
  157.            
  158.             //Keep y same
  159.             td.size = new Vector3( parentTerrain.terrainData.size.x / terraPeaces,
  160.                                    parentTerrain.terrainData.size.y,
  161.                                    parentTerrain.terrainData.size.z / terraPeaces
  162.                                   );
  163.            
  164.             float[,] parentHeight = parentTerrain.terrainData.GetHeights(0,0, parentTerrain.terrainData.heightmapResolution, parentTerrain.terrainData.heightmapResolution );
  165.            
  166.             float[,] peaceHeight = new float[ parentTerrain.terrainData.heightmapResolution / terraPeaces + 1,
  167.                                               parentTerrain.terrainData.heightmapResolution / terraPeaces + 1
  168.                                             ];
  169.            
  170.             // Shift calc
  171.             int heightShift = parentTerrain.terrainData.heightmapResolution / terraPeaces;                             
  172.                    
  173.             int startX = 0;
  174.             int startY = 0;
  175.            
  176.             int endX = 0;
  177.             int endY = 0;
  178.             /*
  179.             if ( i==0 )
  180.             {
  181.                 startX = startY = 0;               
  182.                 endX = endY = parentTerrain.terrainData.heightmapResolution / terraPeaces + 1;
  183.             }
  184.            
  185.             if ( i==1 )
  186.             {
  187.                 startX = startY = 0;               
  188.                 endX = parentTerrain.terrainData.heightmapResolution / terraPeaces + 1;
  189.                 endY = parentTerrain.terrainData.heightmapResolution / terraPeaces + 1;
  190.             }
  191.            
  192.             if ( i==2 )
  193.             {
  194.                 startX = startY = 0;               
  195.                 endX = parentTerrain.terrainData.heightmapResolution / terraPeaces + 1;
  196.                 endY = parentTerrain.terrainData.heightmapResolution / terraPeaces + 1;
  197.             }
  198.            
  199.             if ( i==3 )
  200.             {
  201.                 startX = startY = 0;               
  202.                 endX = parentTerrain.terrainData.heightmapResolution / terraPeaces + 1;
  203.                 endY = parentTerrain.terrainData.heightmapResolution / terraPeaces + 1;
  204.             }
  205.                 */                     
  206.                 endX = parentTerrain.terrainData.heightmapResolution / terraPeaces ;
  207.                 endY = parentTerrain.terrainData.heightmapResolution / terraPeaces ;               
  208.             // iterate
  209.             for ( int x=startX;x< endX;x++)
  210.             {  
  211.                
  212.                 EditorUtility.DisplayProgressBar("Split terrain","Split height", (float) x / ( endX - startX ));  
  213.                
  214.                 for ( int y=startY;y< endY;y++)
  215.                 {
  216.                
  217.                     int xShift=0;
  218.                     int yShift=0;
  219.                    
  220.                     //
  221.                     /*
  222.                     if ( i==0 )
  223.                     {
  224.                         xShift = 0;
  225.                         yShift = 0;                    
  226.                     }
  227.                    
  228.                     //
  229.                     if ( i==1 )
  230.                     {                      
  231.                         xShift = heightShift;
  232.                         yShift = 0;                    
  233.                     }
  234.                    
  235.                     //
  236.                     if ( i==2 )
  237.                     {
  238.                         xShift = 0;
  239.                         yShift = heightShift;  
  240.                     }
  241.                    
  242.                     if ( i==3 )
  243.                     {
  244.                         xShift = heightShift;
  245.                         yShift = heightShift;  
  246.                     }
  247.                     */
  248.                     xShift=heightShift*(i%terraPeaces);
  249.                     yShift=heightShift*(i/terraPeaces);
  250.                     float ph = parentHeight[ x + xShift,y + yShift];   
  251.                                                
  252.                     peaceHeight[x ,y ] = ph;
  253.                    
  254.                 }
  255.                                                        
  256.             }
  257.            
  258.             EditorUtility.ClearProgressBar();
  259.            
  260.             // Set heightmap to child
  261.             genTer.terrainData.SetHeights( 0,0, peaceHeight );
  262.             #endregion
  263.            
  264.             // Split splat map
  265.             #region split splat map
  266.                                
  267.             td.alphamapResolution = parentTerrain.terrainData.alphamapResolution /  terraPeaces;                                                   
  268.            
  269.             float[,,] parentSplat = parentTerrain.terrainData.GetAlphamaps(0,0, parentTerrain.terrainData.alphamapResolution, parentTerrain.terrainData.alphamapResolution );          
  270.  
  271.             float[,,] peaceSplat = new float[ parentTerrain.terrainData.alphamapResolution / terraPeaces ,
  272.                                               parentTerrain.terrainData.alphamapResolution / terraPeaces,
  273.                                               parentTerrain.terrainData.alphamapLayers
  274.                                             ];
  275.                                    
  276.             // Shift calc
  277.             int splatShift = parentTerrain.terrainData.alphamapResolution / terraPeaces;                               
  278.  
  279.             startX = startY = 0;               
  280.                 endX = parentTerrain.terrainData.alphamapResolution / terraPeaces;
  281.                 endY = parentTerrain.terrainData.alphamapResolution / terraPeaces;
  282.             // iterate
  283.             for ( int s=0;s<parentTerrain.terrainData.alphamapLayers;s++)
  284.             {              
  285.                 for ( int x=startX;x< endX;x++)
  286.                 {  
  287.                    
  288.                     EditorUtility.DisplayProgressBar("Split terrain","Split splat", (float) x / ( endX - startX ));  
  289.                    
  290.                     for ( int y=startY;y< endY;y++)
  291.                     {
  292.                    
  293.                         int xShift=0;
  294.                         int yShift=0;
  295.                        
  296.                         //
  297.                         xShift=splatShift*(i%terraPeaces);
  298.                         yShift=splatShift*(i/terraPeaces);
  299.                         float ph = parentSplat[x + xShift,y + yShift, s];  
  300.                         peaceSplat[x ,y, s] = ph;
  301.                        
  302.                     }
  303.                                                            
  304.                    
  305.                 }          
  306.             }
  307.            
  308.             EditorUtility.ClearProgressBar();
  309.            
  310.             // Set heightmap to child
  311.             genTer.terrainData.SetAlphamaps( 0,0, peaceSplat );
  312.             #endregion
  313.                
  314.                
  315.             AssetDatabase.SaveAssets();
  316.  
  317.  
  318.  
  319.         }
  320.        
  321.         EditorUtility.ClearProgressBar();
  322.                
  323.        
  324.        
  325.     }
  326.    
  327.     void OnGUI()
  328.     {
  329.                    
  330.         if(GUILayout.Button("Split terrain"))
  331.         {          
  332.            
  333.             SplitIt();                         
  334.         }
  335.            
  336.         terrainsCount=EditorGUILayout.IntField(terrainsCount);                                         
  337.     }
  338.    
  339.        
  340.    
  341. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement