Exemple #1
0
 void OnEnable()
 {
     if (Terrain.activeTerrain != null)
     {
         m_selectedMask = GaiaSplatPrototype.GetGaiaSplatPrototypes(Terrain.activeTerrain).Length;
     }
 }
Exemple #2
0
        void OnGUI()
        {
            //Set up the box style
            if (m_boxStyle == null)
            {
                m_boxStyle = new GUIStyle(GUI.skin.box);
                m_boxStyle.normal.textColor = GUI.skin.label.normal.textColor;
                m_boxStyle.fontStyle        = FontStyle.Bold;
                m_boxStyle.alignment        = TextAnchor.UpperLeft;
            }

            //Setup the wrap style
            if (m_wrapStyle == null)
            {
                m_wrapStyle           = new GUIStyle(GUI.skin.label);
                m_wrapStyle.fontStyle = FontStyle.Normal;
                m_wrapStyle.wordWrap  = true;
            }

            //Text intro
            GUILayout.BeginVertical("Gaia Mask Exporter", m_boxStyle);
            GUILayout.Space(20);
            EditorGUILayout.LabelField("The Gaia splatmap exporter allows you to export texture splatmaps to use as masks.", m_wrapStyle);
            GUILayout.EndVertical();

            if (string.IsNullOrEmpty(m_maskName))
            {
                m_maskName = string.Format("Terrain-Splatmaps-{0:yyyyMMdd-HHmmss}", DateTime.Now);
            }
            m_maskName = EditorGUILayout.TextField(GetLabel("Mask Name"), m_maskName);

            List <GUIContent> textureNames = new List <GUIContent>();

            if (Terrain.activeTerrain != null)
            {
                var splatPrototypes = GaiaSplatPrototype.GetGaiaSplatPrototypes(Terrain.activeTerrain);
                for (int idx = 0; idx < splatPrototypes.Length; idx++)
                {
                    textureNames.Add(new GUIContent(splatPrototypes[idx].texture.name));
                }
            }
            textureNames.Add(new GUIContent("All"));
            m_selectedMask = EditorGUILayout.Popup(GetLabel("Selected Texture"), m_selectedMask, textureNames.ToArray());

            GUILayout.Space(5);

            EditorGUI.indentLevel++;
            if (DisplayButton(GetLabel("Export Selected Texture")))
            {
                ExportMask();
            }
            EditorGUI.indentLevel--;
        }
        /// <summary>
        /// Gets all splat prototypes from a terrain. Uses the correct terrain API for pre and post Unity 2018.3.
        /// </summary>
        /// <param name="terrain">The terrain containing the splat prototype data.</param>
        /// <returns>Null if invalid terrain data. An empty GaiaSplatPrototype array if no splat prototypes in terrain data. A filled GaiaSplatPrototype array if splat prototypes present.</returns>
        public static GaiaSplatPrototype[] GetGaiaSplatPrototypes(Terrain terrain)
        {
            if (terrain == null || terrain.terrainData == null)
            {
                return(null);
            }
            TerrainData terrainData = terrain.terrainData;

#if UNITY_2018_3_OR_NEWER
            if (terrainData.terrainLayers == null || terrainData.terrainLayers.Length == 0)
            {
                return(new GaiaSplatPrototype[0]);
            }

            GaiaSplatPrototype[] splatPrototypes = new GaiaSplatPrototype[terrainData.terrainLayers.Length];

            for (int i = 0; i < terrainData.terrainLayers.Length; i++)
            {
                splatPrototypes[i] = new GaiaSplatPrototype(terrainData.terrainLayers[i]);
            }
            return(splatPrototypes);
#else
            if (terrainData.splatPrototypes == null || terrainData.splatPrototypes.Length == 0)
            {
                return(new GaiaSplatPrototype[0]);
            }

            GaiaSplatPrototype[] splatPrototypes = new GaiaSplatPrototype[terrainData.splatPrototypes.Length];

            for (int i = 0; i < terrainData.splatPrototypes.Length; i++)
            {
                splatPrototypes[i] = new GaiaSplatPrototype(terrainData.splatPrototypes[i]);
            }
            return(splatPrototypes);
#endif
        }
Exemple #4
0
        /// <summary>
        /// Takes a spawner preset list and assembles arrays with the new prototypes in them. If a reference Terrain is passed in, the arrays will contain the existing prototypes on the terrain + only the additional stuff from the preset list, no duplicates.
        /// </summary>
        /// <param name="spawnerPresetList"></param>
        /// <param name="terrainLayers"></param>
        /// <param name="terrainDetails"></param>
        /// <param name="terrainTrees"></param>
        /// <param name="referenceTerrain"></param>
        public static void GetPrototypes(List <BiomeSpawnerListEntry> spawnerPresetList, ref TerrainLayer[] terrainLayers, ref DetailPrototype[] terrainDetails, ref TreePrototype[] terrainTrees, Terrain referenceTerrain = null)
        {
            //Early out when no spawner preset list
            if (spawnerPresetList == null || spawnerPresetList.Count == 0)
            {
                return;
            }

            //collect the splat prototypes in a GaiaSplatPrototype List first, then build a terrain layer array from that later
            List <GaiaSplatPrototype> presetSplatPrototypes = new List <GaiaSplatPrototype>();
            List <DetailPrototype>    presetTerrainDetails  = new List <DetailPrototype>();
            List <TreePrototype>      presetTerrainTrees    = new List <TreePrototype>();


            //if there is a reference terrain, start by pre-filling those lists with the prototypes from the terrain
            if (referenceTerrain != null)
            {
                foreach (TerrainLayer layer in referenceTerrain.terrainData.terrainLayers)
                {
                    presetSplatPrototypes.Add(new GaiaSplatPrototype(layer));
                }
                foreach (DetailPrototype detailPrototype in referenceTerrain.terrainData.detailPrototypes)
                {
                    presetTerrainDetails.Add(detailPrototype);
                }
                foreach (TreePrototype treePrototype in referenceTerrain.terrainData.treePrototypes)
                {
                    presetTerrainTrees.Add(treePrototype);
                }
            }

            foreach (BiomeSpawnerListEntry preset in spawnerPresetList.Where(x => x.m_autoAssignPrototypes == true))
            {
                if (preset == null)
                {
                    //Skip entries missing information
                    continue;
                }

                if (preset.m_spawnerSettings == null)
                {
                    continue;
                }

                if (preset.m_spawnerSettings.m_resources == null)
                {
                    continue;
                }

                GaiaResource resources = preset.m_spawnerSettings.m_resources;
                foreach (SpawnRule sr in preset.m_spawnerSettings.m_spawnerRules)
                {
                    //skip if resource is not maintained properly (=null)
                    if (sr.ResourceIsNull(preset.m_spawnerSettings))
                    {
                        Debug.Log("Spawn Rule " + sr.m_name + " in " + preset.m_spawnerSettings.name + " has missing resources maintained. This rule might not work properly when spawning later.");
                        continue;
                    }

                    switch (sr.m_resourceType)
                    {
                    case GaiaConstants.SpawnerResourceType.TerrainTexture:
                        ResourceProtoTexture protoTexture = resources.m_texturePrototypes[sr.m_resourceIdx];
                        if (protoTexture != null)
                        {
                            GaiaSplatPrototype newSplat = new GaiaSplatPrototype();
                            newSplat.normalMap       = protoTexture.m_normal;
                            newSplat.normalScale     = protoTexture.m_normalScale;
                            newSplat.smoothness      = protoTexture.m_smoothness;
                            newSplat.metallic        = protoTexture.m_metallic;
                            newSplat.diffuseRemapMin = protoTexture.m_diffuseRemapMin;
                            newSplat.diffuseRemapMax = protoTexture.m_diffuseRemapMax;
                            newSplat.maskMapRemapMin = protoTexture.m_maskMapRemapMin;
                            newSplat.maskMapRemapMax = protoTexture.m_maskMapRemapMax;
                            newSplat.specularColor   = protoTexture.m_specularColor;
                            newSplat.tileOffset      = new Vector2(protoTexture.m_offsetX, protoTexture.m_offsetY);
                            newSplat.tileSize        = new Vector2(protoTexture.m_sizeX, protoTexture.m_sizeY);
                            newSplat.texture         = protoTexture.m_texture;
                            newSplat.maskMap         = protoTexture.m_maskmap;
                            //Only add as a new prototype if not a fully equal prototype already exists in the list
                            if (!presetSplatPrototypes.Exists(x => x.texture == newSplat.texture &&
                                                              x.normalMap == newSplat.normalMap &&
                                                              x.tileOffset == newSplat.tileOffset &&
                                                              x.tileSize == newSplat.tileSize
                                                              ))
                            {
                                presetSplatPrototypes.Add(newSplat);
                            }
                        }
                        break;

                    case GaiaConstants.SpawnerResourceType.TerrainDetail:
                        ResourceProtoDetail protoDetail = resources.m_detailPrototypes[sr.m_resourceIdx];
                        if (protoDetail != null)
                        {
                            DetailPrototype newTerrainDetail = new DetailPrototype();
                            newTerrainDetail.renderMode       = protoDetail.m_renderMode;
                            newTerrainDetail.prototypeTexture = protoDetail.m_detailTexture;
                            newTerrainDetail.prototype        = protoDetail.m_detailProtoype;
                            newTerrainDetail.dryColor         = protoDetail.m_dryColour;
                            newTerrainDetail.healthyColor     = protoDetail.m_healthyColour;
                            newTerrainDetail.maxHeight        = protoDetail.m_maxHeight;
                            newTerrainDetail.maxWidth         = protoDetail.m_maxWidth;
                            newTerrainDetail.minHeight        = protoDetail.m_minHeight;
                            newTerrainDetail.minWidth         = protoDetail.m_minWidth;
                            newTerrainDetail.noiseSpread      = protoDetail.m_noiseSpread;

                            if ((protoDetail.m_renderMode == DetailRenderMode.Grass && protoDetail.m_detailProtoype == null) || protoDetail.m_renderMode == DetailRenderMode.GrassBillboard)
                            {
                                if (!presetTerrainDetails.Exists(x => x.prototypeTexture == newTerrainDetail.prototypeTexture &&
                                                                 x.prototype == newTerrainDetail.prototype &&
                                                                 x.dryColor == newTerrainDetail.dryColor &&
                                                                 x.healthyColor == newTerrainDetail.healthyColor &&
                                                                 x.maxHeight == newTerrainDetail.maxHeight &&
                                                                 x.maxWidth == newTerrainDetail.maxWidth &&
                                                                 x.minHeight == newTerrainDetail.minHeight &&
                                                                 x.minWidth == newTerrainDetail.minWidth &&
                                                                 x.noiseSpread == newTerrainDetail.noiseSpread
                                                                 ))
                                {
                                    presetTerrainDetails.Add(newTerrainDetail);
                                }
                            }
                            else
                            {
                                if (!presetTerrainDetails.Exists(x => x.prototype == newTerrainDetail.prototype &&
                                                                 x.prototype == newTerrainDetail.prototype &&
                                                                 x.dryColor == newTerrainDetail.dryColor &&
                                                                 x.healthyColor == newTerrainDetail.healthyColor &&
                                                                 x.maxHeight == newTerrainDetail.maxHeight &&
                                                                 x.maxWidth == newTerrainDetail.maxWidth &&
                                                                 x.minHeight == newTerrainDetail.minHeight &&
                                                                 x.minWidth == newTerrainDetail.minWidth &&
                                                                 x.noiseSpread == newTerrainDetail.noiseSpread
                                                                 ))
                                {
                                    presetTerrainDetails.Add(newTerrainDetail);
                                }
                            }
                        }
                        break;

                    case GaiaConstants.SpawnerResourceType.TerrainTree:
                        ResourceProtoTree protoTree = resources.m_treePrototypes[sr.m_resourceIdx];
                        if (protoTree != null)
                        {
                            TreePrototype newTree = new TreePrototype();
                            newTree.bendFactor = protoTree.m_bendFactor;
                            newTree.prefab     = protoTree.m_desktopPrefab;
                            if (!presetTerrainTrees.Exists(x => x.bendFactor == newTree.bendFactor &&
                                                           x.prefab == newTree.prefab))
                            {
                                presetTerrainTrees.Add(newTree);
                            }
                        }
                        break;
                    }
                }
            }

            //now look at the existing terrain layers on the terrain again, and add only the additional new Splat Prototypes as new layers - all the other ones must exist on the terrains already
            List <GaiaSplatPrototype> additionalSplatPrototypes = new List <GaiaSplatPrototype>();
            List <DetailPrototype>    additionalTerrainDetails  = new List <DetailPrototype>();
            List <TreePrototype>      additionalTerrainTrees    = new List <TreePrototype>();

            //Do we have a refernece terrain? The only the splat prototypes with a higher index then what is currently present on the terrain already are relevant
            if (referenceTerrain != null)
            {
                for (int i = referenceTerrain.terrainData.terrainLayers.Length; i <= presetSplatPrototypes.Count - 1; i++)
                {
                    additionalSplatPrototypes.Add(presetSplatPrototypes[i]);
                }
                for (int i = referenceTerrain.terrainData.detailPrototypes.Length; i <= presetTerrainDetails.Count - 1; i++)
                {
                    additionalTerrainDetails.Add(presetTerrainDetails[i]);
                }
                for (int i = referenceTerrain.terrainData.treePrototypes.Length; i <= presetTerrainTrees.Count - 1; i++)
                {
                    additionalTerrainTrees.Add(presetTerrainTrees[i]);
                }
            }
            else
            {
                //no reference terrain - we take preset prototypes collected before
                additionalSplatPrototypes = presetSplatPrototypes;
                additionalTerrainDetails  = presetTerrainDetails;
                additionalTerrainTrees    = presetTerrainTrees;
            }

            //convert Gaia Splat Prototypes into actual terrain layer files
            string layername = string.Format("Gaia_-{0:yyyyMMdd-HHmmss}", DateTime.Now);

            TerrainLayer[] additionalTerrainLayers = GaiaSplatPrototype.CreateTerrainLayers(layername, additionalSplatPrototypes.ToArray());

            if (referenceTerrain != null)
            {
                //got a reference terrain? return the existing prototypes so they are not altered and attach the truly new ones
                terrainLayers = referenceTerrain.terrainData.terrainLayers;
                terrainLayers = terrainLayers.Concat(additionalTerrainLayers).ToArray();

                terrainDetails = referenceTerrain.terrainData.detailPrototypes;
                terrainDetails = terrainDetails.Concat(additionalTerrainDetails.ToArray()).ToArray();

                terrainTrees = referenceTerrain.terrainData.treePrototypes;
                terrainTrees = terrainTrees.Concat(additionalTerrainTrees.ToArray()).ToArray();
            }
            else
            {
                //no reference terrain, just return all the new stuff directly
                terrainLayers  = additionalTerrainLayers;
                terrainDetails = additionalTerrainDetails.ToArray();
                terrainTrees   = additionalTerrainTrees.ToArray();
            }
        }