예제 #1
0
 public static TerrainLayer GetLayerFromPrototype(ResourceProtoTexture proto)
 {
     foreach (Terrain t in Terrain.activeTerrains)
     {
         foreach (TerrainLayer layer in t.terrainData.terrainLayers)
         {
             if (proto != null && layer != null)
             {
                 if (proto.m_texture != null && layer.diffuseTexture != null)
                 {
                     if (PWCommon4.Utils.IsSameTexture(proto.m_texture, layer.diffuseTexture, false) == true)
                     {
                         return(layer);
                     }
                 }
             }
         }
     }
     return(null);
 }
예제 #2
0
        /// <summary>
        /// Extract and save the resources file
        /// </summary>
        /// <param name="writer"></param>
        /// <param name="source"></param>
        private void SaveResources(StreamWriter writer, GaiaResource source)
        {
            if (writer == null)
            {
                Debug.LogError("Can not write resources, writer not supplied.");
                return;
            }
            if (source == null)
            {
                Debug.LogError("Can not write resources, resources not supplied.");
                return;
            }

            //Create extraction path
            string path = "Assets/GaiaExtensions/";

            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            path += m_extensionName + "/";
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            path += Path.GetFileName(AssetDatabase.GetAssetPath(source.GetInstanceID()));

            GaiaResource resources = ScriptableObject.CreateInstance <Gaia.GaiaResource>();

            AssetDatabase.CreateAsset(resources, path);
            resources.m_beachHeight   = source.m_beachHeight;
            resources.m_name          = source.m_name;
            resources.m_resourcesID   = source.m_resourcesID;
            resources.m_seaLevel      = source.m_seaLevel;
            resources.m_terrainHeight = source.m_terrainHeight;

            //Iterate through the prototypes
            SpawnCritera         srcCrit, newCrit;
            ResourceProtoTexture srcTex, newTex;

            resources.m_texturePrototypes = new ResourceProtoTexture[source.m_texturePrototypes.GetLength(0)];
            for (int resIdx = 0; resIdx < source.m_texturePrototypes.GetLength(0); resIdx++)
            {
                srcTex              = source.m_texturePrototypes[resIdx];
                newTex              = new ResourceProtoTexture();
                newTex.m_metalic    = srcTex.m_metalic;
                newTex.m_name       = srcTex.m_name;
                newTex.m_normal     = srcTex.m_normal;
                newTex.m_offsetX    = srcTex.m_offsetX;
                newTex.m_offsetY    = srcTex.m_offsetY;
                newTex.m_sizeX      = srcTex.m_sizeX;
                newTex.m_sizeY      = srcTex.m_sizeY;
                newTex.m_smoothness = srcTex.m_smoothness;
                newTex.m_texture    = srcTex.m_texture;

                newTex.m_spawnCriteria = new SpawnCritera[srcTex.m_spawnCriteria.GetLength(0)];
                for (int critIdx = 0; critIdx < srcTex.m_spawnCriteria.GetLength(0); critIdx++)
                {
                    srcCrit = srcTex.m_spawnCriteria[critIdx];

                    newCrit = new SpawnCritera();
                    newCrit.m_checkHeight      = srcCrit.m_checkHeight;
                    newCrit.m_checkProximity   = srcCrit.m_checkProximity;
                    newCrit.m_checkSlope       = srcCrit.m_checkSlope;
                    newCrit.m_checkTexture     = srcCrit.m_checkTexture;
                    newCrit.m_checkType        = srcCrit.m_checkType;
                    newCrit.m_heightFitness    = srcCrit.m_heightFitness;
                    newCrit.m_isActive         = srcCrit.m_isActive;
                    newCrit.m_matchingTextures = srcCrit.m_matchingTextures;
                    newCrit.m_maxHeight        = srcCrit.m_maxHeight;

                    newTex.m_spawnCriteria[critIdx] = newCrit;
                }
                resources.m_texturePrototypes[resIdx] = newTex;
            }
        }
예제 #3
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();
            }
        }
예제 #4
0
        public Spawner CreateSpawner(bool autoAddResources = false, Transform targetTransform = null)
        {
            //Find or create gaia
            GameObject gaiaObj    = GaiaUtils.GetGaiaGameObject();
            GameObject spawnerObj = new GameObject(this.name);

            spawnerObj.AddComponent <Spawner>();
            if (targetTransform != null)
            {
                spawnerObj.transform.parent = targetTransform;
            }
            else
            {
                spawnerObj.transform.parent = gaiaObj.transform;
            }

            Spawner spawner = spawnerObj.GetComponent <Spawner>();

            spawner.LoadSettings(this);
            //spawner.m_settings.m_resources = (GaiaResource)AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(this.m_resourcesGUID), typeof(GaiaResource));
            if (autoAddResources)
            {
                TerrainLayer[]    terrainLayers  = new TerrainLayer[0];
                DetailPrototype[] terrainDetails = new DetailPrototype[0];
                TreePrototype[]   terrainTrees   = new TreePrototype[0];
                GaiaDefaults.GetPrototypes(new List <BiomeSpawnerListEntry>()
                {
                    new BiomeSpawnerListEntry()
                    {
                        m_spawnerSettings = this, m_autoAssignPrototypes = true
                    }
                }, ref terrainLayers, ref terrainDetails, ref terrainTrees, Terrain.activeTerrain);

                foreach (Terrain t in Terrain.activeTerrains)
                {
                    GaiaDefaults.ApplyPrototypesToTerrain(t, terrainLayers, terrainDetails, terrainTrees);
                }
            }

            //We need to check the texture prototypes in this spawner against the already created terrain layers for this session
            //- otherwise the spawner will not know about those in subsequent spawns and might create unneccessary additional layers

            //Get a list of all exisiting Terrain Layers for this session
            string path = GaiaDirectories.GetTerrainLayerPath();

#if UNITY_EDITOR
            AssetDatabase.ImportAsset(path);
            if (Directory.Exists(path))
            {
                string[] allLayerGuids = AssetDatabase.FindAssets("t:TerrainLayer", new string[1] {
                    path
                });
                List <TerrainLayer> existingTerrainLayers = new List <TerrainLayer>();
                foreach (string guid in allLayerGuids)
                {
                    try
                    {
                        TerrainLayer layer = (TerrainLayer)AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(guid), typeof(TerrainLayer));
                        if (layer != null)
                        {
                            existingTerrainLayers.Add(layer);
                        }
                    }
                    catch (Exception ex)
                    {
                        if (ex.Message == "")
                        {
                        }
                    }
                }
                foreach (SpawnRule sr in spawner.m_settings.m_spawnerRules)
                {
                    if (sr.m_resourceType == SpawnerResourceType.TerrainTexture)
                    {
                        ResourceProtoTexture protoTexture = spawner.m_settings.m_resources.m_texturePrototypes[sr.m_resourceIdx];
                        //if a terrainLayer with these properties exist we can assume it fits to the given spawn rule
                        TerrainLayer terrainLayer = existingTerrainLayers.FirstOrDefault(x => x.diffuseTexture == protoTexture.m_texture &&
                                                                                         x.normalMapTexture == protoTexture.m_normal &&
                                                                                         x.tileOffset == new Vector2(protoTexture.m_offsetX, protoTexture.m_offsetY) &&
                                                                                         x.tileSize == new Vector2(protoTexture.m_sizeX, protoTexture.m_sizeY)
                                                                                         );
                        if (terrainLayer != null)
                        {
                            protoTexture.m_LayerGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(terrainLayer));
                        }
                    }
                }
            }
#endif


            foreach (SpawnRule rule in spawner.m_settings.m_spawnerRules)
            {
                rule.m_spawnedInstances = 0;
            }

            if (Terrain.activeTerrains.Where(x => !TerrainHelper.IsWorldMapTerrain(x)).Count() > 0)
            {
                spawner.FitToAllTerrains();
            }
            //else
            //{
            //    spawner.FitToTerrain();
            //}
            return(spawner);
        }