123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351 |
- using UnityEngine;
- using UnityEditor;
- using System.Collections;
- using System.Collections.Generic;
- using System;
- /// <summary>
- /// 地形切分 引擎工具类
- /// </summary>
- public class MySplitTerrain : EditorWindow
- {
- // 目标地形
- private Terrain LargeTargetTerrain;
- // 目标数据
- private TerrainData LargeTargetData;
- // 切分次数
- private int TerrainNum = 4;
- //
- private int TerrainNumKH = 2;
- // 地图切片
- private Terrain[,] IndividualTerrain;
- // 地图切片数据
- private TerrainData[,] IndividualTerrainData;
- // 宽长高
- private float W, L, H;
- private float X, Z;
- // 缩放
- private Vector3 scale;
- // 植被数量
- private TreeInstance[] TreeNum;
- private GameObject[] treeainS;
- private int Pixel_Error = 200;
- private int Base_Map_Dist = 30;
- private bool Cast_Shadows = true;
- private Material Material;
- private bool Draw = true;
- private int Detail_Distance = 30;
- private float Detail_Density = 1f;
- private int Tree_Distance = 30;
- private int Billboad_Start = 30;
- private int Fabe_Length = 5;
- private int Max_Mesh_Trees = 30;
- private float Speed = 0.5f;
- private float Size = 0.5f;
- private float Bending = 0.5f;
- private Color Grass_Tint = new Color(0.7F, 0.6F, 0.5F, 0);
- private Vector2 scrollPosTerrain;
- [MenuItem("地图/地形切分工具")]
- public static void OpenSplitTerrainWindow()
- {
- EditorWindow.GetWindow(typeof(MySplitTerrain));
- }
- void Update()
- {
- }
- void OnGUI()
- {
- GUILayout.Label("目标地形预制体");
- LargeTargetTerrain = EditorGUILayout.ObjectField(LargeTargetTerrain, typeof(Terrain), true) as Terrain;
- GUILayout.Label("切分数量2的幂");
- //248
- TerrainNumKH = EditorGUILayout.IntField(TerrainNumKH);
- if (!Mathf.IsPowerOfTwo(TerrainNumKH))
- {
- return;
- }
- if (GUILayout.Button("生成"))
- {
- Split();
- }
- GUILayout.BeginArea(new Rect(10, 120, 500, 700));
- GUILayout.Label("地形数据检测");
- GUILayout.Label("---Base Terrain---");
- GUILayout.Label("像素误差");
- Pixel_Error = (int)EditorGUILayout.Slider(Pixel_Error, 1, 200);
- GUILayout.Label("基础切片区域");
- Base_Map_Dist = (int)EditorGUILayout.Slider(Base_Map_Dist, 0, 2000);
- //GUILayout.Label("Cast shadows");
- Cast_Shadows = EditorGUILayout.Toggle("阴影品质", Cast_Shadows);
- //GUILayout.Label("Material");
- //Material = EditorGUILayout.ObjectField(Material, typeof(Material), true) as Material;
- //GUILayout.Label("---Tree &Detail Objects---");
- //// GUILayout.Label("Draw");
- //Draw = EditorGUILayout.Toggle("Draw", Draw);
- //GUILayout.Label("细节距离");
- //Detail_Distance = (int)EditorGUILayout.Slider(Detail_Distance, 0, 250);
- //GUILayout.Label("细节密度");
- //Detail_Density = EditorGUILayout.Slider(Detail_Density, 0, 1);
- //GUILayout.Label("植被距离");
- //Tree_Distance = (int)EditorGUILayout.Slider(Tree_Distance, 0, 2000);
- //GUILayout.Label("Billboad Start");
- //Billboad_Start = (int)EditorGUILayout.Slider(Billboad_Start, 5, 2000);
- //GUILayout.Label("Fabe Length");
- //Fabe_Length = (int)EditorGUILayout.Slider(Fabe_Length, 0, 200);
- //GUILayout.Label("Max Mesh Trees");
- //Max_Mesh_Trees = (int)EditorGUILayout.Slider(Max_Mesh_Trees, 0, 10000);
- //GUILayout.Label("---Wind Settings---");
- //GUILayout.Label("Speed");
- //Speed = EditorGUILayout.Slider(Speed, 0, 1);
- //GUILayout.Label("Size");
- //Size = EditorGUILayout.Slider(Size, 0, 1);
- //GUILayout.Label("Bending");
- //Bending = EditorGUILayout.Slider(Bending, 0, 1);
- // GUILayout.Label("Grass Tint");
- //Grass_Tint = EditorGUILayout.ColorField("Grass Tint", Grass_Tint);
- if (GUILayout.Button("地形批量修改"))
- {
- Terrainbatchchange();
- }
- GUILayout.EndArea();
- GUILayout.BeginArea(new Rect(520, 120, 300, 700));
- GUILayout.Label("Treeain) ");
- if (GUILayout.Button("地形列表"))
- {
- GetTerrainNumList();
- }
- scrollPosTerrain = GUILayout.BeginScrollView(scrollPosTerrain, GUILayout.Width(300), GUILayout.Height(500));
- if (treeainS != null)
- for (int i = 0; i < treeainS.Length; i++)
- {
- treeainS[i] = EditorGUILayout.ObjectField(treeainS[i], typeof(GameObject), true) as GameObject;
- }
- GUILayout.EndScrollView();
- GUILayout.EndArea();
- GUILayout.Space(20);
- }
- void GetTerrainNumList()
- {
- treeainS = GameObject.FindGameObjectsWithTag("Terrain");
- }
- void Terrainbatchchange()
- {
- for (int i = 0; i < treeainS.Length; i++)
- {
- treeainS[i].GetComponent<Terrain>().heightmapPixelError = LargeTargetTerrain.heightmapPixelError;
- treeainS[i].GetComponent<Terrain>().basemapDistance = LargeTargetTerrain.basemapDistance;
- treeainS[i].GetComponent<Terrain>().castShadows = LargeTargetTerrain.castShadows;
- treeainS[i].GetComponent<Terrain>().materialTemplate = LargeTargetTerrain.materialTemplate;
- treeainS[i].GetComponent<Terrain>().enabled = LargeTargetTerrain.enabled;
- treeainS[i].GetComponent<Terrain>().detailObjectDistance = LargeTargetTerrain.detailObjectDistance;
- treeainS[i].GetComponent<Terrain>().detailObjectDensity = LargeTargetTerrain.detailObjectDensity;
- treeainS[i].GetComponent<Terrain>().treeDistance = LargeTargetTerrain.treeDistance;
- treeainS[i].GetComponent<Terrain>().treeBillboardDistance = LargeTargetTerrain.treeBillboardDistance;
- treeainS[i].GetComponent<Terrain>().treeCrossFadeLength = LargeTargetTerrain.treeCrossFadeLength;
- treeainS[i].GetComponent<Terrain>().treeMaximumFullLODCount = LargeTargetTerrain.treeMaximumFullLODCount;
- treeainS[i].GetComponent<Terrain>().terrainData.wavingGrassStrength = LargeTargetTerrain.terrainData.wavingGrassStrength;
- treeainS[i].GetComponent<Terrain>().terrainData.wavingGrassSpeed = LargeTargetTerrain.terrainData.wavingGrassSpeed;
- treeainS[i].GetComponent<Terrain>().terrainData.wavingGrassAmount = LargeTargetTerrain.terrainData.wavingGrassAmount;
- treeainS[i].GetComponent<Terrain>().terrainData.wavingGrassTint = LargeTargetTerrain.terrainData.wavingGrassTint;
- treeainS[i].GetComponent<Terrain>().terrainData.terrainLayers = LargeTargetData.terrainLayers;
- }
- }
- void Split()
- {
- GetDataLargeTargetTerrain();
- IndividualTerrainCreat();
- divisionTreeainData();
- DiveisionTreeatinAlphamapData();
- DiveisionTreeatinTree();
- DiveisionTreeatinGrass();
- }
- void GetDataLargeTargetTerrain()
- {
- LargeTargetData = LargeTargetTerrain.terrainData;
- scale = LargeTargetData.size;
- TreeNum = LargeTargetData.treeInstances;
- }
- void IndividualTerrainCreat()
- {
- TerrainNum = TerrainNumKH * TerrainNumKH;
- try
- {
- double num = Mathf.Sqrt(TerrainNum);
- string str = num.ToString();
- str = str.Substring(str.LastIndexOf('.'), 2);
- }
- catch (Exception)
- {
- string path = AssetDatabase.GetAssetPath(LargeTargetTerrain);
- if(path == "")
- {
- return;
- }
- W = LargeTargetTerrain.terrainData.size.x;
- H = LargeTargetTerrain.terrainData.size.y;
- L = LargeTargetTerrain.terrainData.size.z;
- TerrainNumKH = (int)Mathf.Sqrt(TerrainNum);
- IndividualTerrainData = new TerrainData[TerrainNumKH, TerrainNumKH];
- IndividualTerrain = new Terrain[TerrainNumKH, TerrainNumKH];
- Vector3[,] TerrainPoint = new Vector3[TerrainNumKH, TerrainNumKH];
- X = W / TerrainNumKH;
- Z = W / TerrainNumKH;
- for (int i = 0; i < TerrainNumKH; i++)
- {
- for (int j = 0; j < TerrainNumKH; j++)
- {
- IndividualTerrainData[i, j] = new TerrainData();
- IndividualTerrain[i, j] = Terrain.CreateTerrainGameObject(IndividualTerrainData[i, j]).GetComponent<Terrain>();
- TerrainPoint[i, j] = new Vector3(i * X, 0, j * Z);
- IndividualTerrainData[i, j].heightmapResolution = (int)LargeTargetData.heightmapResolution / TerrainNumKH;
- IndividualTerrainData[i, j].size = new Vector3(W / TerrainNumKH, LargeTargetData.size.y, L / TerrainNumKH);
- IndividualTerrain[i, j].transform.position = TerrainPoint[i, j];
- IndividualTerrain[i, j].transform.name = (IndividualTerrain[i, j].transform.name + i + j);
- IndividualTerrain[i, j].heightmapPixelError = LargeTargetTerrain.heightmapPixelError;
- IndividualTerrain[i, j].basemapDistance = LargeTargetTerrain.basemapDistance;
- IndividualTerrain[i, j].castShadows = LargeTargetTerrain.castShadows;
- IndividualTerrain[i, j].reflectionProbeUsage = LargeTargetTerrain.reflectionProbeUsage;
- IndividualTerrain[i, j].materialTemplate = LargeTargetTerrain.materialTemplate;
- IndividualTerrain[i, j].enabled = LargeTargetTerrain.enabled;
- IndividualTerrain[i, j].detailObjectDistance = LargeTargetTerrain.detailObjectDistance;
- IndividualTerrain[i, j].detailObjectDensity = LargeTargetTerrain.detailObjectDensity;
- IndividualTerrain[i, j].treeDistance = LargeTargetTerrain.treeDistance;
- IndividualTerrain[i, j].treeBillboardDistance = LargeTargetTerrain.treeBillboardDistance;
- IndividualTerrain[i, j].treeCrossFadeLength = LargeTargetTerrain.treeCrossFadeLength;
- IndividualTerrain[i, j].treeMaximumFullLODCount = LargeTargetTerrain.treeMaximumFullLODCount;
- IndividualTerrain[i, j].terrainData.wavingGrassStrength = LargeTargetTerrain.terrainData.wavingGrassStrength;
- IndividualTerrain[i, j].terrainData.wavingGrassSpeed = LargeTargetTerrain.terrainData.wavingGrassSpeed;
- IndividualTerrain[i, j].terrainData.wavingGrassAmount = LargeTargetTerrain.terrainData.wavingGrassAmount;
- IndividualTerrain[i, j].terrainData.wavingGrassTint = LargeTargetTerrain.terrainData.wavingGrassTint;
- IndividualTerrain[i, j].terrainData.terrainLayers = LargeTargetData.terrainLayers;
- IndividualTerrain[i, j].transform.parent = LargeTargetTerrain.transform;
- MySplitTerrainTile mystt = IndividualTerrain[i, j].gameObject.GetOrAddComponent<MySplitTerrainTile>();
- mystt.refreshTime = 1;
- AssetDatabase.CreateAsset(IndividualTerrainData[i, j], AssetDatabase.GetAssetPath(LargeTargetTerrain) + IndividualTerrain[i, j].transform.name + i + j + ".asset");
- }
- }
- }
- }
- void divisionTreeainData()
- {
- for (int i = 0; i < TerrainNumKH; i++)
- {
- for (int j = 0; j < TerrainNumKH; j++)
- {
- IndividualTerrain[i, j].basemapDistance = 100;
- int X, Y;
- X = LargeTargetData.heightmapResolution / TerrainNumKH;
- Y = LargeTargetData.heightmapResolution / TerrainNumKH;
- float[,] height = LargeTargetData.GetHeights(X * i, Y * j, X + 1, Y + 1);
- IndividualTerrainData[i, j].SetHeights(0, 0, height);
- }
- }
- }
- void DiveisionTreeatinAlphamapData()
- {
- for (int i = 0; i < TerrainNumKH; i++)
- {
- for (int j = 0; j < TerrainNumKH; j++)
- {
- int X, Y;
- X = LargeTargetData.alphamapWidth / TerrainNumKH;
- Y = LargeTargetData.alphamapHeight / TerrainNumKH;
- float[,,] aMap = LargeTargetData.GetAlphamaps(X * i, Y * j, X, Y);
- IndividualTerrainData[i, j].alphamapResolution = LargeTargetData.alphamapResolution / TerrainNumKH;
- //IndividualTerrainData[i, j].splatPrototypes = LargeTargetData.splatPrototypes;
- IndividualTerrainData[i, j].SetAlphamaps(0, 0, aMap);
- }
- }
- }
- void DiveisionTreeatinTree()
- {
- List<Vector3> TreesPoint = new List<Vector3>();
- for (int k = 0; k < TreeNum.Length; k++)
- {
- Vector3 treespoint = new Vector3(TreeNum[k].position.x * W, TreeNum[k].position.y * H, TreeNum[k].position.z * L);
- TreesPoint.Add(treespoint);
- }
- for (int i = 0; i < TerrainNumKH; i++)
- {
- for (int j = 0; j < TerrainNumKH; j++)
- {
- IndividualTerrainData[i, j].treePrototypes = LargeTargetData.treePrototypes;
- Vector3 IndividualTerrainSize = IndividualTerrain[i, j].terrainData.size;
- Vector3 IndividualTerrainPoint = IndividualTerrain[i, j].transform.position;
- Rect rect = new Rect(IndividualTerrainPoint.x, IndividualTerrainPoint.z, IndividualTerrainSize.x, IndividualTerrainSize.z);
- List<TreeInstance> trees = new List<TreeInstance>();
- trees.Clear();
- for (int k = 0; k < TreeNum.Length; k++)
- {
- if (rect.Contains(new Vector2(TreeNum[k].position.x * W, TreeNum[k].position.z * L)))
- {
- Vector3 treesList = new Vector3(TreeNum[k].position.x * W, TreeNum[k].position.y * H, TreeNum[k].position.z * L);
- for (int p = 0; p < TreesPoint.Count; p++)
- {
- if (treesList == TreesPoint[p])
- {
- Vector3 ScreenTreeS = new Vector3(TreeNum[k].position.x * W, TreeNum[k].position.y * H, TreeNum[k].position.z * L);
- Vector3 ZDTreeS = new Vector3(ScreenTreeS.x - IndividualTerrainPoint.x, ScreenTreeS.y, ScreenTreeS.z - IndividualTerrainPoint.z);
- Vector3 shareTree = new Vector3(ZDTreeS.x / IndividualTerrainSize.x, ZDTreeS.y / IndividualTerrainSize.y, ZDTreeS.z / IndividualTerrainSize.z);
- TreeNum[k].position = shareTree;
- trees.Add(TreeNum[k]);
- }
- }
- }
- }
- IndividualTerrainData[i, j].treeInstances = trees.ToArray();
- }
- }
- }
- void DiveisionTreeatinGrass()
- {
- DetailPrototype[] Grass = LargeTargetData.detailPrototypes;
- int LargetSize = LargeTargetData.detailResolution;
- for (int i = 0; i < TerrainNumKH; i++)
- {
- for (int j = 0; j < TerrainNumKH; j++)
- {
- IndividualTerrainData[i, j].detailPrototypes = Grass;
- IndividualTerrainData[i, j].SetDetailResolution(LargetSize / TerrainNumKH, 8);
- for (int k = 0; k < Grass.Length; k++)
- {
- int[,] text = LargeTargetData.GetDetailLayer(LargetSize / TerrainNumKH * i, LargetSize / TerrainNumKH * j, LargetSize / TerrainNumKH, LargetSize / TerrainNumKH, k);
- IndividualTerrainData[i, j].SetDetailLayer(0, 0, k, text);
- }
- }
- }
- }
- }
|