You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
198 lines
9.2 KiB
C#
198 lines
9.2 KiB
C#
|
4 years ago
|
#if FLORA_PRESENT
|
||
|
|
using ProceduralWorlds.Flora;
|
||
|
|
#endif
|
||
|
|
using System.Collections;
|
||
|
|
using System.Collections.Generic;
|
||
|
|
using System.Linq;
|
||
|
|
using UnityEditor;
|
||
|
|
using UnityEngine;
|
||
|
|
|
||
|
|
namespace Gaia
|
||
|
|
{
|
||
|
|
/// <summary>
|
||
|
|
/// Data structure to provide override values for the asset guid / instance ID for a Flora LOD entry. List of those overrides are being used to handle loading of multiple LODs per spawn rule.
|
||
|
|
/// </summary>
|
||
|
|
public class FloraLODIdOverrides
|
||
|
|
{
|
||
|
|
public string m_assetGUIDOverride;
|
||
|
|
public int m_instanceIDOverride;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Data structure to support serializing multiple LODs of flora setting objects for trees / terrain details together with tree / terrain detail resource settings in the spawner
|
||
|
|
/// </summary>
|
||
|
|
[System.Serializable]
|
||
|
|
public class FloraLOD
|
||
|
|
{
|
||
|
|
public int m_index = 0;
|
||
|
|
public bool m_foldedOut = false;
|
||
|
|
public GaiaConstants.SpawnerResourceType m_spawnerResourceType;
|
||
|
|
public string m_name = "New Flora Settings Object";
|
||
|
|
public string m_detailerSettingsObjectAssetGUID;
|
||
|
|
public int m_detailerSettingsObjectInstanceID;
|
||
|
|
#if FLORA_PRESENT
|
||
|
|
public DetailScriptableObject DetailerSettingsObject
|
||
|
|
{
|
||
|
|
get
|
||
|
|
{
|
||
|
|
if (m_pwDetailerSettingsObject == null)
|
||
|
|
{
|
||
|
|
if (!(m_spawnerResourceType == GaiaConstants.SpawnerResourceType.TerrainDetail || m_spawnerResourceType == GaiaConstants.SpawnerResourceType.TerrainTree))
|
||
|
|
{
|
||
|
|
Debug.LogError($"Trying to create a Flora Scriptable object for a {m_spawnerResourceType} resource, this is not supported (yet)");
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
if (!string.IsNullOrEmpty(m_detailerSettingsObjectAssetGUID))
|
||
|
|
{
|
||
|
|
#if UNITY_EDITOR
|
||
|
|
string assetPath = AssetDatabase.GUIDToAssetPath(m_detailerSettingsObjectAssetGUID);
|
||
|
|
|
||
|
|
//This can be multiple objects since the scriptable object can be embedded in a spawner settings file
|
||
|
|
UnityEngine.Object[] allObjects = AssetDatabase.LoadAllAssetsAtPath(assetPath);
|
||
|
|
|
||
|
|
//Looking for the object via the instance ID
|
||
|
|
foreach (UnityEngine.Object obj in allObjects)
|
||
|
|
{
|
||
|
|
if (obj.GetType() == typeof(DetailScriptableObject) && obj.GetInstanceID() == m_detailerSettingsObjectInstanceID)
|
||
|
|
{
|
||
|
|
//found it, cast it into the correct type to store it
|
||
|
|
m_pwDetailerSettingsObject = (DetailScriptableObject)obj;
|
||
|
|
//is this a file that was embedded within other assets at this path?
|
||
|
|
if (allObjects.Count() > 1)
|
||
|
|
{
|
||
|
|
//we need to create a copy and save it to not work with the embedded file
|
||
|
|
m_pwDetailerSettingsObject = ScriptableObject.Instantiate(m_pwDetailerSettingsObject);
|
||
|
|
FloraUtils.SaveSettingsFile(m_pwDetailerSettingsObject, ref m_detailerSettingsObjectAssetGUID, ref m_detailerSettingsObjectInstanceID, false, m_name + "_" + m_index.ToString(), GaiaDirectories.GetFloraDataPath());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return m_pwDetailerSettingsObject;
|
||
|
|
}
|
||
|
|
set
|
||
|
|
{
|
||
|
|
if (value != m_pwDetailerSettingsObject)
|
||
|
|
{
|
||
|
|
m_pwDetailerSettingsObject = value;
|
||
|
|
if (value != null)
|
||
|
|
{
|
||
|
|
#if UNITY_EDITOR
|
||
|
|
m_detailerSettingsObjectAssetGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(value));
|
||
|
|
m_detailerSettingsObjectInstanceID = value.GetInstanceID();
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
m_detailerSettingsObjectAssetGUID = "";
|
||
|
|
m_detailerSettingsObjectInstanceID = -1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
//This needs to be serialized still to survive recompiles, etc.!
|
||
|
|
[SerializeField]
|
||
|
|
private DetailScriptableObject m_pwDetailerSettingsObject;
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Creates an instantiated (separate) copy of the detailer settings object in the Gaia User Data directory.
|
||
|
|
/// </summary>
|
||
|
|
public void InstantiateDetailerSettingsGO(ref Dictionary<int, string> materialMap)
|
||
|
|
{
|
||
|
|
#if UNITY_EDITOR
|
||
|
|
if (m_pwDetailerSettingsObject == null)
|
||
|
|
{
|
||
|
|
if (!string.IsNullOrEmpty(m_detailerSettingsObjectAssetGUID))
|
||
|
|
{
|
||
|
|
|
||
|
|
string assetPath = AssetDatabase.GUIDToAssetPath(m_detailerSettingsObjectAssetGUID);
|
||
|
|
|
||
|
|
//This can be multiple objects since the scriptable object can be embedded in a spawner settings file
|
||
|
|
UnityEngine.Object[] allObjects = AssetDatabase.LoadAllAssetsAtPath(assetPath);
|
||
|
|
|
||
|
|
//Looking for the object via the instance ID
|
||
|
|
foreach (UnityEngine.Object obj in allObjects)
|
||
|
|
{
|
||
|
|
if (obj.GetType() == typeof(DetailScriptableObject) && obj.GetInstanceID() == m_detailerSettingsObjectInstanceID)
|
||
|
|
{
|
||
|
|
//found it, cast it into the correct type to store it
|
||
|
|
m_pwDetailerSettingsObject = (DetailScriptableObject)obj;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (m_pwDetailerSettingsObject == null)
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
string floraDataPath = GaiaDirectories.GetFloraDataPath();
|
||
|
|
|
||
|
|
if (m_pwDetailerSettingsObject != null)
|
||
|
|
{
|
||
|
|
m_pwDetailerSettingsObject = ScriptableObject.Instantiate(m_pwDetailerSettingsObject);
|
||
|
|
FloraUtils.SaveSettingsFile(m_pwDetailerSettingsObject, ref m_detailerSettingsObjectAssetGUID, ref m_detailerSettingsObjectInstanceID, false, m_name + "_LOD" + m_index.ToString(), floraDataPath);
|
||
|
|
}
|
||
|
|
|
||
|
|
Material[] mats = m_pwDetailerSettingsObject.Mat.Where(x => x != null).ToArray();
|
||
|
|
List<Material> createdMaterials = new List<Material>();
|
||
|
|
//Handle Materials - those should never be null in theory, just need to be re-instantiated and saved
|
||
|
|
for (int i = 0; i < mats.Length; i++)
|
||
|
|
{
|
||
|
|
//if the material map contains the instance ID already, this means this material has already been created within the Flora data folder
|
||
|
|
int instanceID = m_pwDetailerSettingsObject.Mat[i].GetInstanceID();
|
||
|
|
if (materialMap.Keys.Contains(instanceID))
|
||
|
|
{
|
||
|
|
//-> take the already existing material then!
|
||
|
|
m_pwDetailerSettingsObject.Mat[i] = (Material)AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(materialMap.First(x => x.Key == instanceID).Value), typeof(Material));
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
//create a new material
|
||
|
|
string originalName = m_pwDetailerSettingsObject.Mat[i].name;
|
||
|
|
m_pwDetailerSettingsObject.Mat[i] = Material.Instantiate(m_pwDetailerSettingsObject.Mat[i]);
|
||
|
|
//Remove "(Clone)" from the name
|
||
|
|
m_pwDetailerSettingsObject.Mat[i].name = originalName;
|
||
|
|
string assetPath = floraDataPath + "/" + m_pwDetailerSettingsObject.Mat[i].name + "_" + instanceID + ".mat";
|
||
|
|
AssetDatabase.CreateAsset(m_pwDetailerSettingsObject.Mat[i], assetPath);
|
||
|
|
//AssetDatabase.ImportAsset(assetPath);
|
||
|
|
//Log the creation of the material for this instance ID in the material map
|
||
|
|
materialMap.Add(instanceID,AssetDatabase.AssetPathToGUID(assetPath));
|
||
|
|
//createdMaterials.Add((Material)AssetDatabase.LoadAssetAtPath(assetPath, typeof(Material)));
|
||
|
|
createdMaterials.Add(m_pwDetailerSettingsObject.Mat[i]);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//Migrate shaders in materials (could potentially be created in different pipeline originally)
|
||
|
|
GaiaUtils.ProcessMaterialLibrary(createdMaterials);
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Copies the fields of the old object over into the existing one to overwrite it
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="oldObject"></param>
|
||
|
|
public void CopySettingsAndApply(DetailScriptableObject oldObject)
|
||
|
|
{
|
||
|
|
string oldName = oldObject.name;
|
||
|
|
GaiaUtils.CopyFields(m_pwDetailerSettingsObject, oldObject, true);
|
||
|
|
DetailerSettingsObject = oldObject;
|
||
|
|
DetailerSettingsObject.name = oldName;
|
||
|
|
DetailerSettingsObject.SourceDataType = CoreCommonFloraData.SourceDataType.Detail;
|
||
|
|
//Make sure the materials use the right shader
|
||
|
|
GaiaUtils.ProcessMaterialLibrary(DetailerSettingsObject.Mat.ToList());
|
||
|
|
#if UNITY_EDITOR
|
||
|
|
EditorUtility.ClearProgressBar();
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|