EditorGUILayout.HelpBox("One or more GameObjects of the selection is not a root Automatic LOD GameObject. Only root Automatic LOD GameObjects can be edited at the same time.",MessageType.Warning);
EditorGUILayout.PropertyField(PropertyGenerateIncludeChildren,newGUIContent(strIncludeChildrenLabel,"If checked, we will traverse the whole GameObject's hierarchy looking for meshes"));
GUILayout.BeginHorizontal();
EditorGUILayout.PropertyField(PropertySwitchMode,newGUIContent("Switch Mode","Use the new LODGroup for best performance and robustness. The other two are legacy methods: Mesh will create internal meshes and switch between them. GameObject will create LOD level hierarchy GameObjects."));
EditorGUILayout.PropertyField(PropertyLevelsToGenerate,newGUIContent("Levels To Generate","Tells how many levels to create by default, but can be changed later on"));
//GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
}
else
{
// LODGroup uses 4 levels by default (3 + fully culled) and there is no way to change that programatically without falling into Unity's bug where LODGroup.SetLODS() fails
if(GUILayout.Button(newGUIContent("Generate LODs","Starts the LOD generation process"),GUILayout.Width(nButtonWidth)))
{
m_bGenerateLODData=true;
}
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
EditorGUILayout.HelpBox("Number of LOD levels and their properties can be changed later on this panel, after pressing the \"Generate LODs\" button.\n\nSwitch Mode should have no significant speed impact, it's more a convenience option:\nSwitch Mesh will generate internal meshes and switch between them on the same GameObject. Switch GameObject will generate child GameObjects containing LOD levels and enable/disable the correct one.",MessageType.Info);
EditorGUILayout.PropertyField(PropertyEvalMode,newGUIContent("LOD Switch Criteria","Changes the criteria used to switch from one LOD to another at runtime"));
PropertyMaxCameraDistanceDistance.floatValue=EditorGUILayout.FloatField(newGUIContent("Max Camera Distance","Furthest camera distance to consider"),PropertyMaxCameraDistanceDistance.floatValue);
}
}
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(PropertyEnablePrefabUsage,newGUIContent("Enable Prefab Usage","Will save the generated mesh assets to disk, so that this GameObject can be used as a prefab and be instantiated at runtime. Otherwise the mesh won't be available"));
EditorGUILayout.HelpBox("Use vertex relevance spheres to select which vertices should be preserved with more or less priority when simplifying the mesh.",MessageType.Info);
EditorGUILayout.Space();
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
if(GUILayout.Button(newGUIContent("Add New Sphere","Adds a new vertex relevance sphere"),GUILayout.Width(nButtonWidthSmall)))
elementRelevance.floatValue=EditorGUILayout.Slider(newGUIContent("Relevance","Tells the simplification algorithm how relevant the vertices inside this sphere are. Default relevance is 0, use lower values to discard non important vertices, and higher values to keep them before others when simplifying the mesh"),elementRelevance.floatValue,-1.0f,1.0f);
if(EditorGUI.EndChangeCheck())
{
PropertyLODDataDirty.boolValue=true;
}
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
if(GUILayout.Button(newGUIContent("Remove Sphere","Removes this relevance sphere"),GUILayout.Width(nButtonWidthSmall)))
helpBoxString+=" Use the LODGroup component to adjust the camera ranges where each LOD level is visible";
}
else
{
helpBoxString+=" Right click to add / delete new LOD levels.Drag the splitters in between to adjust when each LOD level should be visible and slide the top cursor to preview the current settings in the Scene window.";
if(GUILayout.Button(newGUIContent("Recompute all levels","Recomputes all different LOD meshes at once"),GUILayout.Width(nButtonWidth)))
{
m_bRecomputeAllMeshes=true;
}
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
if(GUILayout.Button(newGUIContent("Delete LOD data...","Deletes all LOD data and restores the original GameObject's mesh"),GUILayout.Width(nButtonWidth)))
{
if(EditorUtility.DisplayDialog("Delete all LOD data and restore original mesh?","Are you sure you want to delete all LOD data and restore the original mesh?","Delete","Cancel"))
{
m_bDeleteLODData=true;
}
}
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
}
else
{
GUILayout.Label("Child LOD GameObject depending on "+automaticLOD.m_LODObjectRoot.name);
EditorGUILayout.PropertyField(PropertyOverrideRootSettings,newGUIContent("Override "+automaticLOD.m_LODObjectRoot.name+" settings","Will allow to edit this object's own parameters, instead of inheriting those of the root Automatic LOD GameObject"));
floatfVertexAmount=EditorGUILayout.Slider(newGUIContent("LOD "+nLevel+" vertex %","The percentage of vertices from the original mesh to keep when simplifying it"),elementVertexAmount.floatValue*100.0f,0.0f,100.0f);
if(GUILayout.Button(newGUIContent("Exclude from LOD tree...","Restores this GameObject's original mesh and excludes it from the LOD computation"),GUILayout.Width(nButtonWidth)))
{
if(EditorUtility.DisplayDialog("Remove from LOD tree?","Are you sure you want to restore this gameobject's mesh and exclude it from the LOD logic?","Remove","Cancel"))
EditorUtility.DisplayDialog("Error","Object "+automaticLOD.name+" has no MeshFilter nor Skinned Mesh to process. Please use the \""+strIncludeChildrenLabel+"\" parameter if you want to process the whole "+automaticLOD.name+" hierarchy for meshes","OK");
// We force a specific LOD here using LODGroup. To exit this state we will monitor the scene cameras and if there is a change then restore control to LODGroup
stringstrRange=string.Format("{0:0.0}% to {1:0.0}%",automaticLOD.m_listLODLevels[nLOD].m_fScreenCoverage*100.0f,m_nCurrentLODSelected<(nLODLevels-1)?(automaticLOD.m_listLODLevels[nLOD+1].m_fScreenCoverage*100.0f):0.0f);
strLabel="Rendered when the object covers "+strRange+" screen space";
stringstrRange=string.Format("{0:0.0} to {1:0.0}",automaticLOD.m_listLODLevels[nLOD].m_fMaxCameraDistance,m_nCurrentLODSelected<(nLODLevels-1)?(automaticLOD.m_listLODLevels[nLOD+1].m_fMaxCameraDistance):Mathf.Infinity);
strLabel="Rendered when the camera is at a distance from "+strRange;
}
GUILayout.Label(strLabel);
}
floatfVertexAmount=EditorGUILayout.Slider(newGUIContent("Total vertices %","The percentage of vertices from the original mesh to keep when simplifying it"),elementMeshVerticesAmount.floatValue*100.0f,0.0f,100.0f);
strMeshAssetPath=UnityEditor.EditorUtility.SaveFilePanelInProject("Save mesh asset(s)","mesh_"+gameObject.name+gameObject.GetInstanceID().ToString()+".asset","asset","Please enter a file name to save the mesh asset(s) to");
EditorGUILayout.HelpBox("One or more GameObjects of the selection is not a root MeshSimplify GameObject. Only root MeshSimplify GameObjects can be edited at the same time.",MessageType.Warning);
EditorGUILayout.PropertyField(PropertyGenerateIncludeChildren,newGUIContent(strIncludeChildrenLabel,"If checked, we will traverse the whole GameObject's hierarchy looking for meshes"));
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(PropertyEnablePrefabUsage,newGUIContent("Enable Prefab Usage","Will save the generated mesh assets to disk, so that this GameObject can be used as a prefab and be instantiated at runtime. Otherwise the mesh won't be available"));
if(EditorGUI.EndChangeCheck())
{
if(PropertyEnablePrefabUsage.boolValue)
{
m_bEnablePrefabUsage=true;
}
else
{
m_bDisablePrefabUsage=true;
}
}
}
else
{
if(PropertyExcludedFromTree.boolValue)
{
GUILayout.Label("Object has been excluded from mesh simplification.");
}
else
{
GUILayout.Label("Child MeshSimplify GameObject depending on "+meshSimplify.m_meshSimplifyRoot.name);
EditorGUILayout.PropertyField(PropertyOverrideRootSettings,newGUIContent("Override "+meshSimplify.m_meshSimplifyRoot.name+" settings","Will allow to edit this object's own parameters, instead of inheriting those of the root Automatic LOD GameObject"));
EditorGUILayout.PropertyField(PropertyUseEdgeLength,newGUIContent("Use Edge Length","Will take edge length into consideration when simplifying the mesh. Edges with higher length will be more likely to be kept"));
if(EditorGUI.EndChangeCheck())
{
PropertyDataDirty.boolValue=true;
}
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(PropertyUseCurvature,newGUIContent("Use Curvature","Will take the angle between triangles into consideration. Edges with smaller angles between two triangles will be more likely to be kept when simplifying the mesh."));
if(EditorGUI.EndChangeCheck())
{
PropertyDataDirty.boolValue=true;
}
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(PropertyProtectTexture,newGUIContent("Protect Texture","Will try to keep mapping integrity during the process of mesh simplification"));
if(EditorGUI.EndChangeCheck())
{
PropertyDataDirty.boolValue=true;
}
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(PropertyLockBorder,newGUIContent("Keep Borders","Will try to keep those vertices that form an object's border"));
if(EditorGUI.EndChangeCheck())
{
PropertyDataDirty.boolValue=true;
}
EditorGUILayout.Space();
floatfVertexAmount=EditorGUILayout.Slider(newGUIContent("Vertex %","The percentage of vertices from the original mesh to keep when simplifying it"),PropertyVertexAmount.floatValue*100.0f,0.0f,100.0f);
m_bPreviewOriginalMesh=EditorGUILayout.Toggle(newGUIContent("Preview Original Mesh","Allows to quickly switch between viewing the simplified mesh and the original mesh to check the reduction quality"),m_bPreviewOriginalMesh);
EditorGUILayout.HelpBox("Use vertex relevance spheres to select which vertices should be preserved with more or less priority when simplifying the mesh.",MessageType.Info);
EditorGUILayout.Space();
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
if(GUILayout.Button(newGUIContent("Add New Sphere","Adds a new vertex relevance sphere"),GUILayout.Width(nButtonWidthSmall)))
elementRelevance.floatValue=EditorGUILayout.Slider(newGUIContent("Relevance","Tells the simplification algorithm how relevant the vertices inside this sphere are. Default relevance is 0, use lower values to discard non important vertices, and higher values to keep them before others when simplifying the mesh"),elementRelevance.floatValue,-1.0f,1.0f);
if(EditorGUI.EndChangeCheck())
{
PropertyDataDirty.boolValue=true;
}
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
if(GUILayout.Button(newGUIContent("Remove Sphere","Removes this simplification sphere"),GUILayout.Width(nButtonWidthSmall)))
if(GUILayout.Button(newGUIContent("Compute mesh","Starts the mesh simplification process and assigns the GameObject the new simplified mesh"),GUILayout.Width(nButtonWidth)))
{
m_bComputeMesh=true;
}
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
if(GUILayout.Button(newGUIContent("Restore Original Mesh...","Deletes the simplified data and restores the original mesh"),GUILayout.Width(nButtonWidth)))
{
if(EditorUtility.DisplayDialog("Delete all data and restore original mesh?","Are you sure you want to delete all data and restore the original mesh?","Delete","Cancel"))
if(GUILayout.Button(newGUIContent("Exclude from tree...","Restores this GameObject's original mesh and excludes it from the mesh simplification tree"),GUILayout.Width(nButtonWidth)))
{
if(EditorUtility.DisplayDialog("Remove from tree?","Are you sure you want to restore this gameobject's mesh and exclude it from the tree?","Remove","Cancel"))
EditorUtility.DisplayDialog("Error","Object "+meshSimplify.name+" has no MeshFilter nor Skinned Mesh to process. Please use the \""+strIncludeChildrenLabel+"\" parameter if you want to process the whole "+meshSimplify.name+" hierarchy for meshes","OK");
strMeshAssetPath=UnityEditor.EditorUtility.SaveFilePanelInProject("Save mesh asset(s)","mesh_"+gameObject.name+gameObject.GetInstanceID().ToString()+".asset","asset","Please enter a file name to save the mesh asset(s) to");
if(strMeshAssetPath.Length==0)
{
//Debug.LogWarning("strMeshAssetPath.Length == 0. User cancelled?");
return;
}
//Debug.Log("User selected " + strMeshAssetPath + " using panel.");