Exemplo n.º 1
0
        void ApplySettingsToTerrains(Terrain[] terrains, string errorContext = "")
        {
            int index = 0;

            try
            {
                bool continueEdit = true;

                // Only show this warning if the user has Mesh Settings enabled.
                if (m_Settings.EnableMeshResSettings)
                {
                    var newSize = new Vector3(m_Settings.TerrainWidth, m_Settings.TerrainHeight,
                                              m_Settings.TerrainLength);
                    foreach (var terrain in terrains)
                    {
                        // If any terrain has a size that's different from the specified settings, let's confirm
                        // the action.
                        if (terrain.terrainData.size != newSize)
                        {
                            var message =
                                "Some terrains have different sizes than the settings specified. This operation will resize the terrains potentially resulting in gaps and/or overlaps.";
                            if (string.IsNullOrEmpty(errorContext))
                            {
                                continueEdit = EditorUtility.DisplayDialog("Confirm",
                                                                           $"{message}\nAre you sure you want to continue?",
                                                                           "Continue", "Cancel");
                            }
                            else
                            {
                                continueEdit = EditorUtility.DisplayDialog("Confirm",
                                                                           $"1. {errorContext}\n2. {message}\n\nAre you sure you want to continue?",
                                                                           "Continue", "Cancel");
                            }
                            break;
                        }
                    }
                }

                if (continueEdit)
                {
                    foreach (var terrain in terrains)
                    {
                        EditorUtility.DisplayProgressBar("Applying settings changes on terrains",
                                                         string.Format("Updating terrain tile {0}", terrain.name),
                                                         ((float)index / terrains.Length));

                        if (m_Settings.EnableBasicSettings)
                        {
                            Undo.RecordObject(terrain, "Terrain property change");

                            terrain.groupingID           = m_Settings.GroupingID;
                            terrain.allowAutoConnect     = m_Settings.AutoConnect;
                            terrain.drawHeightmap        = m_Settings.DrawHeightmap;
                            terrain.drawInstanced        = m_Settings.DrawInstanced;
                            terrain.heightmapPixelError  = m_Settings.PixelError;
                            terrain.basemapDistance      = m_Settings.BaseMapDistance;
                            terrain.shadowCastingMode    = m_Settings.ShadowCastingMode;
                            terrain.materialTemplate     = m_Settings.MaterialTemplate;
                            terrain.reflectionProbeUsage = m_Settings.ReflectionProbeUsage;
#if UNITY_2019_2_OR_NEWER
#else
                            terrain.materialType = m_Settings.MaterialType;
                            if (m_Settings.MaterialType != Terrain.MaterialType.Custom)
                            {
                                terrain.legacySpecular  = m_Settings.LegacySpecular;
                                terrain.legacyShininess = m_Settings.LegacyShininess;
                            }
#endif
                        }

                        if (m_Settings.EnableMeshResSettings)
                        {
                            Undo.RecordObject(terrain.terrainData, "TerrainData property change");
                            Vector3 size = new Vector3(m_Settings.TerrainWidth, m_Settings.TerrainHeight,
                                                       m_Settings.TerrainLength);
                            terrain.terrainData.size = size;
                            terrain.terrainData.SetDetailResolution(m_Settings.DetailResolutaion,
                                                                    m_Settings.DetailResolutionPerPatch);
                        }

                        if (m_Settings.EnableTextureResSettings)
                        {
                            terrain.terrainData.baseMapResolution = m_Settings.BaseTextureResolution;
                            if (m_Settings.AlphaMapResolution != terrain.terrainData.alphamapResolution)
                            {
                                ToolboxHelper.ResizeControlTexture(terrain.terrainData, m_Settings.AlphaMapResolution);
                            }

                            if (m_Settings.HeightMapResolution != terrain.terrainData.heightmapResolution)
                            {
                                ToolboxHelper.ResizeHeightmap(terrain.terrainData, m_Settings.HeightMapResolution);
                            }
                        }

                        if (m_Settings.EnableTreeSettings)
                        {
                            Undo.RecordObject(terrain, "Terrain property change");

                            terrain.drawTreesAndFoliage         = m_Settings.DrawTreesAndFoliage;
                            terrain.bakeLightProbesForTrees     = m_Settings.BakeLightProbesForTrees;
                            terrain.deringLightProbesForTrees   = m_Settings.DeringLightProbesForTrees;
                            terrain.preserveTreePrototypeLayers = m_Settings.PreserveTreePrototypeLayers;
                            terrain.detailObjectDistance        = m_Settings.DetailObjectDistance;
                            terrain.collectDetailPatches        = m_Settings.CollectDetailPatches;
                            terrain.detailObjectDensity         = m_Settings.DetailObjectDensity;
                            terrain.treeDistance            = m_Settings.TreeDistance;
                            terrain.treeBillboardDistance   = m_Settings.TreeBillboardDistance;
                            terrain.treeCrossFadeLength     = m_Settings.TreeCrossFadeLength;
                            terrain.treeMaximumFullLODCount = m_Settings.TreeMaximumFullLODCount;
                        }

                        if (m_Settings.EnableWindSettings)
                        {
                            Undo.RecordObject(terrain.terrainData, "TerrainData property change");
                            terrain.terrainData.wavingGrassStrength = m_Settings.WavingGrassStrength;
                            terrain.terrainData.wavingGrassSpeed    = m_Settings.WavingGrassSpeed;
                            terrain.terrainData.wavingGrassAmount   = m_Settings.WavingGrassAmount;
                            terrain.terrainData.wavingGrassTint     = m_Settings.WavingGrassTint;
                        }

                        index++;
                    }
                }
            }
            finally
            {
                AssetDatabase.Refresh();
                EditorUtility.ClearProgressBar();
            }
        }
        void ApplySettingsToTerrains(Terrain[] terrains)
        {
            int index = 0;

            try
            {
                foreach (var terrain in terrains)
                {
                    EditorUtility.DisplayProgressBar("Applying settings changes on terrains", string.Format("Updating terrain tile {0}", terrain.name), ((float)index / terrains.Length));

                    if (m_Settings.EnableBasicSettings)
                    {
                        Undo.RecordObject(terrain, "Terrain property change");

                        terrain.groupingID           = m_Settings.GroupingID;
                        terrain.allowAutoConnect     = m_Settings.AutoConnect;
                        terrain.drawHeightmap        = m_Settings.DrawHeightmap;
                        terrain.drawInstanced        = m_Settings.DrawInstanced;
                        terrain.heightmapPixelError  = m_Settings.PixelError;
                        terrain.basemapDistance      = m_Settings.BaseMapDistance;
                        terrain.shadowCastingMode    = m_Settings.ShadowCastingMode;
                        terrain.materialTemplate     = m_Settings.MaterialTemplate;
                        terrain.reflectionProbeUsage = m_Settings.ReflectionProbeUsage;
#if UNITY_2019_2_OR_NEWER
#else
                        terrain.materialType = m_Settings.MaterialType;
                        if (m_Settings.MaterialType != Terrain.MaterialType.Custom)
                        {
                            terrain.legacySpecular  = m_Settings.LegacySpecular;
                            terrain.legacyShininess = m_Settings.LegacyShininess;
                        }
#endif
                    }

                    if (m_Settings.EnableMeshResSettings)
                    {
                        Undo.RecordObject(terrain.terrainData, "TerrainData property change");
                        Vector3 size = new Vector3(m_Settings.TerrainWidth, m_Settings.TerrainHeight, m_Settings.TerrainLength);
                        terrain.terrainData.size = size;
                        terrain.terrainData.SetDetailResolution(m_Settings.DetailResolutaion, m_Settings.DetailResolutionPerPatch);
                    }

                    if (m_Settings.EnableTextureResSettings)
                    {
                        terrain.terrainData.baseMapResolution = m_Settings.BaseTextureResolution;
                        if (m_Settings.AlphaMapResolution != terrain.terrainData.alphamapResolution)
                        {
                            ToolboxHelper.ResizeControlTexture(terrain.terrainData, m_Settings.AlphaMapResolution);
                        }
                        if (m_Settings.HeightMapResolution != terrain.terrainData.heightmapResolution)
                        {
                            ToolboxHelper.ResizeHeightmap(terrain.terrainData, m_Settings.HeightMapResolution);
                        }
                    }

                    if (m_Settings.EnableTreeSettings)
                    {
                        Undo.RecordObject(terrain, "Terrain property change");

                        terrain.drawTreesAndFoliage         = m_Settings.DrawTreesAndFoliage;
                        terrain.bakeLightProbesForTrees     = m_Settings.BakeLightProbesForTrees;
                        terrain.deringLightProbesForTrees   = m_Settings.DeringLightProbesForTrees;
                        terrain.preserveTreePrototypeLayers = m_Settings.PreserveTreePrototypeLayers;
                        terrain.detailObjectDistance        = m_Settings.DetailObjectDistance;
                        terrain.collectDetailPatches        = m_Settings.CollectDetailPatches;
                        terrain.detailObjectDensity         = m_Settings.DetailObjectDensity;
                        terrain.treeDistance            = m_Settings.TreeDistance;
                        terrain.treeBillboardDistance   = m_Settings.TreeBillboardDistance;
                        terrain.treeCrossFadeLength     = m_Settings.TreeCrossFadeLength;
                        terrain.treeMaximumFullLODCount = m_Settings.TreeMaximumFullLODCount;
                    }

                    if (m_Settings.EnableWindSettings)
                    {
                        Undo.RecordObject(terrain.terrainData, "TerrainData property change");
                        terrain.terrainData.wavingGrassStrength = m_Settings.WavingGrassStrength;
                        terrain.terrainData.wavingGrassSpeed    = m_Settings.WavingGrassSpeed;
                        terrain.terrainData.wavingGrassAmount   = m_Settings.WavingGrassAmount;
                        terrain.terrainData.wavingGrassTint     = m_Settings.WavingGrassTint;
                    }

                    index++;
                }
            }
            finally
            {
                AssetDatabase.Refresh();
                EditorUtility.ClearProgressBar();
            }
        }
        void Create()
        {
            // check lighting auto bake
            if (m_Settings.EnableLightingAutoBake)
            {
                UnityEditor.Lightmapping.giWorkflowMode = UnityEditor.Lightmapping.GIWorkflowMode.Iterative;
            }
            else
            {
                UnityEditor.Lightmapping.giWorkflowMode = UnityEditor.Lightmapping.GIWorkflowMode.OnDemand;
            }

            if (m_Settings.EnableClearExistingData)
            {
                ClearExistingTerrainGroup(m_Settings.GroupID);
            }

            // create tiles
            int        tileCount        = m_Settings.TilesX * m_Settings.TilesZ;
            Vector2Int tileOffset       = Vector2Int.zero;
            Vector2Int tileOffsetSource = Vector2Int.zero;
            Vector2Int tileResolution   = new Vector2Int(m_Settings.TerrainWidth / m_Settings.TilesX, m_Settings.TerrainLength / m_Settings.TilesZ);
            Vector3    tileSize         = new Vector3(tileResolution.x, m_Settings.TerrainHeight, tileResolution.y);
            Vector3    tilePosition     = m_Settings.StartPosition;

            Terrain[] terrains = new Terrain[tileCount];

            string assetFolderPath = GetAssetPathFromFullPath(m_Settings.TerrainAssetDirectory);
            int    tileIndex       = 0;

            try
            {
                // create terrain grouping object
                string       groupName    = "TerrainGroup_" + m_Settings.GroupID;
                GameObject   terrainGroup = new GameObject(groupName);
                TerrainGroup groupComp    = terrainGroup.AddComponent <TerrainGroup>();
                terrainGroup.transform.position = m_Settings.StartPosition;
                Heightmap globalHeightmap = null;

                Undo.RegisterCreatedObjectUndo(terrainGroup, "Create terrain");

                // heightmap offset
                if (m_Settings.UseGlobalHeightmap)
                {
                    byte[] rawData = File.ReadAllBytes(m_Settings.GlobalHeightmapPath);
                    globalHeightmap  = new Heightmap(rawData, m_Settings.FlipMode);
                    tileOffsetSource = new Vector2Int(globalHeightmap.Width / m_Settings.TilesX, globalHeightmap.Height / m_Settings.TilesZ);
                }
                else
                {
                    tileOffsetSource = tileResolution;
                }

                for (int x = 0; x < m_Settings.TilesX; x++, tileOffset.x += tileOffsetSource.x, tilePosition.x += tileResolution.x)
                {
                    tileOffset.y   = 0;
                    tilePosition.z = m_Settings.StartPosition.z;

                    for (int y = 0; y < m_Settings.TilesZ; y++, tileOffset.y += tileOffsetSource.y, tilePosition.z += tileResolution.y)
                    {
                        EditorUtility.DisplayProgressBar("Creating terrains", string.Format("Updating terrain tile ({0}, {1})", x, y), ((float)tileIndex / tileCount));

                        TerrainData terrainData = new TerrainData();
                        terrainData.alphamapResolution = m_Settings.ControlTextureResolution;
                        terrainData.baseMapResolution  = m_Settings.BaseTextureResolution;
                        terrainData.SetDetailResolution(m_Settings.DetailResolution, m_Settings.DetailResolutionPerPatch);

                        GameObject newGO      = Terrain.CreateTerrainGameObject(terrainData);
                        Terrain    newTerrain = newGO.GetComponent <Terrain>();
                        newTerrain.groupingID          = m_Settings.GroupID;
                        newTerrain.allowAutoConnect    = m_Settings.AutoConnect;
                        newTerrain.drawInstanced       = m_Settings.DrawInstanced;
                        newTerrain.heightmapPixelError = m_Settings.PixelError;
                        newTerrain.basemapDistance     = m_Settings.BaseMapDistance;
                        if (m_Settings.MaterialOverride != null)
                        {
                            newTerrain.materialTemplate = m_Settings.MaterialOverride;
#if UNITY_2019_2_OR_NEWER
#else
                            newTerrain.materialType = Terrain.MaterialType.Custom;
#endif
                        }

                        string terrainName = $"Terrain_{x}_{y}";;
                        if (m_Settings.EnableGuid)
                        {
                            Guid newGuid = Guid.NewGuid();
                            terrainName = $"Terrain_{x}_{y}_{newGuid}";
                        }
                        newGO.name = terrainName;
                        newTerrain.transform.position = tilePosition;
                        newTerrain.transform.SetParent(terrainGroup.transform);

                        // import height
                        if (m_Settings.HeightmapMode == Heightmap.Mode.Global && globalHeightmap != null)
                        {
                            Heightmap tileHeightmap = GetTileHeightmapFromGlobalHeightmap(globalHeightmap, tileOffset);
                            tileHeightmap.ApplyTo(newTerrain);
                        }

                        if (m_Settings.HeightmapMode == Heightmap.Mode.Tiles || m_Settings.HeightmapMode == Heightmap.Mode.Batch)
                        {
                            if (File.Exists(m_Settings.TileHeightmapPaths[tileIndex]))
                            {
                                var       remap       = (m_Settings.HeightmapRemapMax - m_Settings.HeightmapRemapMin) / m_Settings.TerrainHeight;
                                var       baseLevel   = m_Settings.HeightmapRemapMin / m_Settings.TerrainHeight;
                                byte[]    rawTileData = File.ReadAllBytes(m_Settings.TileHeightmapPaths[tileIndex]);
                                Heightmap tileHeight  = new Heightmap(rawTileData, m_Settings.FlipMode);
                                Heightmap tileMap     = new Heightmap(tileHeight, Vector2Int.zero, new Vector2Int(tileHeight.Width, tileHeight.Height), remap, baseLevel);
                                tileMap.ApplyTo(newTerrain);
                            }
                        }

                        terrains[tileIndex] = newTerrain;
                        tileIndex++;

                        // save terrain data asset
                        terrainData.size = tileSize;                         // set terrain size after heightmap process
                        string assetPath = $"{assetFolderPath}/{terrainName}.asset";
                        if (!Directory.Exists(assetFolderPath))
                        {
                            Directory.CreateDirectory(assetFolderPath);
                        }
                        AssetDatabase.CreateAsset(terrainData, assetPath);

                        // finally, resize height resolution if needed
                        if (terrainData.heightmapResolution != (m_Settings.HeightmapResolution))
                        {
                            ToolboxHelper.ResizeHeightmap(terrainData, (m_Settings.HeightmapResolution));
                        }

                        Undo.RegisterCreatedObjectUndo(newGO, "Create terrain");
                    }
                }

                m_Terrains     = terrains;
                m_CurrentGroup = terrainGroup;

                UpdateGroupSettings(groupComp);
                ToolboxHelper.CalculateAdjacencies(m_Terrains, m_Settings.TilesX, m_Settings.TilesZ);
            }
            finally
            {
                AssetDatabase.SaveAssets();
                AssetDatabase.Refresh();
                EditorUtility.ClearProgressBar();
            }
        }