2820 lines
123 KiB
C#
2820 lines
123 KiB
C#
using UnityEngine;
|
|
using System.Collections.Generic;
|
|
using System;
|
|
#if UNITY_EDITOR
|
|
using UnityEditor;
|
|
#endif
|
|
|
|
namespace Gaia
|
|
{
|
|
[System.Serializable]
|
|
public class GaiaResource
|
|
{
|
|
[Tooltip("Unique identifier for these resources."), HideInInspector]
|
|
public string m_resourcesID = Guid.NewGuid().ToString();
|
|
[Tooltip("Resource name")]
|
|
public string m_name = "Gaia Resource";
|
|
//[Tooltip("The absolute height of the sea or water table in meters. All spawn criteria heights are calculated relative to this. This can also be thought of as the water level. This value is sourced from the defaults file, and managed on a session by session basis.")]
|
|
//public float m_seaLevel = 100f;
|
|
[Tooltip("The beach height in meters. Beaches are spawned at sea level and are extended for this height above sea level. This is used when creating default spawn rules in order to create a beach in the zone between water and land.")]
|
|
public float m_beachHeight = 5f;
|
|
[Tooltip("Terrain height.")]
|
|
public float m_terrainHeight = 1000f;
|
|
[Tooltip("Texture prototypes and fitness criteria.")]
|
|
public ResourceProtoTexture[] m_texturePrototypes = new ResourceProtoTexture[0];
|
|
[Tooltip("Detail prototypes, dna and fitness criteria.")]
|
|
public ResourceProtoDetail[] m_detailPrototypes = new ResourceProtoDetail[0];
|
|
[Tooltip("Tree prototypes, dna and fitness criteria.")]
|
|
public ResourceProtoTree[] m_treePrototypes = new ResourceProtoTree[0];
|
|
[Tooltip("Game object prototypes, dna and fitness criteria.")]
|
|
public ResourceProtoGameObject[] m_gameObjectPrototypes = new ResourceProtoGameObject[0];
|
|
[Tooltip("GeNa spawner prototypes")]
|
|
public ResourceProtoSpawnExtension[] m_spawnExtensionPrototypes = new ResourceProtoSpawnExtension[0];
|
|
[Tooltip("Stamp prototypes for World Generator")]
|
|
public ResourceProtoStampDistribution[] m_stampDistributionPrototypes = new ResourceProtoStampDistribution[0];
|
|
[Tooltip("Prototypes for the World Biome Masks")]
|
|
public ResourceProtoWorldBiomeMask[] m_worldBiomeMaskPrototypes = new ResourceProtoWorldBiomeMask[0];
|
|
[Tooltip("Prototypes for Light / Reflection Probes")]
|
|
public ResourceProtoProbe[] m_probePrototypes = new ResourceProtoProbe[0];
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// Set up the asset associations, return true if something changes. Can only be run when the editor is present.
|
|
/// </summary>
|
|
/// <returns>True if something changes</returns>
|
|
public bool SetAssetAssociations()
|
|
{
|
|
int idx = 0;
|
|
bool isChanged = false;
|
|
|
|
ResourceProtoTexture texturePrototype;
|
|
for (idx = 0; idx < m_texturePrototypes.GetLength(0); idx++)
|
|
{
|
|
texturePrototype = m_texturePrototypes[idx];
|
|
if (texturePrototype.SetAssetAssociations())
|
|
{
|
|
isChanged = true;
|
|
}
|
|
}
|
|
|
|
ResourceProtoDetail detailPrototype;
|
|
for (idx = 0; idx < m_detailPrototypes.GetLength(0); idx++)
|
|
{
|
|
detailPrototype = m_detailPrototypes[idx];
|
|
if (detailPrototype.SetAssetAssociations())
|
|
{
|
|
isChanged = true;
|
|
}
|
|
}
|
|
|
|
ResourceProtoTree treePrototype;
|
|
for (idx = 0; idx < m_treePrototypes.GetLength(0); idx++)
|
|
{
|
|
treePrototype = m_treePrototypes[idx];
|
|
if (treePrototype.SetAssetAssociations())
|
|
{
|
|
isChanged = true;
|
|
}
|
|
}
|
|
|
|
ResourceProtoGameObject goPrototype;
|
|
for (idx = 0; idx < m_gameObjectPrototypes.GetLength(0); idx++)
|
|
{
|
|
goPrototype = m_gameObjectPrototypes[idx];
|
|
if (goPrototype.SetAssetAssociations())
|
|
{
|
|
isChanged = true;
|
|
}
|
|
}
|
|
|
|
return isChanged;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Associate any unallocated assets to this resource. Return true if something changes.
|
|
/// </summary>
|
|
/// <returns>True of the resources were changed in any way</returns>
|
|
public bool AssociateAssets()
|
|
{
|
|
int idx = 0;
|
|
bool isChanged = false;
|
|
|
|
ResourceProtoTexture texturePrototype;
|
|
for (idx = 0; idx < m_texturePrototypes.GetLength(0); idx++)
|
|
{
|
|
texturePrototype = m_texturePrototypes[idx];
|
|
if (texturePrototype.AssociateAssets())
|
|
{
|
|
isChanged = true;
|
|
}
|
|
}
|
|
|
|
ResourceProtoDetail detailPrototype;
|
|
for (idx = 0; idx < m_detailPrototypes.GetLength(0); idx++)
|
|
{
|
|
detailPrototype = m_detailPrototypes[idx];
|
|
if (detailPrototype.AssociateAssets())
|
|
{
|
|
isChanged = true;
|
|
}
|
|
}
|
|
|
|
ResourceProtoTree treePrototype;
|
|
for (idx = 0; idx < m_treePrototypes.GetLength(0); idx++)
|
|
{
|
|
treePrototype = m_treePrototypes[idx];
|
|
if (treePrototype.AssociateAssets())
|
|
{
|
|
isChanged = true;
|
|
}
|
|
}
|
|
|
|
ResourceProtoGameObject goPrototype;
|
|
for (idx = 0; idx < m_gameObjectPrototypes.GetLength(0); idx++)
|
|
{
|
|
goPrototype = m_gameObjectPrototypes[idx];
|
|
if (goPrototype.AssociateAssets())
|
|
{
|
|
isChanged = true;
|
|
}
|
|
}
|
|
|
|
return isChanged;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Delete all the prototypes
|
|
/// </summary>
|
|
public void DeletePrototypes()
|
|
{
|
|
m_texturePrototypes = new ResourceProtoTexture[0];
|
|
m_detailPrototypes = new ResourceProtoDetail[0];
|
|
m_treePrototypes = new ResourceProtoTree[0];
|
|
m_gameObjectPrototypes = new ResourceProtoGameObject[0];
|
|
//m_stampPrototypes = new ResourceProtoStamp[0];
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check if any of the resource prototypes are missing from the terrain
|
|
/// </summary>
|
|
/// <returns>True if any of the prototypes are missing from the terrain</returns>
|
|
public bool PrototypesMissingFromTerrain()
|
|
{
|
|
Terrain terrain = Gaia.TerrainHelper.GetActiveTerrain();
|
|
if (terrain == null)
|
|
{
|
|
Debug.LogWarning("Could not check assets in terrain as no terrain has been supplied.");
|
|
return false;
|
|
}
|
|
|
|
int idx = 0;
|
|
for (idx = 0; idx < m_texturePrototypes.GetLength(0); idx++)
|
|
{
|
|
if (PrototypeMissingFromTerrain(GaiaConstants.SpawnerResourceType.TerrainTexture, idx))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
for (idx = 0; idx < m_detailPrototypes.GetLength(0); idx++)
|
|
{
|
|
if (PrototypeMissingFromTerrain(GaiaConstants.SpawnerResourceType.TerrainDetail, idx))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
for (idx = 0; idx < m_treePrototypes.GetLength(0); idx++)
|
|
{
|
|
if (PrototypeMissingFromTerrain(GaiaConstants.SpawnerResourceType.TerrainTree, idx))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
for (idx = 0; idx < m_gameObjectPrototypes.GetLength(0); idx++)
|
|
{
|
|
if (PrototypeMissingFromTerrain(GaiaConstants.SpawnerResourceType.GameObject, idx))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check if a specific prototype is missing from the terrain
|
|
/// </summary>
|
|
/// <param name="resourceType">Type of resource</param>
|
|
/// <param name="resourceIdx">Index of the resource</param>
|
|
/// <returns>True if it is missing, false otherwise</returns>
|
|
public bool PrototypeMissingFromTerrain(GaiaConstants.SpawnerResourceType resourceType, int resourceIdx, Terrain terrain = null)
|
|
{
|
|
if (terrain == null)
|
|
{
|
|
terrain = Terrain.activeTerrain;
|
|
}
|
|
|
|
if (PrototypeIdxInTerrain(resourceType, resourceIdx, terrain) == -1)
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get the prototype index in the actual terrain and return its index, otherwise -1 signifies not found
|
|
/// </summary>
|
|
/// <param name="resourceType">Type of resource to check</param>
|
|
/// <param name="resourceIdx">Index of the resource to check</param>
|
|
/// <returns>Index in the terrain if found, -1 if not found</returns>
|
|
public int PrototypeIdxInTerrain(GaiaConstants.SpawnerResourceType resourceType, int resourceIdx, Terrain terrain = null)
|
|
{
|
|
//Error index -1 = not found
|
|
int errorIdx = -1;
|
|
int localTerrainIdx = 0;
|
|
|
|
|
|
if (terrain == null)
|
|
{
|
|
terrain = Terrain.activeTerrain;
|
|
}
|
|
|
|
|
|
//Check to see if we have a terrain
|
|
if (terrain == null)
|
|
{
|
|
return errorIdx;
|
|
}
|
|
|
|
//Check the resource index
|
|
if (ResourceIdxOutOfBounds(resourceType, resourceIdx))
|
|
{
|
|
return errorIdx;
|
|
}
|
|
|
|
//Check to see if its actually available in unity
|
|
if (!ResourceIsInUnity(resourceType, resourceIdx))
|
|
{
|
|
return errorIdx;
|
|
}
|
|
|
|
//Now see if the resource exists within that terrain
|
|
switch (resourceType)
|
|
{
|
|
case GaiaConstants.SpawnerResourceType.TerrainTexture:
|
|
#if UNITY_2018_3_OR_NEWER
|
|
ResourceProtoTexture splat = m_texturePrototypes[resourceIdx];
|
|
foreach (TerrainLayer proto in terrain.terrainData.terrainLayers)
|
|
{
|
|
if (splat != null && proto != null)
|
|
{
|
|
if (splat.m_texture != null && proto.diffuseTexture != null)
|
|
{
|
|
if (PWCommon3.Utils.IsSameTexture(splat.m_texture, proto.diffuseTexture, false) == true)
|
|
{
|
|
return localTerrainIdx;
|
|
}
|
|
}
|
|
}
|
|
localTerrainIdx++;
|
|
}
|
|
#else
|
|
ResourceProtoTexture splat = m_texturePrototypes[resourceIdx];
|
|
foreach (GaiaSplatPrototype proto in GaiaSplatPrototype.GetGaiaSplatPrototypes(terrain))
|
|
{
|
|
if (PWCommon1.Utils.IsSameTexture(splat.m_texture, proto.texture, false) == true)
|
|
{
|
|
return localTerrainIdx;
|
|
}
|
|
localTerrainIdx++;
|
|
}
|
|
#endif
|
|
return errorIdx;
|
|
case GaiaConstants.SpawnerResourceType.TerrainDetail:
|
|
ResourceProtoDetail detail = m_detailPrototypes[resourceIdx];
|
|
foreach (DetailPrototype proto in terrain.terrainData.detailPrototypes)
|
|
{
|
|
if (detail.m_renderMode == proto.renderMode)
|
|
{
|
|
if (PWCommon3.Utils.IsSameTexture(detail.m_detailTexture, proto.prototypeTexture, false))
|
|
{
|
|
return localTerrainIdx;
|
|
}
|
|
if (PWCommon3.Utils.IsSameGameObject(detail.m_detailProtoype, proto.prototype, false))
|
|
{
|
|
return localTerrainIdx;
|
|
}
|
|
}
|
|
localTerrainIdx++;
|
|
}
|
|
return errorIdx;
|
|
case GaiaConstants.SpawnerResourceType.TerrainTree:
|
|
ResourceProtoTree tree = m_treePrototypes[resourceIdx];
|
|
foreach (TreePrototype proto in terrain.terrainData.treePrototypes)
|
|
{
|
|
if (PWCommon3.Utils.IsSameGameObject(tree.m_desktopPrefab, proto.prefab, false))
|
|
{
|
|
return localTerrainIdx;
|
|
}
|
|
localTerrainIdx++;
|
|
}
|
|
return errorIdx;
|
|
case GaiaConstants.SpawnerResourceType.GameObject:
|
|
return resourceIdx;
|
|
case GaiaConstants.SpawnerResourceType.SpawnExtension:
|
|
return resourceIdx;
|
|
}
|
|
return errorIdx;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns all splatmap prototypes from this resource file in a list.
|
|
/// </summary>
|
|
/// <returns>List containing all splatmap prototypes from the resource file.</returns>
|
|
public List<GaiaSplatPrototype> GetSplatPrototypes()
|
|
{
|
|
//Alpha splats
|
|
GaiaSplatPrototype newSplat;
|
|
List<GaiaSplatPrototype> terrainSplats = new List<GaiaSplatPrototype>();
|
|
foreach (ResourceProtoTexture splat in m_texturePrototypes)
|
|
{
|
|
if (splat.m_texture != null)
|
|
{
|
|
newSplat = new GaiaSplatPrototype();
|
|
newSplat.normalMap = splat.m_normal;
|
|
newSplat.maskMap = splat.m_maskmap;
|
|
newSplat.tileOffset = new Vector2(splat.m_offsetX, splat.m_offsetY);
|
|
newSplat.tileSize = new Vector2(splat.m_sizeX, splat.m_sizeY);
|
|
newSplat.texture = splat.m_texture;
|
|
terrainSplats.Add(newSplat);
|
|
}
|
|
else
|
|
{
|
|
Debug.LogWarning("Unable to find resource for " + splat.m_name + "... ignoring.");
|
|
}
|
|
}
|
|
|
|
return terrainSplats;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check to see if a resource index is out of bounds
|
|
/// </summary>
|
|
/// <param name="resourceType">Resource type</param>
|
|
/// <param name="resourceIdx">Resource index</param>
|
|
/// <returns>True if out of bounds, false otherwise</returns>
|
|
public bool ResourceIdxOutOfBounds(GaiaConstants.SpawnerResourceType resourceType, int resourceIdx)
|
|
{
|
|
switch (resourceType)
|
|
{
|
|
case GaiaConstants.SpawnerResourceType.TerrainTexture:
|
|
if (resourceIdx < 0 || resourceIdx >= m_texturePrototypes.GetLength(0))
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
case GaiaConstants.SpawnerResourceType.TerrainDetail:
|
|
if (resourceIdx < 0 || resourceIdx >= m_detailPrototypes.GetLength(0))
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
case GaiaConstants.SpawnerResourceType.TerrainTree:
|
|
if (resourceIdx < 0 || resourceIdx >= m_treePrototypes.GetLength(0))
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
case GaiaConstants.SpawnerResourceType.GameObject:
|
|
if (resourceIdx < 0 || resourceIdx >= m_gameObjectPrototypes.GetLength(0))
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
case GaiaConstants.SpawnerResourceType.SpawnExtension:
|
|
if (resourceIdx < 0 || resourceIdx >= m_spawnExtensionPrototypes.GetLength(0))
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Returns all terrain detail prototypes from this resource file in a list.
|
|
/// </summary>
|
|
/// <returns>List containing all terrain detail prototypes from the resource file.</returns>
|
|
public List<DetailPrototype> GetDetailPrototypes()
|
|
{
|
|
List<DetailPrototype> terrainDetails = new List<DetailPrototype>();
|
|
DetailPrototype newDetail;
|
|
foreach (ResourceProtoDetail detail in m_detailPrototypes)
|
|
{
|
|
if (detail.m_detailProtoype != null || detail.m_detailTexture != null)
|
|
{
|
|
newDetail = new DetailPrototype();
|
|
newDetail.renderMode = detail.m_renderMode;
|
|
if (detail.m_detailProtoype != null)
|
|
{
|
|
newDetail.usePrototypeMesh = true;
|
|
newDetail.prototype = detail.m_detailProtoype;
|
|
}
|
|
else
|
|
{
|
|
newDetail.usePrototypeMesh = false;
|
|
newDetail.prototypeTexture = detail.m_detailTexture;
|
|
}
|
|
newDetail.dryColor = detail.m_dryColour;
|
|
newDetail.healthyColor = detail.m_healthyColour;
|
|
newDetail.maxHeight = detail.m_maxHeight;
|
|
newDetail.maxWidth = detail.m_maxWidth;
|
|
newDetail.minHeight = detail.m_minHeight;
|
|
newDetail.minWidth = detail.m_minWidth;
|
|
newDetail.noiseSpread = detail.m_noiseSpread;
|
|
newDetail.bendFactor = detail.m_bendFactor;
|
|
terrainDetails.Add(newDetail);
|
|
}
|
|
else
|
|
{
|
|
Debug.LogWarning("Unable to find resource for " + detail.m_name + "... ignoring.");
|
|
}
|
|
}
|
|
|
|
return terrainDetails;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check to see if the resource is actually available to unity
|
|
/// </summary>
|
|
/// <param name="resourceType">Resource type</param>
|
|
/// <param name="resourceIdx"Resource idx></param>
|
|
/// <returns>True if the resource could be found, false otherwise</returns>
|
|
public bool ResourceIsInUnity(GaiaConstants.SpawnerResourceType resourceType, int resourceIdx)
|
|
{
|
|
if (ResourceIdxOutOfBounds(resourceType, resourceIdx))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//Now see if the resource exists within that terrain
|
|
switch (resourceType)
|
|
{
|
|
case GaiaConstants.SpawnerResourceType.TerrainTexture:
|
|
ResourceProtoTexture splat = m_texturePrototypes[resourceIdx];
|
|
if (splat.m_texture == null)
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
case GaiaConstants.SpawnerResourceType.TerrainDetail:
|
|
ResourceProtoDetail detail = m_detailPrototypes[resourceIdx];
|
|
if (detail.m_detailTexture == null && detail.m_detailProtoype == null)
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
case GaiaConstants.SpawnerResourceType.TerrainTree:
|
|
ResourceProtoTree tree = m_treePrototypes[resourceIdx];
|
|
if (tree.m_desktopPrefab == null)
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
case GaiaConstants.SpawnerResourceType.GameObject:
|
|
ResourceProtoGameObject go = m_gameObjectPrototypes[resourceIdx];
|
|
if (go.m_instances[0] == null)
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
case GaiaConstants.SpawnerResourceType.SpawnExtension:
|
|
ResourceProtoSpawnExtension se = m_spawnExtensionPrototypes[resourceIdx];
|
|
if (se.m_instances[0] == null)
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Returns all tree prototypes from this resource file in a list.
|
|
/// </summary>
|
|
/// <returns>List containing all tree prototypes from the resource file.</returns>
|
|
public List<TreePrototype> GetTreePrototypes()
|
|
{
|
|
//Tree prototypes
|
|
TreePrototype newTree;
|
|
List<TreePrototype> terrainTrees = new List<TreePrototype>();
|
|
foreach (ResourceProtoTree tree in m_treePrototypes)
|
|
{
|
|
if (tree.m_desktopPrefab != null)
|
|
{
|
|
newTree = new TreePrototype();
|
|
newTree.bendFactor = tree.m_bendFactor;
|
|
newTree.prefab = tree.m_desktopPrefab;
|
|
terrainTrees.Add(newTree);
|
|
}
|
|
else
|
|
{
|
|
Debug.LogWarning("Unable to find resource for " + tree.m_name + "... ignoring.");
|
|
}
|
|
}
|
|
return terrainTrees;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Pick up the prototypes being used in the terrain
|
|
/// </summary>
|
|
public void UpdatePrototypesFromTerrain()
|
|
{
|
|
Terrain terrain = Gaia.TerrainHelper.GetActiveTerrain();
|
|
if (terrain == null)
|
|
{
|
|
Debug.LogWarning("Can not update prototypes from the terrain as there is no terrain currently active in this scene.");
|
|
return;
|
|
}
|
|
|
|
//Name storage to stop replicated names
|
|
Dictionary<string, string> names = new Dictionary<string, string>();
|
|
|
|
//Create some useful defaults
|
|
m_terrainHeight = terrain.terrainData.size.y;
|
|
|
|
|
|
int idx;
|
|
SpawnCritera criteria;
|
|
GaiaSplatPrototype terrainTextureProto;
|
|
ResourceProtoTexture resourceTextureProto;
|
|
List<ResourceProtoTexture> resourceTexturePrototypes = new List<ResourceProtoTexture>(m_texturePrototypes);
|
|
|
|
float seaLevel = GaiaSessionManager.GetSessionManager(false).GetSeaLevel();
|
|
|
|
var splatPrototypes = GaiaSplatPrototype.GetGaiaSplatPrototypes(terrain);
|
|
|
|
while (resourceTexturePrototypes.Count > splatPrototypes.Length)
|
|
{
|
|
resourceTexturePrototypes.RemoveAt(resourceTexturePrototypes.Count - 1);
|
|
}
|
|
for (idx = 0; idx < splatPrototypes.Length; idx++)
|
|
{
|
|
terrainTextureProto = splatPrototypes[idx];
|
|
if (idx < resourceTexturePrototypes.Count)
|
|
{
|
|
resourceTextureProto = resourceTexturePrototypes[idx];
|
|
}
|
|
else
|
|
{
|
|
resourceTextureProto = new ResourceProtoTexture();
|
|
resourceTexturePrototypes.Add(resourceTextureProto);
|
|
}
|
|
resourceTextureProto.m_name = GetUniqueName(terrainTextureProto.texture.name, ref names);
|
|
resourceTextureProto.m_texture = terrainTextureProto.texture;
|
|
resourceTextureProto.m_normal = terrainTextureProto.normalMap;
|
|
resourceTextureProto.m_maskmap = terrainTextureProto.maskMap;
|
|
resourceTextureProto.m_offsetX = terrainTextureProto.tileOffset.x;
|
|
resourceTextureProto.m_offsetY = terrainTextureProto.tileOffset.y;
|
|
resourceTextureProto.m_sizeX = terrainTextureProto.tileSize.x;
|
|
resourceTextureProto.m_sizeY = terrainTextureProto.tileSize.y;
|
|
resourceTextureProto.m_normalScale = terrainTextureProto.normalScale;
|
|
resourceTextureProto.m_metallic = terrainTextureProto.metallic;
|
|
resourceTextureProto.m_smoothness = terrainTextureProto.smoothness;
|
|
|
|
//Handle empty spawn criteria
|
|
if (resourceTextureProto.m_spawnCriteria.Length == 0)
|
|
{
|
|
resourceTextureProto.m_spawnCriteria = new SpawnCritera[1];
|
|
criteria = new SpawnCritera();
|
|
criteria.m_isActive = true;
|
|
criteria.m_virginTerrain = false;
|
|
criteria.m_checkType = Gaia.GaiaConstants.SpawnerLocationCheckType.PointCheck;
|
|
|
|
//Create some reasonable terrain based starting points
|
|
switch (idx)
|
|
{
|
|
case 0: //Base
|
|
{
|
|
criteria.m_checkHeight = true;
|
|
criteria.m_minHeight = seaLevel * -1f;
|
|
criteria.m_maxHeight = m_terrainHeight - seaLevel;
|
|
criteria.m_heightFitness = new AnimationCurve(new Keyframe(0f, 1f), new Keyframe(1f, 1f));
|
|
criteria.m_checkSlope = false;
|
|
criteria.m_minSlope = 0f;
|
|
criteria.m_maxSlope = 90f;
|
|
criteria.m_slopeFitness = new AnimationCurve(new Keyframe(0f, 1f), new Keyframe(1f, 0f));
|
|
criteria.m_checkProximity = false;
|
|
criteria.m_checkTexture = false;
|
|
break;
|
|
}
|
|
|
|
case 1: //Grass1
|
|
{
|
|
criteria.m_checkHeight = true;
|
|
criteria.m_minHeight = 1f;
|
|
criteria.m_maxHeight = m_terrainHeight - seaLevel;
|
|
criteria.m_heightFitness = new AnimationCurve(new Keyframe(0f, 0f), new Keyframe(0.01f, 1f), new Keyframe(1f, 1f));
|
|
criteria.m_checkSlope = false;
|
|
criteria.m_minSlope = 0f;
|
|
criteria.m_maxSlope = 90;
|
|
criteria.m_slopeFitness = new AnimationCurve(new Keyframe(0f, 1f), new Keyframe(1f, 0f));
|
|
criteria.m_checkProximity = false;
|
|
criteria.m_checkTexture = false;
|
|
break;
|
|
}
|
|
|
|
case 2: //Grass2
|
|
{
|
|
criteria.m_checkHeight = true;
|
|
criteria.m_minHeight = 2f;
|
|
criteria.m_maxHeight = m_terrainHeight - seaLevel;
|
|
criteria.m_heightFitness = new AnimationCurve(new Keyframe(0f, 0f), new Keyframe(0.02f, 1f), new Keyframe(1f, 1f));
|
|
criteria.m_checkSlope = true;
|
|
criteria.m_minSlope = 0f;
|
|
criteria.m_maxSlope = 90f;
|
|
criteria.m_slopeFitness = new AnimationCurve(new Keyframe(0f, 0f), new Keyframe(0.1f, 1f), new Keyframe(1f, 1f));
|
|
criteria.m_checkProximity = false;
|
|
criteria.m_checkTexture = false;
|
|
break;
|
|
}
|
|
|
|
case 3: //Cliffs
|
|
{
|
|
criteria.m_checkHeight = false;
|
|
criteria.m_minHeight = seaLevel * -1f;
|
|
criteria.m_maxHeight = m_terrainHeight - seaLevel;
|
|
criteria.m_heightFitness = new AnimationCurve(new Keyframe(0f, 1f), new Keyframe(1f, 1f));
|
|
criteria.m_checkSlope = true;
|
|
criteria.m_minSlope = 15f;
|
|
criteria.m_maxSlope = 90f;
|
|
criteria.m_slopeFitness = new AnimationCurve(new Keyframe(0f, 0f), new Keyframe(0.2f, 1f), new Keyframe(1f, 1f));
|
|
criteria.m_checkProximity = false;
|
|
criteria.m_checkTexture = false;
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
criteria.m_isActive = false;
|
|
criteria.m_checkHeight = false;
|
|
criteria.m_minHeight = UnityEngine.Random.Range(m_beachHeight - (m_beachHeight / 4f), m_beachHeight * 2f);
|
|
criteria.m_maxHeight = m_terrainHeight - seaLevel;
|
|
criteria.m_heightFitness = new AnimationCurve(new Keyframe(0f, 1f), new Keyframe(1f, 1f));
|
|
criteria.m_checkSlope = false;
|
|
criteria.m_minSlope = 0f;
|
|
criteria.m_maxSlope = 90f;
|
|
criteria.m_slopeFitness = new AnimationCurve(new Keyframe(0f, 1f), new Keyframe(1f, 0f));
|
|
criteria.m_checkProximity = false;
|
|
criteria.m_checkTexture = false;
|
|
break;
|
|
}
|
|
}
|
|
resourceTextureProto.m_spawnCriteria[0] = criteria;
|
|
}
|
|
}
|
|
m_texturePrototypes = resourceTexturePrototypes.ToArray();
|
|
|
|
|
|
//Detail prototypes
|
|
idx = 0;
|
|
names.Clear();
|
|
DetailPrototype terrainDetailProto;
|
|
ResourceProtoDetail resourceDetailProto;
|
|
List<ResourceProtoDetail> resourceDetailPrototypes = new List<ResourceProtoDetail>(m_detailPrototypes);
|
|
while (resourceDetailPrototypes.Count > terrain.terrainData.detailPrototypes.Length)
|
|
{
|
|
resourceDetailPrototypes.RemoveAt(resourceDetailPrototypes.Count - 1);
|
|
}
|
|
for (idx = 0; idx < terrain.terrainData.detailPrototypes.Length; idx++)
|
|
{
|
|
terrainDetailProto = terrain.terrainData.detailPrototypes[idx];
|
|
if (idx < resourceDetailPrototypes.Count)
|
|
{
|
|
resourceDetailProto = resourceDetailPrototypes[idx];
|
|
}
|
|
else
|
|
{
|
|
resourceDetailProto = new ResourceProtoDetail();
|
|
resourceDetailPrototypes.Add(resourceDetailProto);
|
|
}
|
|
|
|
resourceDetailProto.m_renderMode = terrainDetailProto.renderMode;
|
|
if (terrainDetailProto.prototype != null)
|
|
{
|
|
resourceDetailProto.m_name = GetUniqueName(terrainDetailProto.prototype.name, ref names);
|
|
resourceDetailProto.m_detailProtoype = terrainDetailProto.prototype;
|
|
}
|
|
else
|
|
{
|
|
resourceDetailProto.m_name = GetUniqueName(terrainDetailProto.prototypeTexture.name, ref names);
|
|
resourceDetailProto.m_detailTexture = terrainDetailProto.prototypeTexture;
|
|
}
|
|
|
|
resourceDetailProto.m_dryColour = terrainDetailProto.dryColor;
|
|
resourceDetailProto.m_healthyColour = terrainDetailProto.healthyColor;
|
|
resourceDetailProto.m_maxHeight = terrainDetailProto.maxHeight;
|
|
resourceDetailProto.m_maxWidth = terrainDetailProto.maxWidth;
|
|
resourceDetailProto.m_minHeight = terrainDetailProto.minHeight;
|
|
resourceDetailProto.m_minWidth = terrainDetailProto.minWidth;
|
|
resourceDetailProto.m_noiseSpread = terrainDetailProto.noiseSpread;
|
|
resourceDetailProto.m_bendFactor = terrainDetailProto.bendFactor;
|
|
|
|
//Handle missing dna
|
|
if (resourceDetailProto.m_dna == null)
|
|
{
|
|
resourceDetailProto.m_dna = new ResourceProtoDNA();
|
|
}
|
|
|
|
//Then reinitialise
|
|
//resourceDetailProto.m_dna.m_rndScaleInfluence = false;
|
|
resourceDetailProto.m_dna.Update(idx, resourceDetailProto.m_maxWidth, resourceDetailProto.m_maxHeight, 0.1f, 1f);
|
|
|
|
//Handle empty spawn criteria
|
|
if (resourceDetailProto.m_spawnCriteria.Length == 0)
|
|
{
|
|
resourceDetailProto.m_spawnCriteria = new SpawnCritera[1];
|
|
criteria = new SpawnCritera();
|
|
criteria.m_isActive = true;
|
|
criteria.m_virginTerrain = true;
|
|
criteria.m_checkType = Gaia.GaiaConstants.SpawnerLocationCheckType.PointCheck;
|
|
|
|
//Create some reasonable terrain based starting points
|
|
criteria.m_checkHeight = true;
|
|
criteria.m_minHeight = UnityEngine.Random.Range(m_beachHeight * 0.25f, m_beachHeight);
|
|
criteria.m_maxHeight = m_terrainHeight - seaLevel;
|
|
criteria.m_heightFitness = new AnimationCurve(new Keyframe(0f, 0f), new Keyframe(0.05f, 1f), new Keyframe(1f, 0f));
|
|
criteria.m_checkSlope = true;
|
|
criteria.m_minSlope = 0f;
|
|
criteria.m_maxSlope = UnityEngine.Random.Range(25f, 40f);
|
|
criteria.m_slopeFitness = new AnimationCurve(new Keyframe(0f, 0f), new Keyframe(0.05f, 1f), new Keyframe(1f, 0f));
|
|
criteria.m_checkProximity = false;
|
|
criteria.m_checkTexture = false;
|
|
resourceDetailProto.m_spawnCriteria[0] = criteria;
|
|
}
|
|
|
|
}
|
|
m_detailPrototypes = resourceDetailPrototypes.ToArray();
|
|
|
|
//Tree prototypes
|
|
idx = 0;
|
|
names.Clear();
|
|
TreePrototype terrainTreeProto;
|
|
ResourceProtoTree resourceTreeProto;
|
|
List<ResourceProtoTree> resourceTreePrototypes = new List<ResourceProtoTree>(m_treePrototypes);
|
|
while (resourceTreePrototypes.Count > terrain.terrainData.treePrototypes.Length)
|
|
{
|
|
resourceTreePrototypes.RemoveAt(resourceTreePrototypes.Count - 1);
|
|
}
|
|
for (idx = 0; idx < terrain.terrainData.treePrototypes.Length; idx++)
|
|
{
|
|
terrainTreeProto = terrain.terrainData.treePrototypes[idx];
|
|
if (idx < resourceTreePrototypes.Count)
|
|
{
|
|
resourceTreeProto = resourceTreePrototypes[idx];
|
|
}
|
|
else
|
|
{
|
|
resourceTreeProto = new ResourceProtoTree();
|
|
resourceTreePrototypes.Add(resourceTreeProto);
|
|
}
|
|
|
|
resourceTreeProto.m_name = GetUniqueName(terrainTreeProto.prefab.name, ref names);
|
|
//resourceTreeProto.m_desktopPrefab = resourceTreeProto.m_mobilePrefab = terrainTreeProto.prefab;
|
|
resourceTreeProto.m_bendFactor = terrainTreeProto.bendFactor;
|
|
|
|
//DNA
|
|
//if (resourceTreeProto.m_dna == null)
|
|
//{
|
|
// resourceTreeProto.m_dna = new ResourceProtoDNA();
|
|
// resourceTreeProto.m_dna.Update(idx);
|
|
//}
|
|
//UpdateDNA(terrainTreeProto.prefab, ref resourceTreeProto.m_dna);
|
|
//resourceTreeProto.m_dna.m_boundsRadius = resourceTreeProto.m_dna.m_width * 0.25f;
|
|
//resourceTreeProto.m_dna.m_seedThrow = resourceTreeProto.m_dna.m_height * 1.5f;
|
|
|
|
|
|
//Spawn criteria
|
|
if (resourceTreeProto.m_spawnCriteria.Length == 0)
|
|
{
|
|
resourceTreeProto.m_spawnCriteria = new SpawnCritera[1];
|
|
criteria = new SpawnCritera();
|
|
criteria.m_isActive = true;
|
|
criteria.m_virginTerrain = true;
|
|
criteria.m_checkType = GaiaConstants.SpawnerLocationCheckType.PointCheck;
|
|
|
|
//Create some reasonable terrain based starting points
|
|
criteria.m_checkHeight = true;
|
|
criteria.m_minHeight = 0f;
|
|
criteria.m_maxHeight = m_terrainHeight - seaLevel;
|
|
criteria.m_heightFitness = new AnimationCurve(new Keyframe(0f, 1f), new Keyframe(1f, 0f));
|
|
criteria.m_checkSlope = true;
|
|
criteria.m_minSlope = 0f;
|
|
criteria.m_maxSlope = UnityEngine.Random.Range(25f, 40f);
|
|
criteria.m_slopeFitness = new AnimationCurve(new Keyframe(0f, 1f), new Keyframe(1f, 0f));
|
|
criteria.m_checkProximity = false;
|
|
criteria.m_checkTexture = false;
|
|
resourceTreeProto.m_spawnCriteria[0] = criteria;
|
|
}
|
|
}
|
|
m_treePrototypes = resourceTreePrototypes.ToArray();
|
|
|
|
//Set up the asset associations
|
|
SetAssetAssociations();
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Get a unique name
|
|
/// </summary>
|
|
/// <param name="name">The original name</param>
|
|
/// <param name="names">The names dictionary</param>
|
|
/// <returns>The new unique name</returns>
|
|
string GetUniqueName(string name, ref Dictionary<string, string> names)
|
|
{
|
|
int idx = 0;
|
|
string newName = name;
|
|
while (names.ContainsKey(newName))
|
|
{
|
|
newName = name + " " + idx.ToString();
|
|
idx++;
|
|
}
|
|
names.Add(newName, newName);
|
|
return newName;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update the DNA based on the physical size of the prefab
|
|
/// </summary>
|
|
/// <param name="prefab"></param>
|
|
/// <param name="?"></param>
|
|
void UpdateDNA(GameObject prefab, ref ResourceProtoDNA dna)
|
|
{
|
|
if (prefab != null)
|
|
{
|
|
GameObject go = GameObject.Instantiate(prefab);
|
|
Bounds bounds = new Bounds(go.transform.position, Vector3.zero);
|
|
foreach (Renderer r in go.GetComponentsInChildren<Renderer>())
|
|
{
|
|
bounds.Encapsulate(r.bounds);
|
|
}
|
|
foreach (Collider c in go.GetComponentsInChildren<Collider>())
|
|
{
|
|
bounds.Encapsulate(c.bounds);
|
|
}
|
|
GameObject.DestroyImmediate(go);
|
|
|
|
//Update dna
|
|
dna.Update(dna.m_protoIdx, bounds.size.x, bounds.size.y);
|
|
}
|
|
}
|
|
|
|
public void ChangeHeight(float oldHeight, float newHeight)
|
|
{
|
|
SpawnCritera[] criteria;
|
|
SpawnCritera criterion;
|
|
float seaLevel = GaiaSessionManager.GetSessionManager(false).GetSeaLevel();
|
|
float oldMax = oldHeight - seaLevel;
|
|
float newMax = newHeight - seaLevel;
|
|
|
|
//Adjust textures
|
|
for (int pidx = 0; pidx < m_texturePrototypes.Length; pidx++)
|
|
{
|
|
criteria = m_texturePrototypes[pidx].m_spawnCriteria;
|
|
for (int cidx = 0; cidx < criteria.Length; cidx++)
|
|
{
|
|
criterion = criteria[cidx];
|
|
if (criterion.m_maxHeight == oldMax)
|
|
{
|
|
criterion.m_maxHeight = newMax;
|
|
}
|
|
}
|
|
}
|
|
|
|
//Adjust details
|
|
for (int pidx = 0; pidx < m_detailPrototypes.Length; pidx++)
|
|
{
|
|
criteria = m_detailPrototypes[pidx].m_spawnCriteria;
|
|
for (int cidx = 0; cidx < criteria.Length; cidx++)
|
|
{
|
|
criterion = criteria[cidx];
|
|
if (criterion.m_maxHeight == oldMax)
|
|
{
|
|
criterion.m_maxHeight = newMax;
|
|
}
|
|
}
|
|
}
|
|
|
|
//Adjust trees
|
|
for (int pidx = 0; pidx < m_treePrototypes.Length; pidx++)
|
|
{
|
|
criteria = m_treePrototypes[pidx].m_spawnCriteria;
|
|
for (int cidx = 0; cidx < criteria.Length; cidx++)
|
|
{
|
|
criterion = criteria[cidx];
|
|
if (criterion.m_maxHeight == oldMax)
|
|
{
|
|
criterion.m_maxHeight = newMax;
|
|
}
|
|
}
|
|
}
|
|
|
|
//Adjust gameobjects
|
|
for (int pidx = 0; pidx < m_gameObjectPrototypes.Length; pidx++)
|
|
{
|
|
criteria = m_gameObjectPrototypes[pidx].m_spawnCriteria;
|
|
for (int cidx = 0; cidx < criteria.Length; cidx++)
|
|
{
|
|
criterion = criteria[cidx];
|
|
if (criterion.m_maxHeight == oldMax)
|
|
{
|
|
criterion.m_maxHeight = newMax;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
//Adjust stamps
|
|
for (int pidx = 0; pidx < m_stampPrototypes.Length; pidx++)
|
|
{
|
|
criteria = m_stampPrototypes[pidx].m_spawnCriteria;
|
|
for (int cidx = 0; cidx < criteria.Length; cidx++)
|
|
{
|
|
criterion = criteria[cidx];
|
|
if (criterion.m_maxHeight == oldMax)
|
|
{
|
|
criterion.m_maxHeight = newMax;
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update the sea level to the sea level provided
|
|
/// </summary>
|
|
/// <param name="newSeaLevel">Value for the new sea level</param>
|
|
public void ChangeSeaLevel(float newSeaLevel)
|
|
{
|
|
float seaLevel = GaiaSessionManager.GetSessionManager(false).GetSeaLevel();
|
|
if (newSeaLevel != seaLevel)
|
|
{
|
|
ChangeSeaLevel(seaLevel, newSeaLevel);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update the sea level - and auto update any terrain criteria - only focus on extremities tho
|
|
/// </summary>
|
|
/// <param name="newSeaLevel">New sea level</param>
|
|
public void ChangeSeaLevel(float oldSeaLevel, float newSeaLevel)
|
|
{
|
|
SpawnCritera[] criteria;
|
|
SpawnCritera criterion;
|
|
float oldMin = oldSeaLevel * -1f;
|
|
float newMin = newSeaLevel * -1f;
|
|
float oldMax = m_terrainHeight - oldSeaLevel;
|
|
float newMax = m_terrainHeight - newSeaLevel;
|
|
|
|
//Adjust textures
|
|
for (int pidx = 0; pidx < m_texturePrototypes.Length; pidx++)
|
|
{
|
|
criteria = m_texturePrototypes[pidx].m_spawnCriteria;
|
|
for (int cidx = 0; cidx < criteria.Length; cidx++)
|
|
{
|
|
criterion = criteria[cidx];
|
|
if (criterion.m_minHeight == oldMin)
|
|
{
|
|
criterion.m_minHeight = newMin;
|
|
}
|
|
if (criterion.m_maxHeight == oldMax)
|
|
{
|
|
criterion.m_maxHeight = newMax;
|
|
}
|
|
}
|
|
}
|
|
|
|
//Adjust details
|
|
for (int pidx = 0; pidx < m_detailPrototypes.Length; pidx++)
|
|
{
|
|
criteria = m_detailPrototypes[pidx].m_spawnCriteria;
|
|
for (int cidx = 0; cidx < criteria.Length; cidx++)
|
|
{
|
|
criterion = criteria[cidx];
|
|
if (criterion.m_minHeight == oldMin)
|
|
{
|
|
criterion.m_minHeight = newMin;
|
|
}
|
|
if (criterion.m_maxHeight == oldMax)
|
|
{
|
|
criterion.m_maxHeight = newMax;
|
|
}
|
|
}
|
|
}
|
|
|
|
//Adjust trees
|
|
for (int pidx = 0; pidx < m_treePrototypes.Length; pidx++)
|
|
{
|
|
criteria = m_treePrototypes[pidx].m_spawnCriteria;
|
|
for (int cidx = 0; cidx < criteria.Length; cidx++)
|
|
{
|
|
criterion = criteria[cidx];
|
|
if (criterion.m_minHeight == oldMin)
|
|
{
|
|
criterion.m_minHeight = newMin;
|
|
}
|
|
if (criterion.m_maxHeight == oldMax)
|
|
{
|
|
criterion.m_maxHeight = newMax;
|
|
}
|
|
}
|
|
}
|
|
|
|
//Adjust gameobjects
|
|
for (int pidx = 0; pidx < m_gameObjectPrototypes.Length; pidx++)
|
|
{
|
|
criteria = m_gameObjectPrototypes[pidx].m_spawnCriteria;
|
|
for (int cidx = 0; cidx < criteria.Length; cidx++)
|
|
{
|
|
criterion = criteria[cidx];
|
|
if (criterion.m_minHeight == oldMin)
|
|
{
|
|
criterion.m_minHeight = newMin;
|
|
}
|
|
if (criterion.m_maxHeight == oldMax)
|
|
{
|
|
criterion.m_maxHeight = newMax;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
//Adjust stamps
|
|
for (int pidx = 0; pidx < m_stampPrototypes.Length; pidx++)
|
|
{
|
|
criteria = m_stampPrototypes[pidx].m_spawnCriteria;
|
|
for (int cidx = 0; cidx < criteria.Length; cidx++)
|
|
{
|
|
criterion = criteria[cidx];
|
|
if (criterion.m_minHeight == oldMin)
|
|
{
|
|
criterion.m_minHeight = newMin;
|
|
}
|
|
if (criterion.m_maxHeight == oldMax)
|
|
{
|
|
criterion.m_maxHeight = newMax;
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
|
|
//Update to new sea level
|
|
float seaLevel = GaiaSessionManager.GetSessionManager(false).GetSeaLevel();
|
|
seaLevel = newSeaLevel;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Set these assets into all terrains
|
|
/// </summary>
|
|
public void ApplyPrototypesToTerrain()
|
|
{
|
|
//Make sure we have located the resources
|
|
AssociateAssets();
|
|
|
|
//Now apply to terrain
|
|
foreach (Terrain t in Terrain.activeTerrains)
|
|
{
|
|
ApplyPrototypesToTerrain(t, GaiaSplatPrototype.CreateTerrainLayers(t.name, GetSplatPrototypes().ToArray()),GetDetailPrototypes(),GetTreePrototypes());
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set these assets into the terrain provided
|
|
/// </summary>
|
|
/// <param name="terrain"></param>
|
|
public void ApplyPrototypesToTerrain(Terrain terrain, TerrainLayer[] terrainLayers, List<DetailPrototype> terrainDetails, List<TreePrototype> terrainTrees)
|
|
{
|
|
// Do a terrain check
|
|
if (terrain == null)
|
|
{
|
|
Debug.LogWarning("Can not apply assets to terrain no terrain has been supplied.");
|
|
return;
|
|
}
|
|
if (terrainLayers != null)
|
|
terrain.terrainData.terrainLayers = terrainLayers;
|
|
if(terrainDetails!=null)
|
|
terrain.terrainData.detailPrototypes = terrainDetails.ToArray();
|
|
if(terrainTrees!=null)
|
|
terrain.terrainData.treePrototypes = terrainTrees.ToArray();
|
|
|
|
terrain.Flush();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add these assets into all terrains if they arent already there
|
|
/// </summary>
|
|
public void AddMissingPrototypesToTerrain()
|
|
{
|
|
AssociateAssets(); //Make sure everything has been connected up
|
|
foreach (Terrain t in Terrain.activeTerrains)
|
|
{
|
|
AddMissingPrototypesToTerrain(t);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add these assets into the terrain provided if they arent already there
|
|
/// </summary>
|
|
/// <param name="terrain"></param>
|
|
public void AddMissingPrototypesToTerrain(Terrain terrain)
|
|
{
|
|
// Do a terrain check
|
|
if (terrain == null)
|
|
{
|
|
Debug.LogWarning("Can not add resources to the terrain as no terrain has been supplied.");
|
|
return;
|
|
}
|
|
|
|
//Alpha splats
|
|
|
|
bool found = false;
|
|
GaiaSplatPrototype newSplat;
|
|
List<GaiaSplatPrototype> terrainSplats = new List<GaiaSplatPrototype>(GaiaSplatPrototype.GetGaiaSplatPrototypes(terrain));
|
|
foreach (ResourceProtoTexture splat in m_texturePrototypes)
|
|
{
|
|
//See if we can locate it already
|
|
found = false;
|
|
foreach (GaiaSplatPrototype sp in terrainSplats)
|
|
{
|
|
if (PWCommon3.Utils.IsSameTexture(sp.texture, splat.m_texture, false))
|
|
{
|
|
found = true;
|
|
}
|
|
}
|
|
//Add if necessary
|
|
if (!found)
|
|
{
|
|
newSplat = new GaiaSplatPrototype();
|
|
newSplat.normalMap = splat.m_normal;
|
|
newSplat.maskMap = splat.m_maskmap;
|
|
newSplat.tileOffset = new Vector2(splat.m_offsetX, splat.m_offsetY);
|
|
newSplat.tileSize = new Vector2(splat.m_sizeX, splat.m_sizeY);
|
|
newSplat.texture = splat.m_texture;
|
|
terrainSplats.Add(newSplat);
|
|
}
|
|
}
|
|
|
|
GaiaSplatPrototype.SetGaiaSplatPrototypes(terrain, terrainSplats.ToArray(), terrain.name);
|
|
|
|
//Detail prototypes
|
|
DetailPrototype newDetail;
|
|
List<DetailPrototype> terrainDetails = new List<DetailPrototype>(terrain.terrainData.detailPrototypes);
|
|
foreach (ResourceProtoDetail detail in m_detailPrototypes)
|
|
{
|
|
//See if we can locate it already
|
|
found = false;
|
|
foreach (DetailPrototype dp in terrainDetails)
|
|
{
|
|
if (dp.renderMode == detail.m_renderMode)
|
|
{
|
|
if (PWCommon3.Utils.IsSameTexture(dp.prototypeTexture, detail.m_detailTexture, false))
|
|
{
|
|
found = true;
|
|
}
|
|
if (PWCommon3.Utils.IsSameGameObject(dp.prototype, detail.m_detailProtoype, false))
|
|
{
|
|
found = true;
|
|
}
|
|
}
|
|
}
|
|
//Add if necessary
|
|
if (!found)
|
|
{
|
|
newDetail = new DetailPrototype();
|
|
newDetail.renderMode = detail.m_renderMode;
|
|
if (detail.m_detailProtoype != null)
|
|
{
|
|
newDetail.usePrototypeMesh = true;
|
|
newDetail.prototype = detail.m_detailProtoype;
|
|
}
|
|
else
|
|
{
|
|
newDetail.usePrototypeMesh = false;
|
|
newDetail.prototypeTexture = detail.m_detailTexture;
|
|
}
|
|
newDetail.dryColor = detail.m_dryColour;
|
|
newDetail.healthyColor = detail.m_healthyColour;
|
|
newDetail.maxHeight = detail.m_maxHeight;
|
|
newDetail.maxWidth = detail.m_maxWidth;
|
|
newDetail.minHeight = detail.m_minHeight;
|
|
newDetail.minWidth = detail.m_minWidth;
|
|
newDetail.noiseSpread = detail.m_noiseSpread;
|
|
newDetail.bendFactor = detail.m_bendFactor;
|
|
terrainDetails.Add(newDetail);
|
|
}
|
|
}
|
|
terrain.terrainData.detailPrototypes = terrainDetails.ToArray();
|
|
|
|
//Tree prototypes
|
|
TreePrototype newTree;
|
|
List<TreePrototype> terrainTrees = new List<TreePrototype>(terrain.terrainData.treePrototypes);
|
|
foreach (ResourceProtoTree tree in m_treePrototypes)
|
|
{
|
|
//See if we can locate it already
|
|
found = false;
|
|
foreach (TreePrototype tp in terrainTrees)
|
|
{
|
|
if (PWCommon3.Utils.IsSameGameObject(tp.prefab, tree.m_desktopPrefab, false))
|
|
{
|
|
found = true;
|
|
}
|
|
}
|
|
//Add if necessary
|
|
if (!found)
|
|
{
|
|
newTree = new TreePrototype();
|
|
newTree.bendFactor = tree.m_bendFactor;
|
|
newTree.prefab = tree.m_desktopPrefab;
|
|
terrainTrees.Add(newTree);
|
|
}
|
|
}
|
|
terrain.terrainData.treePrototypes = terrainTrees.ToArray();
|
|
|
|
terrain.Flush();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add the resource to the terrains if not already there
|
|
/// </summary>
|
|
/// <param name="resourceType">Resource type</param>
|
|
/// <param name="resourceIdx">Resource idx</param>
|
|
public void AddPrototypeToTerrain(GaiaConstants.SpawnerResourceType resourceType, int resourceIdx, Terrain[] terrains = null )
|
|
{
|
|
if (terrains == null)
|
|
{
|
|
terrains = Terrain.activeTerrains;
|
|
}
|
|
|
|
foreach (Terrain terrain in terrains)
|
|
{
|
|
AddPrototypeToTerrain(resourceType, resourceIdx, terrain);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add the resource to the specified terrain if its not already there
|
|
/// </summary>
|
|
/// <param name="resourceType">Resource type</param>
|
|
/// <param name="resourceIdx">Resource idx</param>
|
|
/// <param name="terrain">Terrain to add it to</param>
|
|
public void AddPrototypeToTerrain(GaiaConstants.SpawnerResourceType resourceType, int resourceIdx, Terrain terrain)
|
|
{
|
|
//Check index
|
|
if (ResourceIdxOutOfBounds(resourceType, resourceIdx))
|
|
{
|
|
return;
|
|
}
|
|
|
|
//Exit if its already there - assume if any terrain then in all terrains
|
|
if (!PrototypeMissingFromTerrain(resourceType, resourceIdx, terrain))
|
|
{
|
|
return;
|
|
}
|
|
|
|
//Now see if the resource exists within that terrain
|
|
switch (resourceType)
|
|
{
|
|
case GaiaConstants.SpawnerResourceType.TerrainTexture:
|
|
//We need to check first if a layer file was created for this texture resource already and if it is still available - if yes, add this one to the terrain instead
|
|
if (m_texturePrototypes[resourceIdx].m_LayerGUID != string.Empty)
|
|
{
|
|
#if UNITY_EDITOR
|
|
TerrainLayer existingLayer = null;
|
|
try
|
|
{
|
|
string assetPath = AssetDatabase.GUIDToAssetPath(m_texturePrototypes[resourceIdx].m_LayerGUID);
|
|
existingLayer = (TerrainLayer)AssetDatabase.LoadAssetAtPath(assetPath, typeof(TerrainLayer));
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
if (e.Message == string.Empty)
|
|
{ }
|
|
}
|
|
if (existingLayer != null)
|
|
{
|
|
//layer was found -> add it
|
|
terrain.terrainData.terrainLayers = GaiaUtils.AddElementToArray(terrain.terrainData.terrainLayers, existingLayer);
|
|
return;
|
|
}
|
|
#endif
|
|
}
|
|
//layer does not exist anymore / yet => create new one
|
|
|
|
ResourceProtoTexture splat = m_texturePrototypes[resourceIdx];
|
|
List<GaiaSplatPrototype> terrainSplats = new List<GaiaSplatPrototype>(GaiaSplatPrototype.GetGaiaSplatPrototypes(terrain));
|
|
TerrainLayer terrainLayer = new TerrainLayer();
|
|
terrainLayer.normalMapTexture = splat.m_normal;
|
|
terrainLayer.normalScale = splat.m_normalScale;
|
|
terrainLayer.metallic = splat.m_metallic;
|
|
terrainLayer.smoothness = splat.m_smoothness;
|
|
terrainLayer.maskMapTexture = splat.m_maskmap;
|
|
terrainLayer.diffuseRemapMin = splat.m_diffuseRemapMin;
|
|
terrainLayer.diffuseRemapMax = splat.m_diffuseRemapMax;
|
|
terrainLayer.maskMapRemapMin = splat.m_maskMapRemapMin;
|
|
terrainLayer.maskMapRemapMin = splat.m_maskMapRemapMin;
|
|
terrainLayer.specular = splat.m_specularColor;
|
|
terrainLayer.tileOffset = new Vector2(splat.m_offsetX, splat.m_offsetY);
|
|
terrainLayer.tileSize = new Vector2(splat.m_sizeX, splat.m_sizeY);
|
|
terrainLayer.diffuseTexture = splat.m_texture;
|
|
terrainLayer = GaiaSplatPrototype.SaveTerrainLayerAsAsset(string.Format("Gaia_-{0:yyyyMMdd-HHmmss}", DateTime.Now), terrain.terrainData.terrainLayers.Length.ToString(), terrainLayer);
|
|
terrain.terrainData.terrainLayers = GaiaUtils.AddElementToArray(terrain.terrainData.terrainLayers, terrainLayer);
|
|
//Store the layer GUID for further reference
|
|
#if UNITY_EDITOR
|
|
m_texturePrototypes[resourceIdx].m_LayerGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(terrainLayer));
|
|
#endif
|
|
break;
|
|
case GaiaConstants.SpawnerResourceType.TerrainDetail:
|
|
ResourceProtoDetail detail = m_detailPrototypes[resourceIdx];
|
|
List<DetailPrototype> terrainDetails = new List<DetailPrototype>(terrain.terrainData.detailPrototypes);
|
|
DetailPrototype newDetail = new DetailPrototype();
|
|
newDetail.renderMode = detail.m_renderMode;
|
|
if (detail.m_detailProtoype != null)
|
|
{
|
|
newDetail.usePrototypeMesh = true;
|
|
newDetail.prototype = detail.m_detailProtoype;
|
|
}
|
|
else
|
|
{
|
|
newDetail.usePrototypeMesh = false;
|
|
newDetail.prototypeTexture = detail.m_detailTexture;
|
|
}
|
|
newDetail.dryColor = detail.m_dryColour;
|
|
newDetail.healthyColor = detail.m_healthyColour;
|
|
newDetail.maxHeight = detail.m_maxHeight;
|
|
newDetail.maxWidth = detail.m_maxWidth;
|
|
newDetail.minHeight = detail.m_minHeight;
|
|
newDetail.minWidth = detail.m_minWidth;
|
|
newDetail.noiseSpread = detail.m_noiseSpread;
|
|
newDetail.bendFactor = detail.m_bendFactor;
|
|
terrainDetails.Add(newDetail);
|
|
terrain.terrainData.detailPrototypes = terrainDetails.ToArray();
|
|
break;
|
|
case GaiaConstants.SpawnerResourceType.TerrainTree:
|
|
ResourceProtoTree tree = m_treePrototypes[resourceIdx];
|
|
List<TreePrototype> terrainTrees = new List<TreePrototype>(terrain.terrainData.treePrototypes);
|
|
TreePrototype newTree = new TreePrototype();
|
|
newTree.bendFactor = tree.m_bendFactor;
|
|
newTree.prefab = tree.m_desktopPrefab;
|
|
terrainTrees.Add(newTree);
|
|
terrain.terrainData.treePrototypes = terrainTrees.ToArray();
|
|
break;
|
|
}
|
|
terrain.Flush();
|
|
}
|
|
|
|
|
|
/*
|
|
public void UpdateDNA()
|
|
{
|
|
//Bounds
|
|
Bounds bounds;
|
|
|
|
//Details
|
|
ResourceProtoDetail detailProto;
|
|
for (int detailIdx = 0; detailIdx < m_detailPrototypes.Length; detailIdx++)
|
|
{
|
|
detailProto = m_detailPrototypes[detailIdx];
|
|
if (detailProto.m_dna == null)
|
|
{
|
|
detailProto.m_dna = new ResourceProtoDNA();
|
|
detailProto.m_dna.Initialise();
|
|
}
|
|
detailProto.m_dna.m_width = detailProto.m_maxWidth;
|
|
detailProto.m_dna.m_height = detailProto.m_maxHeight;
|
|
detailProto.m_dna.m_boundsRadius = detailProto.m_dna.m_width;
|
|
}
|
|
|
|
ResourceProtoTree treeProto;
|
|
for (int treeIdx = 0; treeIdx < m_treePrototypes.Length; treeIdx++)
|
|
{
|
|
treeProto = m_treePrototypes[treeIdx];
|
|
if (treeProto.m_dna == null)
|
|
{
|
|
treeProto.m_dna = new ResourceProtoDNA();
|
|
treeProto.m_dna.Initialise();
|
|
}
|
|
if (treeProto.m_desktopPrefab != null)
|
|
{
|
|
GameObject go = Instantiate(treeProto.m_desktopPrefab);
|
|
bounds = new Bounds(go.transform.position, Vector3.zero);
|
|
foreach (Renderer r in go.GetComponentsInChildren<Renderer>())
|
|
{
|
|
bounds.Encapsulate(r.bounds);
|
|
}
|
|
foreach (Collider c in go.GetComponentsInChildren<Collider>())
|
|
{
|
|
bounds.Encapsulate(c.bounds);
|
|
}
|
|
treeProto.m_dna.m_width = bounds.size.x;
|
|
treeProto.m_dna.m_height = bounds.size.y;
|
|
treeProto.m_dna.m_boundsRadius = treeProto.m_dna.m_width;
|
|
DestroyImmediate(go);
|
|
}
|
|
}
|
|
|
|
ResourceProtoGameObject gameProto;
|
|
for (int goIdx = 0; goIdx < m_gameObjectPrototypes.Length; goIdx++)
|
|
{
|
|
gameProto = m_gameObjectPrototypes[goIdx];
|
|
if (gameProto.m_dna == null)
|
|
{
|
|
gameProto.m_dna = new ResourceProtoDNA();
|
|
gameProto.m_dna.Initialise();
|
|
}
|
|
if (gameProto.m_instances.Length > 0 && gameProto.m_instances[0].m_desktopPrefab != null)
|
|
{
|
|
GameObject go = Instantiate(gameProto.m_instances[0].m_desktopPrefab);
|
|
bounds = new Bounds(go.transform.position, Vector3.zero);
|
|
foreach (Renderer r in go.GetComponentsInChildren<Renderer>())
|
|
{
|
|
bounds.Encapsulate(r.bounds);
|
|
}
|
|
foreach (Collider c in go.GetComponentsInChildren<Collider>())
|
|
{
|
|
bounds.Encapsulate(c.bounds);
|
|
}
|
|
gameProto.m_dna.m_width = bounds.size.x;
|
|
gameProto.m_dna.m_height = bounds.size.y;
|
|
gameProto.m_dna.m_boundsRadius = gameProto.m_dna.m_width;
|
|
DestroyImmediate(go);
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
|
|
#region Cache Helpers
|
|
|
|
/// <summary>
|
|
/// Return true if any of these resources do texture based lookups
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public bool ChecksTextures()
|
|
{
|
|
int idx;
|
|
for (idx = 0; idx < m_texturePrototypes.Length; idx++)
|
|
{
|
|
if (m_texturePrototypes[idx].ChecksTextures())
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
for (idx = 0; idx < m_detailPrototypes.Length; idx++)
|
|
{
|
|
if (m_detailPrototypes[idx].ChecksTextures())
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
for (idx = 0; idx < m_treePrototypes.Length; idx++)
|
|
{
|
|
if (m_treePrototypes[idx].ChecksTextures())
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
for (idx = 0; idx < m_gameObjectPrototypes.Length; idx++)
|
|
{
|
|
if (m_gameObjectPrototypes[idx].ChecksTextures())
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
/*
|
|
for (idx = 0; idx < m_stampPrototypes.Length; idx++)
|
|
{
|
|
if (m_stampPrototypes[idx].ChecksTextures())
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
*/
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Return true if any of these resources do proximity based lookups
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public bool ChecksProximity()
|
|
{
|
|
int idx;
|
|
for (idx = 0; idx < m_texturePrototypes.Length; idx++)
|
|
{
|
|
if (m_texturePrototypes[idx].ChecksProximity())
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
for (idx = 0; idx < m_detailPrototypes.Length; idx++)
|
|
{
|
|
if (m_detailPrototypes[idx].ChecksProximity())
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
for (idx = 0; idx < m_treePrototypes.Length; idx++)
|
|
{
|
|
if (m_treePrototypes[idx].ChecksProximity())
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
for (idx = 0; idx < m_gameObjectPrototypes.Length; idx++)
|
|
{
|
|
if (m_gameObjectPrototypes[idx].ChecksProximity())
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
/*
|
|
for (idx = 0; idx < m_stampPrototypes.Length; idx++)
|
|
{
|
|
if (m_stampPrototypes[idx].ChecksProximity())
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
*/
|
|
return false;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Add Resources
|
|
|
|
/// <summary>
|
|
/// Add a new game object resource, and make some assumptions based on current terrain settings
|
|
/// </summary>
|
|
/// <param name="prefab"></param>
|
|
public void AddGameObject(GameObject prefab)
|
|
{
|
|
if (prefab == null)
|
|
{
|
|
Debug.LogWarning("Can't add null game object");
|
|
}
|
|
|
|
#if UNITY_2018_3_OR_NEWER && UNITY_EDITOR
|
|
if (PrefabUtility.GetPrefabAssetType(prefab) != PrefabAssetType.NotAPrefab)
|
|
{
|
|
float seaLevel = GaiaSessionManager.GetSessionManager(false).GetSeaLevel();
|
|
//Create names array
|
|
Dictionary<string, string> names = new Dictionary<string, string>();
|
|
|
|
//Create space for larger array
|
|
ResourceProtoGameObject[] pgos = new ResourceProtoGameObject[m_gameObjectPrototypes.Length + 1];
|
|
|
|
//Copy existing items across
|
|
for (int idx = 0; idx < m_gameObjectPrototypes.Length; idx++)
|
|
{
|
|
pgos[idx] = m_gameObjectPrototypes[idx];
|
|
names.Add(pgos[idx].m_name, pgos[idx].m_name);
|
|
}
|
|
|
|
//Create the new game object prototype
|
|
ResourceProtoGameObject pgo = new ResourceProtoGameObject();
|
|
pgo.m_name = GetUniqueName(prefab.name, ref names);
|
|
|
|
//Create and store prefab in instances
|
|
ResourceProtoGameObjectInstance pgi = new ResourceProtoGameObjectInstance();
|
|
pgi.m_rotateToSlope = true;
|
|
pgi.m_desktopPrefab = prefab;
|
|
pgi.m_name = prefab.name;
|
|
pgo.m_instances = new ResourceProtoGameObjectInstance[1];
|
|
pgo.m_instances[0] = pgi;
|
|
|
|
//Update dna
|
|
pgo.m_dna.Update(m_gameObjectPrototypes.Length);
|
|
UpdateDNA(prefab, ref pgo.m_dna);
|
|
//pgo.m_dna.m_minScale = 1f;
|
|
//pgo.m_dna.m_maxScale = 1f;
|
|
|
|
|
|
//Create spawn criteria
|
|
pgo.m_spawnCriteria = new SpawnCritera[1];
|
|
SpawnCritera criteria = new SpawnCritera();
|
|
criteria.m_isActive = true;
|
|
criteria.m_virginTerrain = true;
|
|
criteria.m_checkType = GaiaConstants.SpawnerLocationCheckType.BoundedAreaCheck;
|
|
//Create some reasonable terrain based starting points
|
|
criteria.m_checkHeight = true;
|
|
criteria.m_minHeight = 0f;
|
|
criteria.m_maxHeight = m_terrainHeight - seaLevel;
|
|
criteria.m_heightFitness = new AnimationCurve(new Keyframe(0f, 1f), new Keyframe(1f, 0f));
|
|
criteria.m_checkSlope = true;
|
|
criteria.m_minSlope = 0f;
|
|
criteria.m_maxSlope = UnityEngine.Random.Range(5f, 15f);
|
|
criteria.m_slopeFitness = new AnimationCurve(new Keyframe(0f, 1f), new Keyframe(1f, 0f));
|
|
criteria.m_checkProximity = false;
|
|
criteria.m_checkTexture = false;
|
|
pgo.m_spawnCriteria[0] = criteria;
|
|
|
|
pgos[pgos.Length - 1] = pgo;
|
|
m_gameObjectPrototypes = pgos;
|
|
}
|
|
#endif
|
|
#if !UNITY_2018_3_OR_NEWER && UNITY_EDITOR
|
|
if (PrefabUtility.GetPrefabType(prefab) != PrefabType.None)
|
|
{
|
|
//Create names array
|
|
Dictionary<string, string> names = new Dictionary<string, string>();
|
|
|
|
//Create space for larger array
|
|
ResourceProtoGameObject[] pgos = new ResourceProtoGameObject[m_gameObjectPrototypes.Length + 1];
|
|
|
|
//Copy existing items across
|
|
for (int idx = 0; idx < m_gameObjectPrototypes.Length; idx++)
|
|
{
|
|
pgos[idx] = m_gameObjectPrototypes[idx];
|
|
names.Add(pgos[idx].m_name, pgos[idx].m_name);
|
|
}
|
|
|
|
//Create the new game object prototype
|
|
ResourceProtoGameObject pgo = new ResourceProtoGameObject();
|
|
pgo.m_name = GetUniqueName(prefab.name, ref names);
|
|
|
|
//Create and store prefab in instances
|
|
ResourceProtoGameObjectInstance pgi = new ResourceProtoGameObjectInstance();
|
|
pgi.m_rotateToSlope = true;
|
|
pgi.m_desktopPrefab = prefab;
|
|
pgi.m_name = prefab.name;
|
|
pgo.m_instances = new ResourceProtoGameObjectInstance[1];
|
|
pgo.m_instances[0] = pgi;
|
|
|
|
//Update dna
|
|
pgo.m_dna.Update(m_gameObjectPrototypes.Length);
|
|
UpdateDNA(prefab, ref pgo.m_dna);
|
|
pgo.m_dna.m_minScale = 1f;
|
|
pgo.m_dna.m_maxScale = 1f;
|
|
|
|
|
|
//Create spawn criteria
|
|
pgo.m_spawnCriteria = new SpawnCritera[1];
|
|
SpawnCritera criteria = new SpawnCritera();
|
|
criteria.m_isActive = true;
|
|
criteria.m_virginTerrain = true;
|
|
criteria.m_checkType = GaiaConstants.SpawnerLocationCheckType.BoundedAreaCheck;
|
|
//Create some reasonable terrain based starting points
|
|
criteria.m_checkHeight = true;
|
|
criteria.m_minHeight = 0f;
|
|
criteria.m_maxHeight = m_terrainHeight - m_seaLevel;
|
|
criteria.m_heightFitness = new AnimationCurve(new Keyframe(0f, 1f), new Keyframe(1f, 0f));
|
|
criteria.m_checkSlope = true;
|
|
criteria.m_minSlope = 0f;
|
|
criteria.m_maxSlope = UnityEngine.Random.Range(5f, 15f);
|
|
criteria.m_slopeFitness = new AnimationCurve(new Keyframe(0f, 1f), new Keyframe(1f, 0f));
|
|
criteria.m_checkProximity = false;
|
|
criteria.m_checkTexture = false;
|
|
pgo.m_spawnCriteria[0] = criteria;
|
|
|
|
pgos[pgos.Length - 1] = pgo;
|
|
m_gameObjectPrototypes = pgos;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Add the game object from a list of prefabs instantiated as game objects
|
|
/// </summary>
|
|
/// <param name="prototypes"></param>
|
|
public void AddGameObject(List<GameObject> prototypes)
|
|
{
|
|
if (prototypes == null || prototypes.Count < 1)
|
|
{
|
|
Debug.LogWarning("Can't add null or empty prototypes list");
|
|
return;
|
|
}
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
//Create names array
|
|
Dictionary<string, string> names = new Dictionary<string, string>();
|
|
|
|
//Create space for larger array
|
|
ResourceProtoGameObject[] pgos = new ResourceProtoGameObject[m_gameObjectPrototypes.Length + 1];
|
|
|
|
//Copy existing items across
|
|
for (int idx = 0; idx < m_gameObjectPrototypes.Length; idx++)
|
|
{
|
|
pgos[idx] = m_gameObjectPrototypes[idx];
|
|
names.Add(pgos[idx].m_name, pgos[idx].m_name);
|
|
}
|
|
|
|
//Create the new game object prototype
|
|
ResourceProtoGameObject pgo = new ResourceProtoGameObject();
|
|
|
|
//Now process all of the prototypes
|
|
Bounds localBounds;
|
|
Bounds globalBounds = new Bounds();
|
|
GameObject prefab = null;
|
|
GameObject rootGO = null;
|
|
ResourceProtoGameObjectInstance pgi = null;
|
|
List<ResourceProtoGameObjectInstance> instances = new List<ResourceProtoGameObjectInstance>();
|
|
|
|
//First calculate the global bounds - everything will be done relative to this
|
|
foreach (GameObject currentInstance in prototypes)
|
|
{
|
|
//Calculate the bounds
|
|
localBounds = Gaia.GaiaUtils.GetBounds(currentInstance);
|
|
|
|
//If first time then set things up
|
|
if (rootGO == null)
|
|
{
|
|
rootGO = currentInstance;
|
|
globalBounds = new Bounds(localBounds.center, localBounds.size);
|
|
}
|
|
else
|
|
{
|
|
globalBounds.Encapsulate(localBounds);
|
|
}
|
|
}
|
|
|
|
//Then process each prototype
|
|
rootGO = null;
|
|
foreach (GameObject currentInstance in prototypes)
|
|
{
|
|
//Get the prefab
|
|
#if UNITY_2018_3_OR_NEWER
|
|
prefab = PrefabUtility.GetCorrespondingObjectFromOriginalSource(currentInstance) as GameObject;
|
|
#elif UNITY_2018_2_OR_NEWER
|
|
prefab = PrefabUtility.GetCorrespondingObjectFromSource(currentInstance) as GameObject;
|
|
#else
|
|
prefab = PrefabUtility.GetPrefabParent(currentInstance) as GameObject;
|
|
#endif
|
|
|
|
//Calculate the bounds
|
|
localBounds = Gaia.GaiaUtils.GetBounds(currentInstance);
|
|
|
|
//If first time then set things up
|
|
if (rootGO == null)
|
|
{
|
|
rootGO = currentInstance;
|
|
pgo.m_name = GetUniqueName(prefab.name, ref names);
|
|
}
|
|
|
|
pgi = new ResourceProtoGameObjectInstance();
|
|
pgi.m_name = prefab.name;
|
|
pgi.m_desktopPrefab = prefab;
|
|
//pgi.m_mobilePrefab = prefab;
|
|
|
|
pgi.m_minInstances = 1;
|
|
pgi.m_maxInstances = 1;
|
|
|
|
pgi.m_minSpawnOffsetX = pgi.m_maxSpawnOffsetX = currentInstance.transform.position.x - globalBounds.center.x;
|
|
//pgi.m_minSpawnOffsetY = pgi.m_maxSpawnOffsetY = localBounds.size.y * -0.05f;
|
|
pgi.m_minSpawnOffsetY = pgi.m_maxSpawnOffsetY = currentInstance.transform.position.y; // Assume zero is ground
|
|
pgi.m_minSpawnOffsetZ = pgi.m_maxSpawnOffsetZ = currentInstance.transform.position.z - globalBounds.center.z;
|
|
pgi.m_minRotationOffsetX = pgi.m_maxRotationOffsetX = currentInstance.transform.localEulerAngles.x;
|
|
pgi.m_minRotationOffsetY = pgi.m_maxRotationOffsetY = currentInstance.transform.localEulerAngles.y;
|
|
pgi.m_minRotationOffsetZ = pgi.m_maxRotationOffsetZ = currentInstance.transform.localEulerAngles.z;
|
|
pgi.m_minScale = pgi.m_maxScale = Mathf.Max(currentInstance.transform.localScale.x, currentInstance.transform.localScale.z);
|
|
pgi.m_minXYZScale = currentInstance.transform.localScale;
|
|
pgi.m_maxXYZScale = currentInstance.transform.localScale;
|
|
if (pgi.m_maxScale > 0f)
|
|
{
|
|
pgi.m_localBounds = Mathf.Max(localBounds.size.x, localBounds.size.z) / pgi.m_maxScale;
|
|
}
|
|
else
|
|
{
|
|
pgi.m_localBounds = Mathf.Max(localBounds.size.x, localBounds.size.z);
|
|
}
|
|
pgi.m_rotateToSlope = true;
|
|
pgi.m_virginTerrain = false;
|
|
|
|
instances.Add(pgi);
|
|
}
|
|
|
|
float seaLevel = GaiaSessionManager.GetSessionManager(false).GetSeaLevel();
|
|
|
|
//Update dna
|
|
pgo.m_dna.Update(m_gameObjectPrototypes.Length, Mathf.Max(globalBounds.size.x, globalBounds.size.z), globalBounds.size.y);
|
|
//pgo.m_dna.m_minScale = 1f;
|
|
//pgo.m_dna.m_maxScale = 1f;
|
|
|
|
//Create spawn criteria
|
|
pgo.m_spawnCriteria = new SpawnCritera[1];
|
|
SpawnCritera criteria = new SpawnCritera();
|
|
criteria.m_isActive = true;
|
|
criteria.m_virginTerrain = true;
|
|
criteria.m_checkType = GaiaConstants.SpawnerLocationCheckType.BoundedAreaCheck;
|
|
|
|
//Create some reasonable terrain based starting points
|
|
criteria.m_checkHeight = true;
|
|
criteria.m_minHeight = 0f;
|
|
criteria.m_maxHeight = m_terrainHeight - seaLevel;
|
|
criteria.m_heightFitness = new AnimationCurve(new Keyframe(0f, 1f), new Keyframe(1f, 0f));
|
|
criteria.m_checkSlope = true;
|
|
criteria.m_minSlope = 0f;
|
|
criteria.m_maxSlope = UnityEngine.Random.Range(5f, 10f);
|
|
criteria.m_slopeFitness = new AnimationCurve(new Keyframe(0f, 1f), new Keyframe(1f, 0f));
|
|
criteria.m_checkProximity = false;
|
|
criteria.m_checkTexture = false;
|
|
pgo.m_spawnCriteria[0] = criteria;
|
|
|
|
pgo.m_instances = instances.ToArray();
|
|
pgos[pgos.Length - 1] = pgo;
|
|
m_gameObjectPrototypes = pgos;
|
|
|
|
|
|
/*
|
|
if (PrefabUtility.GetPrefabType(prefab) != PrefabType.None)
|
|
{
|
|
//Create names array
|
|
Dictionary<string, string> names = new Dictionary<string, string>();
|
|
|
|
//Create space for larger array
|
|
ResourceProtoGameObject[] pgos = new ResourceProtoGameObject[m_gameObjectPrototypes.Length + 1];
|
|
|
|
//Copy existing items across
|
|
for (int idx = 0; idx < m_gameObjectPrototypes.Length; idx++)
|
|
{
|
|
pgos[idx] = m_gameObjectPrototypes[idx];
|
|
names.Add(pgos[idx].m_name, pgos[idx].m_name);
|
|
}
|
|
|
|
//Create the new game object prototype
|
|
ResourceProtoGameObject pgo = new ResourceProtoGameObject();
|
|
pgo.m_name = GetUniqueName(prefab.name, ref names);
|
|
|
|
//Create and store prefab in instances
|
|
ResourceProtoGameObjectInstance pgi = new ResourceProtoGameObjectInstance();
|
|
pgi.m_conformToSlope = true;
|
|
pgi.m_desktopPrefab = prefab;
|
|
pgi.m_name = prefab.name;
|
|
pgo.m_instances = new ResourceProtoGameObjectInstance[1];
|
|
pgo.m_instances[0] = pgi;
|
|
|
|
//Update dna
|
|
pgo.m_dna.Update(m_gameObjectPrototypes.Length);
|
|
UpdateDNA(prefab, ref pgo.m_dna);
|
|
|
|
//Create spawn criteria
|
|
pgo.m_spawnCriteria = new SpawnCritera[1];
|
|
SpawnCritera criteria = new SpawnCritera();
|
|
criteria.m_isActive = true;
|
|
criteria.m_virginTerrain = true;
|
|
criteria.m_checkType = GaiaConstants.SpawnerLocationCheckType.BoundedAreaCheck;
|
|
//Create some reasonable terrain based starting points
|
|
criteria.m_checkHeight = true;
|
|
criteria.m_minHeight = UnityEngine.Random.Range(m_beachHeight - (m_beachHeight / 4f), m_beachHeight * 2f);
|
|
criteria.m_maxHeight = m_terrainHeight - m_seaLevel;
|
|
criteria.m_heightFitness = new AnimationCurve(new Keyframe(0f, 1f), new Keyframe(1f, 0f));
|
|
criteria.m_checkSlope = true;
|
|
criteria.m_minSlope = UnityEngine.Random.Range(0f, 1.5f);
|
|
criteria.m_maxSlope = UnityEngine.Random.Range(1.6f, 5f);
|
|
criteria.m_slopeFitness = new AnimationCurve(new Keyframe(0f, 1f), new Keyframe(1f, 0f));
|
|
criteria.m_checkProximity = false;
|
|
criteria.m_checkTexture = false;
|
|
pgo.m_spawnCriteria[0] = criteria;
|
|
|
|
pgos[pgos.Length - 1] = pgo;
|
|
m_gameObjectPrototypes = pgos;
|
|
}
|
|
*/
|
|
#endif
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
#region Create Spawners
|
|
|
|
public GameObject CreateCoverageTextureSpawner(float range, float increment)
|
|
{
|
|
CreateOrFindSessionManager();
|
|
GameObject gaiaObj = GaiaUtils.GetGaiaGameObject();
|
|
|
|
GameObject spawnerObj = new GameObject("Coverage Texture Spawner");
|
|
spawnerObj.AddComponent<Spawner>();
|
|
Spawner spawner = spawnerObj.GetComponent<Spawner>();
|
|
spawner.m_settings.m_resources = this;
|
|
spawnerObj.transform.parent = gaiaObj.transform;
|
|
spawnerObj.transform.position = Gaia.TerrainHelper.GetActiveTerrainCenter();
|
|
|
|
//Do basic setup
|
|
spawner.m_settings.m_resources = this;
|
|
spawner.m_mode = GaiaConstants.OperationMode.DesignTime;
|
|
spawner.m_spawnerShape = GaiaConstants.SpawnerShape.Box;
|
|
spawner.m_rndGenerator = new Gaia.XorshiftPlus(spawner.m_seed);
|
|
spawner.m_settings.m_spawnRange = range;
|
|
spawner.m_spawnFitnessAttenuator = new AnimationCurve(new Keyframe(0f, 1f), new Keyframe(1f, 1f));
|
|
spawner.m_spawnRuleSelector = GaiaConstants.SpawnerRuleSelector.All;
|
|
spawner.m_spawnLocationAlgorithm = GaiaConstants.SpawnerLocation.EveryLocation;
|
|
spawner.m_spawnCollisionLayers = Gaia.TerrainHelper.GetActiveTerrainLayer();
|
|
spawner.m_locationIncrement = Mathf.Clamp(increment, 0.2f, 64f);
|
|
|
|
//Iterate thru all the textures and add them. Assume the first one is the base.
|
|
SpawnRule rule;
|
|
for (int resIdx = 0; resIdx < m_texturePrototypes.Length; resIdx++ )
|
|
{
|
|
rule = new SpawnRule();
|
|
rule.m_name = m_texturePrototypes[resIdx].m_name;
|
|
rule.m_resourceType = GaiaConstants.SpawnerResourceType.TerrainTexture;
|
|
rule.m_resourceIdx = resIdx;
|
|
rule.m_minRequiredFitness = 0f;
|
|
rule.m_failureRate = 0f;
|
|
rule.m_maxInstances = (ulong)((range * 2f) * (range * 2f));
|
|
rule.m_isActive = true;
|
|
rule.m_isFoldedOut = false;
|
|
rule.m_ignoreMaxInstances = true;
|
|
rule.m_useExtendedSpawn = false;
|
|
//spawner.m_activeRuleCnt++;
|
|
spawner.m_settings.m_spawnerRules.Add(rule);
|
|
|
|
//Break the 3rd texture up with some perlin
|
|
if (resIdx == 2)
|
|
{
|
|
rule.m_noiseMask = GaiaConstants.NoiseType.Perlin;
|
|
rule.m_noiseMaskFrequency = 1f;
|
|
rule.m_noiseMaskLacunarity = 1.5f;
|
|
rule.m_noiseMaskOctaves = 8;
|
|
rule.m_noiseMaskPersistence = 0.25f;
|
|
rule.m_noiseMaskSeed = (float)UnityEngine.Random.Range(0, 5000);
|
|
rule.m_noiseStrength = 1f;
|
|
rule.m_noiseZoom = 150f;
|
|
}
|
|
}
|
|
|
|
//And it to the group spawner
|
|
SpawnerGroup.SpawnerInstance si;
|
|
si = new SpawnerGroup.SpawnerInstance();
|
|
si.m_name = spawnerObj.name;
|
|
si.m_interationsPerSpawn = 1;
|
|
si.m_spawner = spawner;
|
|
//sg.m_spawners.Add(si);
|
|
|
|
return spawnerObj;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Create a detail spawner with the specified range
|
|
/// </summary>
|
|
/// <param name="range"></param>
|
|
/// <returns></returns>
|
|
public GameObject CreateCoverageDetailSpawner(float range, float increment)
|
|
{
|
|
CreateOrFindSessionManager();
|
|
GameObject gaiaObj = GaiaUtils.GetGaiaGameObject();
|
|
//SpawnerGroup sg = CreateOrFindGroupSpawner();
|
|
|
|
GameObject spawnerObj = new GameObject("Coverage Detail Spawner");
|
|
spawnerObj.AddComponent<Spawner>();
|
|
Spawner spawner = spawnerObj.GetComponent<Spawner>();
|
|
spawner.m_settings.m_resources = this;
|
|
spawnerObj.transform.parent = gaiaObj.transform;
|
|
spawnerObj.transform.position = Gaia.TerrainHelper.GetActiveTerrainCenter();
|
|
|
|
//Do basic setup
|
|
spawner.m_settings.m_resources = this;
|
|
spawner.m_mode = GaiaConstants.OperationMode.DesignTime;
|
|
spawner.m_spawnerShape = GaiaConstants.SpawnerShape.Box;
|
|
spawner.m_rndGenerator = new Gaia.XorshiftPlus(spawner.m_seed);
|
|
spawner.m_settings.m_spawnRange = range;
|
|
spawner.m_spawnFitnessAttenuator = new AnimationCurve(new Keyframe(0f, 1f), new Keyframe(1f, 1f));
|
|
spawner.m_spawnRuleSelector = GaiaConstants.SpawnerRuleSelector.All;
|
|
spawner.m_spawnLocationAlgorithm = GaiaConstants.SpawnerLocation.EveryLocationJittered;
|
|
spawner.m_spawnCollisionLayers = Gaia.TerrainHelper.GetActiveTerrainLayer();
|
|
spawner.m_locationIncrement = increment;
|
|
|
|
//Iterate thru all the details and add them.
|
|
SpawnRule rule;
|
|
for (int resIdx = 0; resIdx < m_detailPrototypes.Length; resIdx++)
|
|
{
|
|
rule = new SpawnRule();
|
|
rule.m_name = m_detailPrototypes[resIdx].m_name;
|
|
rule.m_resourceType = GaiaConstants.SpawnerResourceType.TerrainDetail;
|
|
rule.m_resourceIdx = resIdx;
|
|
rule.m_minRequiredFitness = UnityEngine.Random.Range(0.2f, 0.5f);
|
|
rule.m_failureRate = UnityEngine.Random.Range(0.7f, 0.95f);
|
|
rule.m_maxInstances = (ulong)((range * 2f) * (range * 2f));
|
|
rule.m_ignoreMaxInstances = true;
|
|
rule.m_isActive = true;
|
|
rule.m_isFoldedOut = false;
|
|
rule.m_useExtendedSpawn = false;
|
|
|
|
//Create some nice defaults for the new grasses
|
|
switch (resIdx)
|
|
{
|
|
case 0:
|
|
{
|
|
rule.m_minRequiredFitness = 0.1f;
|
|
rule.m_failureRate = 0f;
|
|
rule.m_noiseMask = GaiaConstants.NoiseType.Perlin;
|
|
rule.m_noiseMaskFrequency = 1f;
|
|
rule.m_noiseMaskLacunarity = 2f;
|
|
rule.m_noiseMaskOctaves = 8;
|
|
rule.m_noiseMaskPersistence = 0.25f;
|
|
rule.m_noiseMaskSeed = 0f;
|
|
rule.m_noiseStrength = 1.5f;
|
|
rule.m_noiseZoom = 50f;
|
|
rule.m_noiseInvert = true;
|
|
}
|
|
break;
|
|
case 1:
|
|
{
|
|
rule.m_minRequiredFitness = 0.1f;
|
|
rule.m_failureRate = 0.8f;
|
|
rule.m_noiseMask = GaiaConstants.NoiseType.Perlin;
|
|
rule.m_noiseMaskFrequency = 1f;
|
|
rule.m_noiseMaskLacunarity = 2f;
|
|
rule.m_noiseMaskOctaves = 8;
|
|
rule.m_noiseMaskPersistence = 0.25f;
|
|
rule.m_noiseMaskSeed = 0f;
|
|
rule.m_noiseStrength = 1.5f;
|
|
rule.m_noiseZoom = 50f;
|
|
rule.m_noiseInvert = true;
|
|
}
|
|
break;
|
|
case 2:
|
|
{
|
|
rule.m_minRequiredFitness = 0.4f;
|
|
rule.m_failureRate = 0f;
|
|
rule.m_noiseMask = GaiaConstants.NoiseType.Perlin;
|
|
rule.m_noiseMaskFrequency = 1f;
|
|
rule.m_noiseMaskLacunarity = 2f;
|
|
rule.m_noiseMaskOctaves = 8;
|
|
rule.m_noiseMaskPersistence = 0.25f;
|
|
rule.m_noiseMaskSeed = 0f;
|
|
rule.m_noiseStrength = 1.5f;
|
|
rule.m_noiseZoom = 50f;
|
|
rule.m_noiseInvert = false;
|
|
}
|
|
break;
|
|
case 3:
|
|
{
|
|
rule.m_minRequiredFitness = 0.2f;
|
|
rule.m_failureRate = 0f;
|
|
rule.m_noiseMask = GaiaConstants.NoiseType.Perlin;
|
|
rule.m_noiseMaskFrequency = 1f;
|
|
rule.m_noiseMaskLacunarity = 2f;
|
|
rule.m_noiseMaskOctaves = 8;
|
|
rule.m_noiseMaskPersistence = 0.25f;
|
|
rule.m_noiseMaskSeed = 0f;
|
|
rule.m_noiseStrength = 1.5f;
|
|
rule.m_noiseZoom = 30f;
|
|
rule.m_noiseInvert = true;
|
|
}
|
|
break;
|
|
case 4:
|
|
{
|
|
rule.m_minRequiredFitness = 0.5f;
|
|
rule.m_failureRate = 0.65f;
|
|
rule.m_noiseMask = GaiaConstants.NoiseType.Perlin;
|
|
rule.m_noiseMaskFrequency = 1f;
|
|
rule.m_noiseMaskLacunarity = 2f;
|
|
rule.m_noiseMaskOctaves = 8;
|
|
rule.m_noiseMaskPersistence = 0.25f;
|
|
rule.m_noiseMaskSeed = 13390f;
|
|
rule.m_noiseStrength = 1.5f;
|
|
rule.m_noiseZoom = 50f;
|
|
rule.m_noiseInvert = true;
|
|
}
|
|
break;
|
|
case 5:
|
|
{
|
|
rule.m_minRequiredFitness = 0.4f;
|
|
rule.m_failureRate = 0.3f;
|
|
rule.m_noiseMask = GaiaConstants.NoiseType.Perlin;
|
|
rule.m_noiseMaskFrequency = 1f;
|
|
rule.m_noiseMaskLacunarity = 2f;
|
|
rule.m_noiseMaskOctaves = 8;
|
|
rule.m_noiseMaskPersistence = 0.25f;
|
|
rule.m_noiseMaskSeed = 13390f;
|
|
rule.m_noiseStrength = 1.5f;
|
|
rule.m_noiseZoom = 30f;
|
|
rule.m_noiseInvert = false;
|
|
}
|
|
break;
|
|
case 6:
|
|
{
|
|
rule.m_minRequiredFitness = 0.5f;
|
|
rule.m_failureRate = 0.9f;
|
|
rule.m_noiseMask = GaiaConstants.NoiseType.Perlin;
|
|
rule.m_noiseMaskFrequency = 1f;
|
|
rule.m_noiseMaskLacunarity = 1.5f;
|
|
rule.m_noiseMaskOctaves = 8;
|
|
rule.m_noiseMaskPersistence = 0.25f;
|
|
rule.m_noiseMaskSeed = 6886f;
|
|
rule.m_noiseStrength = 1f;
|
|
rule.m_noiseZoom = 90f;
|
|
rule.m_noiseInvert = false;
|
|
}
|
|
break;
|
|
default:
|
|
{
|
|
rule.m_isActive = false;
|
|
}
|
|
break;
|
|
}
|
|
|
|
//spawner.m_activeRuleCnt++;
|
|
spawner.m_settings.m_spawnerRules.Add(rule);
|
|
}
|
|
|
|
//And it to the group spawner
|
|
SpawnerGroup.SpawnerInstance si;
|
|
si = new SpawnerGroup.SpawnerInstance();
|
|
si.m_name = spawnerObj.name;
|
|
si.m_interationsPerSpawn = 1;
|
|
si.m_spawner = spawner;
|
|
//sg.m_spawners.Add(si);
|
|
|
|
return spawnerObj;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Create / show the session manager
|
|
/// </summary>
|
|
public GameObject CreateOrFindSessionManager()
|
|
{
|
|
Debug.Log("Spawned Session");
|
|
GaiaSessionManager sessMgr = GaiaSessionManager.GetSessionManager();
|
|
ChangeSeaLevel(sessMgr.m_session.m_seaLevel);
|
|
return sessMgr.gameObject;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Find or create the Spawner Group in the scene
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
/*
|
|
public SpawnerGroup CreateOrFindGroupSpawner()
|
|
{
|
|
CreateOrFindSessionManager();
|
|
GameObject gaiaObj = CreateOrFindGaia();
|
|
|
|
//Find or create the spawner group
|
|
GameObject sgObj = GameObject.Find("Group Spawner");
|
|
if (sgObj == null)
|
|
{
|
|
sgObj = new GameObject("Group Spawner");
|
|
sgObj.AddComponent<SpawnerGroup>();
|
|
sgObj.transform.parent = gaiaObj.transform;
|
|
}
|
|
return sgObj.GetComponent<SpawnerGroup>();
|
|
}
|
|
*/
|
|
|
|
/// <summary>
|
|
/// Create a clustered detail spawner with the specified range
|
|
/// </summary>
|
|
/// <param name="range"></param>
|
|
/// <returns></returns>
|
|
public GameObject CreateClusteredDetailSpawner(float range, float increment)
|
|
{
|
|
CreateOrFindSessionManager();
|
|
GameObject gaiaObj = GaiaUtils.GetGaiaGameObject();
|
|
//SpawnerGroup sg = CreateOrFindGroupSpawner();
|
|
|
|
GameObject spawnerObj = new GameObject("Clustered Detail Spawner");
|
|
spawnerObj.AddComponent<Spawner>();
|
|
Spawner spawner = spawnerObj.GetComponent<Spawner>();
|
|
spawner.m_settings.m_resources = this;
|
|
spawnerObj.transform.parent = gaiaObj.transform;
|
|
spawnerObj.transform.position = Gaia.TerrainHelper.GetActiveTerrainCenter();
|
|
|
|
//Do basic setup
|
|
spawner.m_settings.m_resources = this;
|
|
spawner.m_mode = GaiaConstants.OperationMode.DesignTime;
|
|
spawner.m_spawnerShape = GaiaConstants.SpawnerShape.Box;
|
|
spawner.m_rndGenerator = new Gaia.XorshiftPlus(spawner.m_seed);
|
|
spawner.m_settings.m_spawnRange = range;
|
|
spawner.m_spawnFitnessAttenuator = new AnimationCurve(new Keyframe(0f, 1f), new Keyframe(1f, 1f));
|
|
spawner.m_spawnRuleSelector = GaiaConstants.SpawnerRuleSelector.Random;
|
|
spawner.m_spawnLocationAlgorithm = GaiaConstants.SpawnerLocation.RandomLocationClustered;
|
|
spawner.m_locationChecksPerInt = UnityEngine.Random.Range((int)range * 7, (int)range * 10);
|
|
spawner.m_maxRandomClusterSize = UnityEngine.Random.Range(10, 100);
|
|
spawner.m_spawnCollisionLayers = Gaia.TerrainHelper.GetActiveTerrainLayer();
|
|
|
|
spawner.m_locationIncrement = increment * 1.5f;
|
|
|
|
//Iterate thru all the details and add them.
|
|
SpawnRule rule;
|
|
for (int resIdx = 0; resIdx < m_detailPrototypes.Length; resIdx++)
|
|
{
|
|
rule = new SpawnRule();
|
|
rule.m_name = m_detailPrototypes[resIdx].m_name;
|
|
rule.m_resourceType = GaiaConstants.SpawnerResourceType.TerrainDetail;
|
|
rule.m_resourceIdx = resIdx;
|
|
rule.m_minRequiredFitness = UnityEngine.Random.Range(0.3f, 0.6f);
|
|
rule.m_failureRate = UnityEngine.Random.Range(0.1f, 0.3f); ;
|
|
rule.m_maxInstances = (ulong)((range * 2f) * (range * 2f));
|
|
rule.m_ignoreMaxInstances = true;
|
|
rule.m_isActive = false;
|
|
rule.m_isFoldedOut = false;
|
|
rule.m_useExtendedSpawn = false;
|
|
//spawner.m_activeRuleCnt++;
|
|
spawner.m_settings.m_spawnerRules.Add(rule);
|
|
|
|
if (resIdx > 2)
|
|
{
|
|
rule.m_isActive = true;
|
|
}
|
|
}
|
|
|
|
//And it to the group spawner
|
|
SpawnerGroup.SpawnerInstance si;
|
|
si = new SpawnerGroup.SpawnerInstance();
|
|
si.m_name = spawnerObj.name;
|
|
si.m_interationsPerSpawn = 1;
|
|
si.m_spawner = spawner;
|
|
//sg.m_spawners.Add(si);
|
|
|
|
//And return it
|
|
return spawnerObj;
|
|
}
|
|
|
|
public GameObject CreateClusteredTreeSpawner(float range)
|
|
{
|
|
CreateOrFindSessionManager();
|
|
GameObject gaiaObj = GaiaUtils.GetGaiaGameObject();
|
|
|
|
GameObject spawnerObj = new GameObject("Clustered Tree Spawner");
|
|
spawnerObj.AddComponent<Spawner>();
|
|
Spawner spawner = spawnerObj.GetComponent<Spawner>();
|
|
spawner.m_settings.m_resources = this;
|
|
spawnerObj.transform.parent = gaiaObj.transform;
|
|
spawnerObj.transform.position = Gaia.TerrainHelper.GetActiveTerrainCenter();
|
|
|
|
//Do basic setup
|
|
spawner.m_settings.m_resources = this;
|
|
spawner.m_mode = GaiaConstants.OperationMode.DesignTime;
|
|
spawner.m_spawnerShape = GaiaConstants.SpawnerShape.Box;
|
|
spawner.m_rndGenerator = new Gaia.XorshiftPlus(spawner.m_seed);
|
|
spawner.m_settings.m_spawnRange = range;
|
|
spawner.m_spawnFitnessAttenuator = new AnimationCurve(new Keyframe(0f, 1f), new Keyframe(1f, 1f));
|
|
spawner.m_spawnRuleSelector = GaiaConstants.SpawnerRuleSelector.Random;
|
|
spawner.m_spawnLocationAlgorithm = GaiaConstants.SpawnerLocation.RandomLocationClustered;
|
|
spawner.m_spawnCollisionLayers = Gaia.TerrainHelper.GetActiveTerrainLayer();
|
|
spawner.m_locationChecksPerInt = (int)range * 5;
|
|
spawner.m_maxRandomClusterSize = 30;
|
|
|
|
//Iterate thru all the trees and add them.
|
|
SpawnRule rule;
|
|
for (int resIdx = 0; resIdx < m_treePrototypes.Length; resIdx++)
|
|
{
|
|
rule = new SpawnRule();
|
|
rule.m_name = m_treePrototypes[resIdx].m_name;
|
|
rule.m_resourceType = GaiaConstants.SpawnerResourceType.TerrainTree;
|
|
rule.m_resourceIdx = resIdx;
|
|
rule.m_minRequiredFitness = 0.25f;
|
|
rule.m_failureRate = 0f;
|
|
rule.m_maxInstances = (ulong)((range * range) / 5f);
|
|
rule.m_isActive = true;
|
|
rule.m_isFoldedOut = false;
|
|
rule.m_useExtendedSpawn = false;
|
|
//spawner.m_activeRuleCnt++;
|
|
spawner.m_settings.m_spawnerRules.Add(rule);
|
|
|
|
//Create some nice defaults for the default trees
|
|
switch (resIdx)
|
|
{
|
|
case 0: //Broadleaf desktop
|
|
{
|
|
rule.m_minRequiredFitness = 0.2f;
|
|
rule.m_failureRate = 0f;
|
|
rule.m_noiseMask = GaiaConstants.NoiseType.Perlin;
|
|
rule.m_noiseMaskFrequency = 1f;
|
|
rule.m_noiseMaskLacunarity = 2f;
|
|
rule.m_noiseMaskOctaves = 8;
|
|
rule.m_noiseMaskPersistence = 0.25f;
|
|
rule.m_noiseMaskSeed = 0f;
|
|
rule.m_noiseStrength = 1.5f;
|
|
rule.m_noiseZoom = 50f;
|
|
rule.m_noiseInvert = false;
|
|
}
|
|
break;
|
|
case 1: //Conifer desktop
|
|
{
|
|
rule.m_minRequiredFitness = 0.2f;
|
|
rule.m_failureRate = 0f;
|
|
rule.m_noiseMask = GaiaConstants.NoiseType.Perlin;
|
|
rule.m_noiseMaskFrequency = 1f;
|
|
rule.m_noiseMaskLacunarity = 2f;
|
|
rule.m_noiseMaskOctaves = 8;
|
|
rule.m_noiseMaskPersistence = 0.25f;
|
|
rule.m_noiseMaskSeed = 0f;
|
|
rule.m_noiseStrength = 1.5f;
|
|
rule.m_noiseZoom = 50f;
|
|
rule.m_noiseInvert = true;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
//And it to the group spawner
|
|
SpawnerGroup.SpawnerInstance si;
|
|
si = new SpawnerGroup.SpawnerInstance();
|
|
si.m_name = spawnerObj.name;
|
|
si.m_interationsPerSpawn = 1;
|
|
si.m_spawner = spawner;
|
|
//sg.m_spawners.Add(si);
|
|
|
|
return spawnerObj;
|
|
}
|
|
|
|
public GameObject CreateCoverageTreeSpawner(float range)
|
|
{
|
|
CreateOrFindSessionManager();
|
|
GameObject gaiaObj = GaiaUtils.GetGaiaGameObject();
|
|
//SpawnerGroup sg = CreateOrFindGroupSpawner();
|
|
|
|
GameObject spawnerObj = new GameObject("Coverage Tree Spawner");
|
|
spawnerObj.AddComponent<Spawner>();
|
|
Spawner spawner = spawnerObj.GetComponent<Spawner>();
|
|
spawner.m_settings.m_resources = this;
|
|
spawnerObj.transform.parent = gaiaObj.transform;
|
|
spawnerObj.transform.position = Gaia.TerrainHelper.GetActiveTerrainCenter();
|
|
|
|
//Do basic setup
|
|
spawner.m_settings.m_resources = this;
|
|
spawner.m_mode = GaiaConstants.OperationMode.DesignTime;
|
|
spawner.m_spawnerShape = GaiaConstants.SpawnerShape.Box;
|
|
spawner.m_rndGenerator = new Gaia.XorshiftPlus(spawner.m_seed);
|
|
spawner.m_settings.m_spawnRange = range;
|
|
spawner.m_spawnFitnessAttenuator = new AnimationCurve(new Keyframe(0f, 1f), new Keyframe(1f, 1f));
|
|
spawner.m_spawnRuleSelector = GaiaConstants.SpawnerRuleSelector.Random;
|
|
spawner.m_spawnLocationAlgorithm = GaiaConstants.SpawnerLocation.EveryLocationJittered;
|
|
spawner.m_locationIncrement = 45f;
|
|
spawner.m_maxJitteredLocationOffsetPct = 0.85f;
|
|
spawner.m_spawnCollisionLayers = Gaia.TerrainHelper.GetActiveTerrainLayer();
|
|
spawner.m_locationChecksPerInt = (int)range * 5;
|
|
|
|
//Iterate thru all the trees and add them.
|
|
SpawnRule rule;
|
|
for (int resIdx = 0; resIdx < m_treePrototypes.Length; resIdx++)
|
|
{
|
|
rule = new SpawnRule();
|
|
rule.m_name = m_treePrototypes[resIdx].m_name;
|
|
rule.m_resourceType = GaiaConstants.SpawnerResourceType.TerrainTree;
|
|
rule.m_resourceIdx = resIdx;
|
|
rule.m_minRequiredFitness = 0.25f;
|
|
rule.m_failureRate = 0f;
|
|
rule.m_maxInstances = (ulong)((range * range) / 5f);
|
|
rule.m_isActive = true;
|
|
rule.m_isFoldedOut = false;
|
|
rule.m_useExtendedSpawn = false;
|
|
//spawner.m_activeRuleCnt++;
|
|
spawner.m_settings.m_spawnerRules.Add(rule);
|
|
|
|
//Create some nice defaults for the default trees
|
|
switch (resIdx)
|
|
{
|
|
case 0: //Broadleaf desktop
|
|
{
|
|
rule.m_minRequiredFitness = 0.2f;
|
|
rule.m_failureRate = 0f;
|
|
rule.m_noiseMask = GaiaConstants.NoiseType.Perlin;
|
|
rule.m_noiseMaskFrequency = 1f;
|
|
rule.m_noiseMaskLacunarity = 2f;
|
|
rule.m_noiseMaskOctaves = 8;
|
|
rule.m_noiseMaskPersistence = 0.25f;
|
|
rule.m_noiseMaskSeed = 0f;
|
|
rule.m_noiseStrength = 1.5f;
|
|
rule.m_noiseZoom = 50f;
|
|
rule.m_noiseInvert = false;
|
|
}
|
|
break;
|
|
case 1: //Conifer desktop
|
|
{
|
|
rule.m_minRequiredFitness = 0.2f;
|
|
rule.m_failureRate = 0f;
|
|
rule.m_noiseMask = GaiaConstants.NoiseType.Perlin;
|
|
rule.m_noiseMaskFrequency = 1f;
|
|
rule.m_noiseMaskLacunarity = 2f;
|
|
rule.m_noiseMaskOctaves = 8;
|
|
rule.m_noiseMaskPersistence = 0.25f;
|
|
rule.m_noiseMaskSeed = 0f;
|
|
rule.m_noiseStrength = 1.5f;
|
|
rule.m_noiseZoom = 50f;
|
|
rule.m_noiseInvert = true;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
//And it to the group spawner
|
|
SpawnerGroup.SpawnerInstance si;
|
|
si = new SpawnerGroup.SpawnerInstance();
|
|
si.m_name = spawnerObj.name;
|
|
si.m_interationsPerSpawn = 1;
|
|
si.m_spawner = spawner;
|
|
//sg.m_spawners.Add(si);
|
|
|
|
return spawnerObj;
|
|
}
|
|
|
|
public GameObject CreateCoverageGameObjectSpawner(float range)
|
|
{
|
|
CreateOrFindSessionManager();
|
|
GameObject gaiaObj = GaiaUtils.GetGaiaGameObject();
|
|
//SpawnerGroup sg = CreateOrFindGroupSpawner();
|
|
|
|
GameObject spawnerObj = new GameObject("Coverage GameObject Spawner");
|
|
spawnerObj.AddComponent<Spawner>();
|
|
Spawner spawner = spawnerObj.GetComponent<Spawner>();
|
|
spawner.m_settings.m_resources = this;
|
|
spawnerObj.transform.parent = gaiaObj.transform;
|
|
spawnerObj.transform.position = Gaia.TerrainHelper.GetActiveTerrainCenter();
|
|
|
|
//Do basic setup
|
|
spawner.m_settings.m_resources = this;
|
|
spawner.m_mode = GaiaConstants.OperationMode.DesignTime;
|
|
spawner.m_spawnerShape = GaiaConstants.SpawnerShape.Box;
|
|
spawner.m_rndGenerator = new Gaia.XorshiftPlus(spawner.m_seed);
|
|
spawner.m_settings.m_spawnRange = range;
|
|
spawner.m_spawnFitnessAttenuator = new AnimationCurve(new Keyframe(0f, 1f), new Keyframe(1f, 1f));
|
|
spawner.m_spawnRuleSelector = GaiaConstants.SpawnerRuleSelector.Random;
|
|
spawner.m_spawnLocationAlgorithm = GaiaConstants.SpawnerLocation.EveryLocationJittered;
|
|
spawner.m_locationIncrement = 45f;
|
|
spawner.m_maxJitteredLocationOffsetPct = 0.85f;
|
|
spawner.m_spawnCollisionLayers = Gaia.TerrainHelper.GetActiveTerrainLayer();
|
|
spawner.m_locationChecksPerInt = (int)range * 5;
|
|
|
|
//Iterate thru all the trees and add them.
|
|
SpawnRule rule;
|
|
for (int resIdx = 0; resIdx < m_gameObjectPrototypes.Length; resIdx++)
|
|
{
|
|
rule = new SpawnRule();
|
|
rule.m_name = m_gameObjectPrototypes[resIdx].m_name;
|
|
rule.m_resourceType = GaiaConstants.SpawnerResourceType.GameObject;
|
|
rule.m_resourceIdx = resIdx;
|
|
rule.m_minRequiredFitness = 0f;
|
|
rule.m_failureRate = 0f;
|
|
rule.m_maxInstances = (ulong)((range * range) / 5f);
|
|
rule.m_isActive = !m_gameObjectPrototypes[resIdx].m_canSpawnAsTree;
|
|
rule.m_isFoldedOut = false;
|
|
rule.m_useExtendedSpawn = false;
|
|
//spawner.m_activeRuleCnt++;
|
|
spawner.m_settings.m_spawnerRules.Add(rule);
|
|
}
|
|
|
|
//And it to the group spawner
|
|
SpawnerGroup.SpawnerInstance si;
|
|
si = new SpawnerGroup.SpawnerInstance();
|
|
si.m_name = spawnerObj.name;
|
|
si.m_interationsPerSpawn = 1;
|
|
si.m_spawner = spawner;
|
|
//sg.m_spawners.Add(si);
|
|
|
|
//And return it
|
|
return spawnerObj;
|
|
}
|
|
|
|
public GameObject CreateCoverageGameObjectSpawnerForTrees(float range)
|
|
{
|
|
CreateOrFindSessionManager();
|
|
GameObject gaiaObj = GaiaUtils.GetGaiaGameObject();
|
|
//SpawnerGroup sg = CreateOrFindGroupSpawner();
|
|
|
|
GameObject spawnerObj = new GameObject("Coverage GO Tree Spawner");
|
|
spawnerObj.AddComponent<Spawner>();
|
|
Spawner spawner = spawnerObj.GetComponent<Spawner>();
|
|
spawner.m_settings.m_resources = this;
|
|
spawnerObj.transform.parent = gaiaObj.transform;
|
|
spawnerObj.transform.position = Gaia.TerrainHelper.GetActiveTerrainCenter();
|
|
|
|
//Do basic setup
|
|
spawner.m_settings.m_resources = this;
|
|
spawner.m_mode = GaiaConstants.OperationMode.DesignTime;
|
|
spawner.m_spawnerShape = GaiaConstants.SpawnerShape.Box;
|
|
spawner.m_rndGenerator = new Gaia.XorshiftPlus(spawner.m_seed);
|
|
spawner.m_settings.m_spawnRange = range;
|
|
spawner.m_spawnFitnessAttenuator = new AnimationCurve(new Keyframe(0f, 1f), new Keyframe(1f, 1f));
|
|
spawner.m_spawnRuleSelector = GaiaConstants.SpawnerRuleSelector.Random;
|
|
spawner.m_spawnLocationAlgorithm = GaiaConstants.SpawnerLocation.EveryLocationJittered;
|
|
spawner.m_locationIncrement = 45f;
|
|
spawner.m_maxJitteredLocationOffsetPct = 0.85f;
|
|
spawner.m_spawnCollisionLayers = Gaia.TerrainHelper.GetActiveTerrainLayer();
|
|
spawner.m_locationChecksPerInt = (int)range * 5;
|
|
|
|
//Iterate thru all the trees and add them.
|
|
SpawnRule rule;
|
|
for (int resIdx = 0; resIdx < m_gameObjectPrototypes.Length; resIdx++)
|
|
{
|
|
if (m_gameObjectPrototypes[resIdx].m_canSpawnAsTree)
|
|
{
|
|
rule = new SpawnRule();
|
|
rule.m_name = m_gameObjectPrototypes[resIdx].m_name;
|
|
rule.m_resourceType = GaiaConstants.SpawnerResourceType.GameObject;
|
|
rule.m_resourceIdx = resIdx;
|
|
rule.m_minRequiredFitness = 0.25f;
|
|
rule.m_failureRate = 0f;
|
|
rule.m_maxInstances = (ulong)((range * range) / 5f);
|
|
rule.m_isActive = true;
|
|
rule.m_isFoldedOut = false;
|
|
rule.m_useExtendedSpawn = false;
|
|
//spawner.m_activeRuleCnt++;
|
|
spawner.m_settings.m_spawnerRules.Add(rule);
|
|
|
|
//Create some nice defaults for the default trees
|
|
switch (resIdx)
|
|
{
|
|
case 0: //Broadleaf desktop
|
|
{
|
|
rule.m_minRequiredFitness = 0.2f;
|
|
rule.m_failureRate = 0f;
|
|
rule.m_noiseMask = GaiaConstants.NoiseType.Perlin;
|
|
rule.m_noiseMaskFrequency = 1f;
|
|
rule.m_noiseMaskLacunarity = 2f;
|
|
rule.m_noiseMaskOctaves = 8;
|
|
rule.m_noiseMaskPersistence = 0.25f;
|
|
rule.m_noiseMaskSeed = 0f;
|
|
rule.m_noiseStrength = 1.5f;
|
|
rule.m_noiseZoom = 50f;
|
|
rule.m_noiseInvert = false;
|
|
}
|
|
break;
|
|
case 1: //Conifer desktop
|
|
{
|
|
rule.m_minRequiredFitness = 0.2f;
|
|
rule.m_failureRate = 0f;
|
|
rule.m_noiseMask = GaiaConstants.NoiseType.Perlin;
|
|
rule.m_noiseMaskFrequency = 1f;
|
|
rule.m_noiseMaskLacunarity = 2f;
|
|
rule.m_noiseMaskOctaves = 8;
|
|
rule.m_noiseMaskPersistence = 0.25f;
|
|
rule.m_noiseMaskSeed = 0f;
|
|
rule.m_noiseStrength = 1.5f;
|
|
rule.m_noiseZoom = 50f;
|
|
rule.m_noiseInvert = true;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//And it to the group spawner
|
|
SpawnerGroup.SpawnerInstance si;
|
|
si = new SpawnerGroup.SpawnerInstance();
|
|
si.m_name = spawnerObj.name;
|
|
si.m_interationsPerSpawn = 1;
|
|
si.m_spawner = spawner;
|
|
|
|
//And return it
|
|
return spawnerObj;
|
|
}
|
|
|
|
|
|
public GameObject CreateClusteredGameObjectSpawner(float range)
|
|
{
|
|
CreateOrFindSessionManager();
|
|
GameObject gaiaObj = GaiaUtils.GetGaiaGameObject();
|
|
//SpawnerGroup sg = CreateOrFindGroupSpawner();
|
|
|
|
GameObject spawnerObj = new GameObject("Clustered GameObject Spawner");
|
|
spawnerObj.AddComponent<Spawner>();
|
|
Spawner spawner = spawnerObj.GetComponent<Spawner>();
|
|
spawner.m_settings.m_resources = this;
|
|
spawnerObj.transform.parent = gaiaObj.transform;
|
|
spawnerObj.transform.position = Gaia.TerrainHelper.GetActiveTerrainCenter();
|
|
|
|
//Do basic setup
|
|
spawner.m_settings.m_resources = this;
|
|
spawner.m_mode = GaiaConstants.OperationMode.DesignTime;
|
|
spawner.m_spawnerShape = GaiaConstants.SpawnerShape.Box;
|
|
spawner.m_rndGenerator = new Gaia.XorshiftPlus(spawner.m_seed);
|
|
spawner.m_settings.m_spawnRange = range;
|
|
spawner.m_spawnFitnessAttenuator = new AnimationCurve(new Keyframe(0f, 1f), new Keyframe(1f, 1f));
|
|
spawner.m_spawnRuleSelector = GaiaConstants.SpawnerRuleSelector.Random;
|
|
spawner.m_spawnLocationAlgorithm = GaiaConstants.SpawnerLocation.RandomLocationClustered;
|
|
spawner.m_spawnCollisionLayers = Gaia.TerrainHelper.GetActiveTerrainLayer();
|
|
spawner.m_locationChecksPerInt = 2000;
|
|
spawner.m_maxRandomClusterSize = 20;
|
|
spawner.m_locationIncrement = 45;
|
|
|
|
//Iterate thru all the trees and add them.
|
|
SpawnRule rule;
|
|
for (int resIdx = 0; resIdx < m_gameObjectPrototypes.Length; resIdx++)
|
|
{
|
|
rule = new SpawnRule();
|
|
rule.m_name = m_gameObjectPrototypes[resIdx].m_name;
|
|
rule.m_resourceType = GaiaConstants.SpawnerResourceType.GameObject;
|
|
rule.m_resourceIdx = resIdx;
|
|
rule.m_minRequiredFitness = 0f;
|
|
rule.m_failureRate = 0f;
|
|
rule.m_maxInstances = (ulong)range * 2;
|
|
rule.m_isActive = true;
|
|
rule.m_isFoldedOut = false;
|
|
rule.m_useExtendedSpawn = false;
|
|
//spawner.m_activeRuleCnt++;
|
|
spawner.m_settings.m_spawnerRules.Add(rule);
|
|
}
|
|
|
|
//And it to the group spawner
|
|
SpawnerGroup.SpawnerInstance si;
|
|
si = new SpawnerGroup.SpawnerInstance();
|
|
si.m_name = spawnerObj.name;
|
|
si.m_interationsPerSpawn = 1;
|
|
si.m_spawner = spawner;
|
|
//sg.m_spawners.Add(si);
|
|
|
|
//And return it
|
|
return spawnerObj;
|
|
}
|
|
|
|
public GameObject CreateClusteredGameObjectSpawnerForTrees(float range)
|
|
{
|
|
CreateOrFindSessionManager();
|
|
GameObject gaiaObj = GaiaUtils.GetGaiaGameObject();
|
|
GameObject spawnerObj = new GameObject("Clustered GO Tree Spawner");
|
|
spawnerObj.AddComponent<Spawner>();
|
|
Spawner spawner = spawnerObj.GetComponent<Spawner>();
|
|
spawner.m_settings.m_resources = this;
|
|
spawnerObj.transform.parent = gaiaObj.transform;
|
|
spawnerObj.transform.position = Gaia.TerrainHelper.GetActiveTerrainCenter();
|
|
|
|
//Do basic setup
|
|
spawner.m_settings.m_resources = this;
|
|
spawner.m_mode = GaiaConstants.OperationMode.DesignTime;
|
|
spawner.m_spawnerShape = GaiaConstants.SpawnerShape.Box;
|
|
spawner.m_rndGenerator = new Gaia.XorshiftPlus(spawner.m_seed);
|
|
spawner.m_settings.m_spawnRange = range;
|
|
spawner.m_spawnFitnessAttenuator = new AnimationCurve(new Keyframe(0f, 1f), new Keyframe(1f, 1f));
|
|
spawner.m_spawnRuleSelector = GaiaConstants.SpawnerRuleSelector.Random;
|
|
spawner.m_spawnLocationAlgorithm = GaiaConstants.SpawnerLocation.RandomLocationClustered;
|
|
spawner.m_spawnCollisionLayers = Gaia.TerrainHelper.GetActiveTerrainLayer();
|
|
spawner.m_locationChecksPerInt = (int)range * 5;
|
|
spawner.m_maxRandomClusterSize = 30;
|
|
|
|
//Iterate thru all the trees and add them.
|
|
SpawnRule rule;
|
|
for (int resIdx = 0; resIdx < m_gameObjectPrototypes.Length; resIdx++)
|
|
{
|
|
if (m_gameObjectPrototypes[resIdx].m_canSpawnAsTree)
|
|
{
|
|
rule = new SpawnRule();
|
|
rule.m_name = m_gameObjectPrototypes[resIdx].m_name;
|
|
rule.m_resourceType = GaiaConstants.SpawnerResourceType.GameObject;
|
|
rule.m_resourceIdx = resIdx;
|
|
rule.m_minRequiredFitness = 0.25f;
|
|
rule.m_failureRate = 0f;
|
|
rule.m_maxInstances = (ulong)range * 2;
|
|
rule.m_isActive = true;
|
|
rule.m_isFoldedOut = false;
|
|
rule.m_useExtendedSpawn = false;
|
|
//spawner.m_activeRuleCnt++;
|
|
spawner.m_settings.m_spawnerRules.Add(rule);
|
|
}
|
|
}
|
|
|
|
//And it to the group spawner
|
|
SpawnerGroup.SpawnerInstance si;
|
|
si = new SpawnerGroup.SpawnerInstance();
|
|
si.m_name = spawnerObj.name;
|
|
si.m_interationsPerSpawn = 1;
|
|
si.m_spawner = spawner;
|
|
|
|
//And return it
|
|
return spawnerObj;
|
|
}
|
|
|
|
|
|
/*
|
|
public GameObject CreateStampSpawner(float range)
|
|
{
|
|
GameObject gaiaObj = GameObject.Find("Gaia");
|
|
if (gaiaObj == null)
|
|
{
|
|
gaiaObj = new GameObject("Gaia");
|
|
}
|
|
GameObject spawnerObj = new GameObject("Stamp Spawner");
|
|
spawnerObj.AddComponent<Spawner>();
|
|
Spawner spawner = spawnerObj.GetComponent<Spawner>();
|
|
spawner.m_settings.m_resources = this;
|
|
spawnerObj.transform.parent = gaiaObj.transform;
|
|
|
|
//Do basic setup
|
|
spawner.m_settings.m_resources = this;
|
|
spawner.m_mode = Constants.OperationMode.DesignTime;
|
|
spawner.m_spawnerShape = Constants.SpawnerShape.Box;
|
|
spawner.m_rndGenerator = new System.Random(spawner.m_seed);
|
|
spawner.m_spawnRange = range;
|
|
spawner.m_spawnRangeAttenuator = new AnimationCurve(new Keyframe(0f, 1f), new Keyframe(1f, 1f));
|
|
spawner.m_spawnRuleSelector = Constants.SpawnerRuleSelector.Random;
|
|
spawner.m_spawnLocationAlgorithm = Constants.SpawnerLocation.RandomLocation;
|
|
spawner.m_spawnerLayerMask = 1 << LayerMask.NameToLayer("Default");
|
|
spawner.m_locationChecksPerInt = 5;
|
|
spawner.m_maxRandomClusterSize = 1;
|
|
|
|
//Iterate thru all the stamps and add them.
|
|
SpawnRule rule;
|
|
for (int resIdx = 0; resIdx < m_stampPrototypes.Length; resIdx++)
|
|
{
|
|
rule = new SpawnRule();
|
|
rule.m_name = m_stampPrototypes[resIdx].m_name;
|
|
rule.m_resourceType = Constants.SpawnerResourceType.Stamp;
|
|
rule.m_resourceIdx = resIdx;
|
|
rule.m_minViableFitness = 0.25f;
|
|
rule.m_failureRate = 0f;
|
|
rule.m_maxInstances = (int)range / 5;
|
|
rule.m_isActive = true;
|
|
rule.m_isFoldedOut = false;
|
|
rule.m_useExtendedFitness = false;
|
|
rule.m_useExtendedSpawn = false;
|
|
spawner.m_activeRuleCnt++;
|
|
spawner.m_spawnerRules.Add(rule);
|
|
}
|
|
|
|
return spawnerObj;
|
|
}
|
|
*/
|
|
|
|
#endregion
|
|
|
|
#region Exporters
|
|
|
|
/// <summary>
|
|
/// This routine will export a texture from the current terrain - experimental only at moment and not supported.
|
|
/// </summary>
|
|
public void ExportTexture()
|
|
{
|
|
Terrain terrain;
|
|
Texture2D exportTexture;
|
|
Color pixel;
|
|
int width, height, layers;
|
|
float aR, aG, aB, aA;
|
|
|
|
//Now iterate through the terrains and export them
|
|
for (int terrIdx = 0; terrIdx < Terrain.activeTerrains.Length; terrIdx++)
|
|
{
|
|
terrain = Terrain.activeTerrains[terrIdx];
|
|
width = terrain.terrainData.alphamapWidth;
|
|
height = terrain.terrainData.alphamapHeight;
|
|
layers = terrain.terrainData.alphamapLayers;
|
|
exportTexture = new Texture2D(width, height, TextureFormat.ARGB32, false);
|
|
float[, ,] splatMaps = terrain.terrainData.GetAlphamaps(0, 0, width, height);
|
|
|
|
//Iterate thru the terrain
|
|
for (int x = 0; x < width; x++)
|
|
{
|
|
for (int z = 0; z < height; z++)
|
|
{
|
|
aR = aG = aB = aA = 0f;
|
|
for (int t = 0; t < layers; t++)
|
|
{
|
|
pixel = m_texturePrototypes[t].m_texture.GetPixel(
|
|
x % ((int)m_texturePrototypes[t].m_sizeX / m_texturePrototypes[t].m_texture.width),
|
|
z % ((int)m_texturePrototypes[t].m_sizeY / m_texturePrototypes[t].m_texture.height)
|
|
);
|
|
aR += splatMaps[x, z, t] * pixel.r;
|
|
aG += splatMaps[x, z, t] * pixel.g;
|
|
aB += splatMaps[x, z, t] * pixel.b;
|
|
aA += splatMaps[x, z, t] * pixel.a;
|
|
}
|
|
exportTexture.SetPixel(x, z, new Color(aR, aG, aB, aA));
|
|
}
|
|
}
|
|
|
|
//Now export / save the texture
|
|
Gaia.GaiaUtils.ExportPNG(terrain.name + " - Export", exportTexture);
|
|
|
|
//And destroy it
|
|
GameObject.DestroyImmediate(exportTexture);
|
|
}
|
|
Debug.LogError("Attempted to export textures on terrain that does not exist!");
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Serialisation
|
|
|
|
///// <summary>
|
|
///// Serialise this as json
|
|
///// </summary>
|
|
///// <returns></returns>
|
|
//public string SerialiseJson()
|
|
//{
|
|
// fsData data;
|
|
// fsSerializer serializer = new fsSerializer();
|
|
// serializer.TrySerialize(this, out data);
|
|
// return fsJsonPrinter.CompressedJson(data);
|
|
//}
|
|
|
|
///// <summary>
|
|
///// Deserialise the suplied json into this object
|
|
///// </summary>
|
|
///// <param name="json">Source json</param>
|
|
//public void DeSerialiseJson(string json)
|
|
//{
|
|
// fsData data = fsJsonParser.Parse(json);
|
|
// fsSerializer serializer = new fsSerializer();
|
|
// var defaults = this;
|
|
// serializer.TryDeserialize<GaiaResource>(data, ref defaults);
|
|
//}
|
|
|
|
#endregion
|
|
}
|
|
} |