/// <summary> /// Takes an imported JSON object, and breaks it into relevant components and data. /// Then calls relevant functions for actual import of asset. /// </summary> /// <param name="objectList"></param> public string ImportMegascansAssets(JObject objectList) { var startTime = System.DateTime.Now; string activeLOD = (string)objectList["activeLOD"]; string minLOD = (string)objectList["minLOD"]; isAlembic = false; plant = false; highPoly = false; hasBillboardLOD = false; hasBillboardLODOnly = false; mapName = ""; //get texture components from the current object. JArray textureComps = (JArray)objectList["components"]; //get mesh components from the current object. JArray meshComps = (JArray)objectList["meshList"]; //Map name overrides. mapNames = (JObject)objectList["mapNameOverride"]; //run a check to see if we're using Unity 5 or below, and then if we're trying to import a high poly mesh. if so, let the user know we are aborting the import. if (meshComps.Count > 0) { isAlembic = Path.GetExtension((string)meshComps[0]["path"]) == ".abc"; } hasBillboardLOD = MegascansMeshUtils.ContainsLowestLOD((JArray)objectList["lodList"], minLOD); assetType = (int)objectList["meshVersion"]; type = (string)objectList["type"]; if (type.ToLower().Contains("3dplant")) { plant = true; if (minLOD == activeLOD) { hasBillboardLODOnly = true; } } try { LoadPreferences(); MegascansUtilities.CalculateNumberOfOperations(objectList, dispType, texPack, shaderType, generateTerrainNormal, hasBillboardLODOnly); path = ConstructPath(objectList); if (path == null || path == "") { Debug.Log("Asset: " + (string)objectList["name"] + " already exist in the Project. Please delete/rename the existing folder and re-import this asset."); AssetDatabase.Refresh(); return(null); } GetShaderType(); } catch (Exception ex) { Debug.Log("Error setting import path."); Debug.Log(ex.ToString()); MegascansUtilities.HideProgressBar(); } try { //process textures ProcessTextures(textureComps); if (finalMat == null && !(plant && hasBillboardLODOnly)) { Debug.Log("The import path is incorrect. Asset import aborted."); return(null); } else { if (type.ToLower().Contains("surface") && applyToSelection) { foreach (MeshRenderer render in MegascansUtilities.GetSelectedMeshRenderers()) { render.material = finalMat; } } } } catch (Exception ex) { Debug.Log("Error importing textures."); Debug.Log(ex.ToString()); MegascansUtilities.HideProgressBar(); } //process meshes if (meshComps == null && !type.Contains("surface")) { Debug.LogError("No meshes found. Please double check your export settings."); Debug.Log("Import failed."); return(null); } if (meshComps.Count > 0) { if (activeLOD == "high") { //detect if we're trying to import a high poly mesh... string msg = "You are about to import a high poly mesh. \nThese meshes are usually millions of polygons and can cause instability to your project. \nWould you like to proceed?"; if (EditorUtility.DisplayDialog("WARNING!", msg, "Yes", "No")) { #if UNITY_EDITOR_WIN hpMat = new Material(finalMat.shader); hpMat.CopyPropertiesFromMaterial(finalMat); hpMat.SetTexture("_NormalMap", null); hpMat.SetTexture("_BumpMap", null); hpMat.DisableKeyword("_NORMALMAP_TANGENT_SPACE"); hpMat.DisableKeyword("_NORMALMAP"); hpMat.name = MegascansUtilities.FixSpaces(new string[] { hpMat.name, "HighPoly" }); string hpMatDir = MegascansUtilities.FixSpaces(new string[] { matPath, "HighPoly.mat" }); AssetDatabase.CreateAsset(hpMat, hpMatDir); #endif highPoly = true; } } try { //process meshes and prefabs PrefabData prefData = new PrefabData(path, finalName, lodFadeMode, highPoly, addAssetToScene, setupCollision, hasBillboardLOD, isAlembic, false, finalMat, hpMat, billboardMat, new List <string>(), new List <List <string> >()); MegascansMeshUtils.ProcessMeshes(objectList, path, highPoly, plant, prefData); } catch (Exception ex) { Debug.Log("Error importing meshes."); Debug.Log(ex.ToString()); MegascansUtilities.HideProgressBar(); } } var endTime = System.DateTime.Now; var totalTime = endTime - startTime; Debug.Log("Asset Import Time: " + totalTime); AssetDatabase.Refresh(); MegascansUtilities.HideProgressBar(); //Application.GarbageCollectUnusedAssets(); return(path); }
/// <summary> /// Takes an imported JSON object, and breaks it into relevant components and data. /// Then calls relevant functions for actual import of asset. /// </summary> /// <param name="objectList"></param> public string ImportMegascansAssets(JObject objectList) { var startTime = System.DateTime.Now; activeLOD = (string)objectList["activeLOD"]; string minLOD = (string)objectList["minLOD"]; assetName = (string)objectList["name"]; type = (string)objectList["type"]; isAlembic = false; plant = false; highPoly = false; hasBillboardLOD = false; hasBillboardLODOnly = false; mapName = ""; folderNamingConvention = (string)objectList["folderNamingConvention"]; //get mesh components from the current object. JArray meshComps = (JArray)objectList["meshList"]; //run a check to see if we're using Unity 5 or below, and then if we're trying to import a high poly mesh. if so, let the user know we are aborting the import. if (meshComps.Count > 0) { isAlembic = Path.GetExtension((string)meshComps[0]["path"]) == ".abc"; } hasBillboardLOD = MegascansMeshUtils.ContainsLowestLOD((JArray)objectList["lodList"], minLOD, activeLOD); if (type.ToLower().Contains("3dplant")) { plant = true; if (minLOD == activeLOD) { hasBillboardLODOnly = true; } } try { LoadPreferences(); shaderType = MegascansUtilities.GetShaderType(); MegascansUtilities.CalculateNumberOfOperations(objectList, dispType, texPack, shaderType, hasBillboardLODOnly); path = ConstructPath(objectList); if (path == null || path == "") { Debug.Log("Asset: " + (string)objectList["name"] + " already exist in the Project. Please delete/rename the existing folder and re-import this asset."); AssetDatabase.Refresh(); return(null); } } catch (Exception ex) { Debug.Log("Error setting import path."); Debug.Log(ex.ToString()); MegascansUtilities.HideProgressBar(); } try { //process textures ProcessTextures(objectList); if (finalMat == null && !(plant && hasBillboardLODOnly)) { Debug.Log("Could not import the textures and create the material."); return(null); } else { if (type.ToLower().Contains("surface") && applyToSelection) { foreach (MeshRenderer render in MegascansUtilities.GetSelectedMeshRenderers()) { render.material = finalMat; } } } } catch (Exception ex) { Debug.Log("Error importing textures."); Debug.Log(ex.ToString()); MegascansUtilities.HideProgressBar(); } //process meshes if (meshComps == null && !type.Contains("surface")) { Debug.LogError("No meshes found. Please double check your export settings."); Debug.Log("Import failed."); return(null); } if (meshComps.Count > 0) { if (activeLOD == "high") { //detect if we're trying to import a high poly mesh... string msg = "You are about to import a high poly mesh. \nThese meshes are usually millions of polygons and can cause instability to your project. \nWould you like to proceed?"; highPoly = EditorUtility.DisplayDialog("WARNING!", msg, "Yes", "No"); } try { //process meshes and prefabs PrefabData prefData = new PrefabData(path, assetName, folderNamingConvention, lodFadeMode, highPoly, addAssetToScene, setupCollision, hasBillboardLOD, isAlembic, false, false, finalMat, billboardMat, new List <string>(), new List <List <string> >()); MegascansMeshUtils.ProcessMeshes(objectList, path, highPoly, plant, prefData); } catch (Exception ex) { Debug.Log("Error importing meshes."); Debug.Log(ex.ToString()); MegascansUtilities.HideProgressBar(); } } var endTime = System.DateTime.Now; var totalTime = endTime - startTime; Debug.Log("Asset Import Time: " + totalTime); AssetDatabase.Refresh(); MegascansUtilities.HideProgressBar(); Resources.UnloadUnusedAssets(); GC.Collect(); return(path); }
/// <summary> /// Creates prefabs for the 3D Scatter assets. /// </summary> /// <param name="hasBillboard"></param> /// <returns></returns> public static void CreatePrefabsScatter(PrefabData prefabData) { try { string prefabPath = MegascansUtilities.ValidateFolderCreate(prefabData.assetPath, "Prefabs"); int numberOfVariations = MegascansUtilities.GetMeshChildrenCount(prefabData.importedGeometryPaths3D); List <GameObject> prefabObjects = new List <GameObject>(); for (int i = 0; i < numberOfVariations; i++) { string prefabName = prefabData.finalAssetName.Replace("$mapName", "").Replace("$resolution", "").Replace("$lod", "").Replace("$variation", ""); string varName = "Var" + (i + 1).ToString(); prefabName = prefabName.Contains("$variation") ? prefabName.Replace("$variation", "Var" + varName) : prefabName + varName; //Setting up prefab gameobject GameObject prefabGameObject = new GameObject(); prefabGameObject.name = prefabName; prefabGameObject.isStatic = true; if (prefabData.setupLODs) { prefabGameObject.AddComponent <LODGroup>(); prefabGameObject.GetComponent <LODGroup>().fadeMode = (LODFadeMode)prefabData.lodFadeMode; //Casting lod fade mode to enum. prefabGameObject.GetComponent <LODGroup>().animateCrossFading = true; } List <LOD> lodsForPrefab = new List <LOD>(); int numberOfFiles = prefabData.importedGeometryPaths3D.Count; List <float> lodHeights = MegascansUtilities.getLODHeightList(numberOfFiles); //Instantiate all the meshes in the scene, add them to the material/collider to them. for (int x = 0; (x < numberOfFiles && x < 8); x++) { UnityEngine.Object loadedGeometry = AssetDatabase.LoadAssetAtPath <UnityEngine.Object>(prefabData.importedGeometryPaths3D[x]); //Highpoly mesh check. if (loadedGeometry.name.ToLower().Contains("highpoly") && !prefabData.highpoly) { continue; } GameObject geometryObject = Instantiate(loadedGeometry) as GameObject; Renderer[] r; if (prefabData.isAlembic) //if the instantiated mesh is an alembic asset. { //Get all variations in a LOD List <Transform> varsInLOD = new List <Transform>(); foreach (Transform var in geometryObject.transform) { varsInLOD.Add(var); } //Delete all the other variations in the LOD object for (int y = 0; y < varsInLOD.Count; y++) { //If variation does not match one currently being processed. if (y != i) { DestroyImmediate(varsInLOD[y].gameObject); } } //Parent the child gameobject (geometry) to the prefab game object. geometryObject.transform.parent = prefabGameObject.transform; geometryObject.transform.localPosition = Vector3.zero; geometryObject.name = geometryObject.name.Replace("(Clone)", ""); r = geometryObject.GetComponentsInChildren <Renderer>(); } else//if the instantiated mesh is a scatter type asset. { //Get all variations in a LOD List <Transform> varsInLOD = new List <Transform>(); foreach (Transform var in geometryObject.transform) { varsInLOD.Add(var); } //Delete all the other variations in the LOD object for (int y = 0; y < varsInLOD.Count; y++) { //If variation does not match one currently being processed. if (y != i) { DestroyImmediate(varsInLOD[y].gameObject); } } //Parent the child gameobject (geometry) to the prefab game object. geometryObject.transform.parent = prefabGameObject.transform; geometryObject.transform.localPosition = Vector3.zero; geometryObject.name = geometryObject.name.Replace("(Clone)", ""); r = geometryObject.GetComponentsInChildren <Renderer>(); } foreach (Renderer ren in r) { ren.material = prefabData.finalMat; //Apply highpoly material if the mesh was highpoly and highpoly filter is enabled. if (loadedGeometry.name.ToLower().Contains("highpoly") && prefabData.highpoly) { ren.material = prefabData.highpolyMat; #if UNITY_EDITOR_OSX ren.material = prefabData.finalMat; #endif } //Apply collision if (prefabData.setupCollision) { ren.gameObject.AddComponent <MeshCollider>().sharedMesh = ren.gameObject.GetComponent <MeshFilter>().sharedMesh; } } if (prefabData.setupLODs) { lodsForPrefab.Add(new LOD(lodHeights[0], r)); lodHeights.RemoveAt(0); } else { break; } } //Set LODs in the LOD group if (prefabData.setupLODs) { prefabGameObject.GetComponent <LODGroup>().SetLODs(lodsForPrefab.ToArray()); prefabGameObject.GetComponent <LODGroup>().RecalculateBounds(); } //Prefab saving string prefLocation = prefabPath + "/" + prefabName + ".prefab"; prefLocation = prefLocation.Replace("(Clone)", ""); GameObject prefabObject = SavePrefab(prefabGameObject, prefLocation, prefabData.addAssetToScene); if (prefabObject) { prefabObjects.Add(prefabObject); } } //Setting up variation holder gameobject GameObject scatterParent = new GameObject(prefabData.assetName); scatterParent.isStatic = true; foreach (GameObject variation in prefabObjects) { variation.transform.parent = scatterParent.transform; } } catch (Exception ex) { Debug.Log("Exception::MegascansMeshUtils::3D Asset Prefab:: " + ex.ToString()); MegascansUtilities.HideProgressBar(); } }
/// <summary> /// Creates prefabs from the newer assets on bridge, has an option for billboard materials on plants. /// </summary> /// <param name="hasBillboard"></param> /// <returns></returns> public static void CreatePrefab3DPlant(PrefabData prefabData) { try { string prefabPath = MegascansUtilities.ValidateFolderCreate(prefabData.assetPath, "Prefabs"); string tempPrefabName = prefabData.finalAssetName.Replace("$mapName", "").Replace("$resolution", "").Replace("$lod", ""); List <GameObject> prefabObjects = new List <GameObject>(); for (int i = 0; i < prefabData.importedGeometryPaths3DPlant.Count; i++) { string variation = "Var" + (i + 1).ToString(); string prefabName = tempPrefabName.Contains("$variation") ? tempPrefabName.Replace("$variation", variation) : tempPrefabName + "_" + variation; //Prefab saving //Setting up prefab gameobject GameObject prefabGameObject = new GameObject(); prefabGameObject.name = prefabName; prefabGameObject.isStatic = true; if (prefabData.setupLODs) { prefabGameObject.AddComponent <LODGroup>(); prefabGameObject.GetComponent <LODGroup>().fadeMode = (LODFadeMode)prefabData.lodFadeMode; //Casting lod fade mode to enum. prefabGameObject.GetComponent <LODGroup>().animateCrossFading = true; } List <LOD> lodsForPrefab = new List <LOD>(); int numberOfFiles = prefabData.importedGeometryPaths3DPlant[i].Count; List <float> lodHeights = MegascansUtilities.getLODHeightList(numberOfFiles); //Instantiate all the meshes in the scene, add them to the material/collider to them. for (int x = 0; (x < numberOfFiles && x < 8); x++) { UnityEngine.Object loadedGeometry = AssetDatabase.LoadAssetAtPath <UnityEngine.Object>(prefabData.importedGeometryPaths3DPlant[i][x]); //Highpoly mesh check. if (loadedGeometry.name.ToLower().Contains("highpoly") && !prefabData.highpoly) { continue; } GameObject geometryObject = Instantiate(loadedGeometry) as GameObject; Renderer[] r; //Parent all the objects to the prefab game object. if (geometryObject.transform.childCount > 0 && !prefabData.isAlembic) { r = new Renderer[geometryObject.transform.childCount]; for (int j = 0; j < geometryObject.transform.childCount; ++j) { //Parent the child gameobject (geometry) to the prefab game object. GameObject geometryChildObject = geometryObject.transform.GetChild(j).gameObject; //Cache a reference to the child gameobject of the geometry. geometryChildObject.transform.parent = prefabGameObject.transform; geometryChildObject.transform.localPosition = Vector3.zero; geometryChildObject.name = geometryChildObject.name.Replace("(Clone)", ""); r[j] = geometryChildObject.GetComponent <Renderer>(); } //Destroy the empty parent container which was holding the meshes. DestroyImmediate(geometryObject); } else if (prefabData.isAlembic) //if the instantiated mesh is an alembic asset. { //Parent the child gameobject (geometry) to the prefab game object. geometryObject.transform.parent = prefabGameObject.transform; geometryObject.transform.localPosition = Vector3.zero; geometryObject.name = geometryObject.name.Replace("(Clone)", ""); r = geometryObject.GetComponentsInChildren <Renderer>(); } else //if the instantiated mesh does not have any children { r = new Renderer[1]; //Parent the child gameobject (geometry) to the prefab game object. geometryObject.transform.parent = prefabGameObject.transform; geometryObject.transform.localPosition = Vector3.zero; geometryObject.name = geometryObject.name.Replace("(Clone)", ""); r[0] = geometryObject.GetComponent <Renderer>(); } foreach (Renderer ren in r) { ren.material = prefabData.finalMat; //Apply highpoly material if the mesh was highpoly and highpoly filter is enabled. if (loadedGeometry.name.ToLower().Contains("highpoly") && prefabData.highpoly) { ren.material = prefabData.highpolyMat; #if UNITY_EDITOR_OSX ren.material = prefabData.finalMat; #endif } //Billboard material application if (prefabData.hasBillboardLOD && x == (numberOfFiles - 1)) { ren.material = prefabData.billboardMat; } //Apply collision if (prefabData.setupCollision) { ren.gameObject.AddComponent <MeshCollider>().sharedMesh = ren.gameObject.GetComponent <MeshFilter>().sharedMesh; } } if (prefabData.setupLODs) { lodsForPrefab.Add(new LOD(lodHeights[0], r)); lodHeights.RemoveAt(0); } else { break; } } //Set LODs in the LOD group if (prefabData.setupLODs) { prefabGameObject.GetComponent <LODGroup>().SetLODs(lodsForPrefab.ToArray()); prefabGameObject.GetComponent <LODGroup>().RecalculateBounds(); } //Prefab saving string prefLocation = prefabPath + "/" + prefabName + ".prefab"; prefLocation = prefLocation.Replace("(Clone)", ""); GameObject prefabObject = SavePrefab(prefabGameObject, prefLocation, prefabData.addAssetToScene); if (prefabObject) { prefabObjects.Add(prefabObject); } } //Setting up variation holder gameobject GameObject plantsParent = new GameObject(prefabData.assetName); plantsParent.isStatic = true; foreach (GameObject variation in prefabObjects) { variation.transform.parent = plantsParent.transform; } } catch (Exception ex) { Debug.Log("Exception::MegascansMeshUtils::3D Plant Prefab:: " + ex.ToString()); MegascansUtilities.HideProgressBar(); } }
/// <summary> /// Import meshes, start from highest LOD and import the chain. /// </summary> public static void ProcessMeshes(JObject assetJson, string assetFolderPath, bool highpoly, bool hasVariations, PrefabData prefabData) { try { bool createPrefabs = EditorPrefs.GetBool("QuixelDefaultSetupPrefabs", true); bool importLODs = EditorPrefs.GetBool("QuixelDefaultImportLODs", true); bool setupLODs = EditorPrefs.GetBool("QuixelDefaultSetupLOD", true); prefabData.setupLODs = (importLODs && setupLODs); //Only do LOD setup if lower lods were imported and LOD grouping is enabled. //get mesh components from the current object. Also, meshComps.Count can give us the number of variations ;) JArray meshComps = (JArray)assetJson["meshList"]; JArray lodList = (JArray)assetJson["lodList"]; string activeLOD = (string)assetJson["activeLOD"]; string minLOD = (string)assetJson["minLOD"]; string modelsFolderPath = MegascansUtilities.ValidateFolderCreate(assetFolderPath, "Models"); if (hasVariations) { List <List <string> > importedGeometryPaths3DPlant = new List <List <string> >(); for (int i = 1; i <= meshComps.Count; i++) { List <string> importedGeometryPaths = new List <string>(); bool lodMatched = false; // This flag helps to import the lower lods once the active lod is found. foreach (JObject mesh in lodList) { if ((int)mesh["variation"] == i) { string currentLOD = (string)mesh["lod"]; if (lodMatched || currentLOD == activeLOD || highpoly) { lodMatched = true; if ((currentLOD == "high") && !highpoly) { continue; } //get the path of the highest LOD to be imported. string sourcePath = (string)mesh["path"]; string destPath = Path.Combine(modelsFolderPath, (string)mesh["nameOverride"]); ImportMesh(sourcePath, destPath); importedGeometryPaths.Add(destPath); if (!importLODs) { break; } } } } importedGeometryPaths3DPlant.Add(importedGeometryPaths); } prefabData.importedGeometryPaths3DPlant = importedGeometryPaths3DPlant; if (createPrefabs) { CreatePrefab3DPlant(prefabData); } } else { List <string> importedGeometryPaths3D = new List <string>(); bool lodMatched = false; // This flag helps to import the lower lods once the active lod is found. foreach (JObject mesh in lodList) { string currentLOD = (string)mesh["lod"]; if (lodMatched || (currentLOD == activeLOD) || highpoly) { lodMatched = true; if ((currentLOD == "high") && !highpoly) { continue; } //get the path of the highest LOD to be imported. string sourcePath = (string)mesh["path"]; string destPath = Path.Combine(modelsFolderPath, (string)mesh["nameOverride"]); ImportMesh(sourcePath, destPath); importedGeometryPaths3D.Add(destPath); if (!importLODs) { break; } } } prefabData.importedGeometryPaths3D = importedGeometryPaths3D; if (createPrefabs) { if (MegascansUtilities.isScatterAsset(assetJson, importedGeometryPaths3D)) { CreatePrefabsScatter(prefabData); } else { CreatePrefab3D(prefabData); } } } } catch (Exception ex) { Debug.Log("Exception::MegascansMeshUtils::Processing Meshes:: " + ex.ToString()); MegascansUtilities.HideProgressBar(); } }
/// <summary> /// Generates prefabs from imported meshes. /// Used for normal 3D assets /// </summary> public static void CreatePrefab3D(PrefabData prefabData) { try { string prefabPath = MegascansUtilities.ValidateFolderCreate(prefabData.assetPath, "Prefabs"); string prefabName = prefabData.modelNamingConvention; //Setting up prefab gameobject GameObject prefabGameObject = new GameObject(); prefabGameObject.name = prefabName; prefabGameObject.isStatic = true; if (prefabData.setupLODs) { prefabGameObject.AddComponent <LODGroup>(); prefabGameObject.GetComponent <LODGroup>().fadeMode = (LODFadeMode)prefabData.lodFadeMode; //Casting lod fade mode to enum. prefabGameObject.GetComponent <LODGroup>().animateCrossFading = true; } List <LOD> lodsForPrefab = new List <LOD>(); int numberOfFiles = prefabData.importedGeometryPaths3D.Count; List <float> lodHeights = MegascansUtilities.getLODHeightList(numberOfFiles); //Instantiate all the meshes in the scene, add them to the material/collider to them. for (int x = 0; (x < numberOfFiles && x < 8); x++) { UnityEngine.Object loadedGeometry = AssetDatabase.LoadAssetAtPath <UnityEngine.Object>(prefabData.importedGeometryPaths3D[x]); //Highpoly mesh check. if (loadedGeometry.name.ToLower().Contains("highpoly") && !prefabData.highpoly) { continue; } GameObject geometryObject = Instantiate(loadedGeometry) as GameObject; Renderer[] r; //Parent all the objects to the prefab game object. if (geometryObject.transform.childCount > 0 && !prefabData.isAlembic) { r = new Renderer[geometryObject.transform.childCount]; for (int j = 0; j < geometryObject.transform.childCount; ++j) { //Parent the child gameobject (geometry) to the prefab game object. GameObject geometryChildObject = geometryObject.transform.GetChild(j).gameObject; //Cache a reference to the child gameobject of the geometry. geometryChildObject.transform.parent = prefabGameObject.transform; geometryChildObject.transform.localPosition = Vector3.zero; geometryChildObject.name = geometryChildObject.name.Replace("(Clone)", ""); r[j] = geometryChildObject.GetComponentInChildren <Renderer>(); } //Destroy the empty parent container which was holding the meshes. DestroyImmediate(geometryObject); } else if (prefabData.isAlembic) //if the instantiated mesh is an alembic asset. { //Parent the child gameobject (geometry) to the prefab game object. geometryObject.transform.parent = prefabGameObject.transform; geometryObject.transform.localPosition = Vector3.zero; geometryObject.name = geometryObject.name.Replace("(Clone)", ""); r = geometryObject.GetComponentsInChildren <Renderer>(); } else //if the instantiated mesh does not have any children { //Parent the child gameobject (geometry) to the prefab game object. geometryObject.transform.parent = prefabGameObject.transform; geometryObject.transform.localPosition = Vector3.zero; geometryObject.name = geometryObject.name.Replace("(Clone)", ""); r = geometryObject.GetComponentsInChildren <Renderer>(); } foreach (Renderer ren in r) { ren.material = prefabData.finalMat; //Apply collision if (prefabData.setupCollision) { ren.gameObject.AddComponent <MeshCollider>().sharedMesh = ren.gameObject.GetComponent <MeshFilter>().sharedMesh; } } if (prefabData.setupLODs) { lodsForPrefab.Add(new LOD(lodHeights[0], r)); lodHeights.RemoveAt(0); } else //We only set the prefab with 1 LOD if setup LODs is unchecked. { break; } } //Set LODs in the LOD group if (prefabData.setupLODs) { prefabGameObject.GetComponent <LODGroup>().SetLODs(lodsForPrefab.ToArray()); prefabGameObject.GetComponent <LODGroup>().RecalculateBounds(); } //Prefab saving string prefLocation = prefabPath + "/" + prefabName + ".prefab"; prefLocation = prefLocation.Replace("(Clone)", ""); SavePrefab(prefabGameObject, prefLocation, prefabData.addAssetToScene); } catch (Exception ex) { Debug.Log("Exception::MegascansMeshUtils::3D Asset Prefab:: " + ex.ToString()); MegascansUtilities.HideProgressBar(); } }
/// <summary> /// Generates prefabs from imported meshes. /// Used for normal 3D assets /// </summary> public static void CreatePrefab3D(PrefabData prefabData) { try { string prefabPath = MegascansUtilities.ValidateFolderCreate(prefabData.assetPath, "Prefabs"); string prefabName = prefabData.finalAssetName.Replace("$mapName", "").Replace("$resolution", "").Replace("$lod", "").Replace("$variation", ""); //Setting up prefab gameobject GameObject prefabGameObject = new GameObject(); prefabGameObject.name = prefabName; prefabGameObject.AddComponent <LODGroup>(); prefabGameObject.GetComponent <LODGroup>().fadeMode = (LODFadeMode)prefabData.lodFadeMode; //Casting lod fade mode to enum. prefabGameObject.GetComponent <LODGroup>().animateCrossFading = true; prefabGameObject.isStatic = true; float lodHeight = 1.0f; List <LOD> lodsForPrefab = new List <LOD>(); int numberOfFiles = prefabData.importedGeometryPaths3D.Count; //Instantiate all the meshes in the scene, add them to the material/collider to them. for (int x = 0; x < numberOfFiles; x++) { UnityEngine.Object loadedGeometry = AssetDatabase.LoadAssetAtPath <UnityEngine.Object>(prefabData.importedGeometryPaths3D[x]); //Highpoly mesh check. if (loadedGeometry.name.ToLower().Contains("highpoly") && !prefabData.highpoly) { continue; } GameObject geometryObject = Instantiate(loadedGeometry) as GameObject; Renderer[] r; //Parent all the objects to the prefab game object. if (geometryObject.transform.childCount > 0 && !prefabData.isAlembic) { r = new Renderer[geometryObject.transform.childCount]; for (int j = 0; j < geometryObject.transform.childCount; ++j) { //Parent the child gameobject (geometry) to the prefab game object. GameObject geometryChildObject = geometryObject.transform.GetChild(j).gameObject; //Cache a reference to the child gameobject of the geometry. geometryChildObject.transform.parent = prefabGameObject.transform; geometryChildObject.transform.localPosition = Vector3.zero; geometryChildObject.name = geometryChildObject.name.Replace("(Clone)", ""); //Get reference to the renderer components to apply material later. r[j] = geometryChildObject.GetComponentInChildren <Renderer>(); } //Destroy the empty parent container which was holding the meshes. DestroyImmediate(geometryObject); } else if (prefabData.isAlembic) //if the instantiated mesh is an alembic asset. { //Parent the child gameobject (geometry) to the prefab game object. geometryObject.transform.parent = prefabGameObject.transform; geometryObject.transform.localPosition = Vector3.zero; geometryObject.name = geometryObject.name.Replace("(Clone)", ""); //Get reference to the renderer components to apply material later. r = geometryObject.GetComponentsInChildren <Renderer>(); } else //if the instantiated mesh does not have any children { //Parent the child gameobject (geometry) to the prefab game object. geometryObject.transform.parent = prefabGameObject.transform; geometryObject.transform.localPosition = Vector3.zero; geometryObject.name = geometryObject.name.Replace("(Clone)", ""); //Get reference to the renderer component to apply material later. r = geometryObject.GetComponentsInChildren <Renderer>(); } foreach (Renderer ren in r) { ren.material = prefabData.finalMat; //Apply highpoly material if the mesh was highpoly and highpoly filter is enabled. if (loadedGeometry.name.ToLower().Contains("highpoly") && prefabData.highpoly) { ren.material = prefabData.highpolyMat; #if UNITY_EDITOR_OSX ren.material = prefabData.finalMat; #endif } //Apply collision if (prefabData.setupCollision) { ren.gameObject.AddComponent <MeshCollider>().sharedMesh = ren.gameObject.GetComponent <MeshFilter>().sharedMesh; } } if (numberOfFiles > 2) { lodHeight *= ((x + 1) >= (numberOfFiles / 2)) ? 0.75f : 0.5f; } else { lodHeight *= (x + 1) < 1 ? 0.75f : 0.15f; } lodsForPrefab.Add(new LOD(lodHeight, r)); } //Set LODs in the LOD group prefabGameObject.GetComponent <LODGroup>().SetLODs(lodsForPrefab.ToArray()); prefabGameObject.GetComponent <LODGroup>().RecalculateBounds(); //Prefab saving string prefLocation = prefabPath + "/" + prefabName + ".prefab"; prefLocation = prefLocation.Replace("(Clone)", ""); SavePrefab(prefabGameObject, prefLocation, prefabData.addAssetToScene); } catch (Exception ex) { Debug.Log("Exception::MegascansMeshUtils::3D Asset Prefab:: " + ex.ToString()); MegascansUtilities.HideProgressBar(); } }