Question by
Nathans_Codes · Nov 02, 2021 at 12:45 PM ·
editorgui
Custom Inspector Button crashes Unity
I am making a procedural Planet Generator, and I am running into a substansial problem.
I've made some custom buttons and a slider for the Inspector, and every time I press one of these buttons or change a value, Unity freezes a bit and then crashes. There are no Console errors though.
Here are the two planet generator scripts:
TerrainFace.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TerrainFace
{
Mesh mesh;
int resolution;
Vector3 localUp;
Vector3 axisA;
Vector3 axisB;
ShapeGenerator shapeGenerator;
public TerrainFace(ShapeGenerator shapeGenerator, Mesh mesh, int resolution, Vector3 localUp)
{
this.shapeGenerator = shapeGenerator;
this.mesh = mesh;
this.resolution = resolution;
this.localUp = localUp;
axisA = new Vector3(localUp.y, localUp.z, localUp.x);
axisB = Vector3.Cross(localUp, axisA);
}
public void ConstructMesh()
{
Vector3[] vertices = new Vector3[resolution * resolution];
int[] triangles = new int[(resolution-1) * (resolution-1) * 6];
int triIndex = 0;
for(int y = 0; y < resolution; y++)
{
for (int x = 0; x < resolution; x++)
{
int i = x + y * resolution;
Vector2 percent = new Vector2(x,y) / (resolution-1);
Vector3 pointOnUnitCube = localUp + (percent.x -.5f) * 2 * axisA + (percent.y-.5f) * 2 * axisB;
Vector3 pointOnUnitSphere = pointOnUnitCube.normalized;
vertices[i] = shapeGenerator.CalculatePointOnPlanet(pointOnUnitSphere);
if (x != resolution-1 && y!=resolution-1)
{
triangles[triIndex] = i;
triangles[triIndex + 1] = i + resolution + 1;
triangles[triIndex + 2] = i + resolution;
triangles[triIndex + 3] = i;
triangles[triIndex + 4] = i + 1;
triangles[triIndex + 5] = i + resolution + 1;
triIndex += 6;
}
}
}
mesh.Clear();
mesh.vertices = vertices;
mesh.triangles = triangles;
mesh.RecalculateNormals();
}
}
Planet.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Planet : MonoBehaviour
{
[Range(2, 256)]
public int resolution = 10;
public bool autoUpdate = true;
public ShapeSettings shapeSettings;
public ColorSettings colorSettings;
[HideInInspector]
public bool shapeSettingsFoldout;
[HideInInspector]
public bool colorSettingsFoldout;
ShapeGenerator shapeGenerator;
[SerializeField, HideInInspector]
MeshFilter[] meshFilters;
TerrainFace[] terrainFaces;
void Initialize()
{
shapeGenerator = new ShapeGenerator(shapeSettings);
if (meshFilters == null || meshFilters.Length == 0) {meshFilters = new MeshFilter[6];}
terrainFaces = new TerrainFace[6];
Vector3[] directions = {Vector3.up, Vector3.down, Vector3.left, Vector3.right, Vector3.forward, Vector3.back};
for (int i = 0; i < 6; i++)
{
if (meshFilters[i] == null)
{
GameObject meshObj = new GameObject("mesh");
meshObj.transform.parent = transform;
meshObj.AddComponent<MeshRenderer>().sharedMaterial = new Material(Shader.Find("Standard"));
meshFilters[i] = meshObj.AddComponent<MeshFilter>();
meshFilters[i].sharedMesh = new Mesh();
}
terrainFaces[i] = new TerrainFace(shapeGenerator, meshFilters[i].sharedMesh, resolution, directions[i]);
}
}
public void GeneratePlanet()
{
Initialize();
GenerateMesh();
GeneratePlanet();
}
public void OnShapeSetingsUpdate()
{
if (autoUpdate)
{
Initialize();
GenerateMesh();
}
}
public void OnColorSettingsUpdate()
{
if (autoUpdate)
{
Initialize();
GenerateColors();
}
}
void GenerateMesh()
{
foreach(TerrainFace face in terrainFaces)
{
if (face != null) {face.ConstructMesh();}
}
}
void GenerateColors()
{
foreach (MeshFilter m in meshFilters)
{
m.GetComponent<MeshRenderer>().sharedMaterial.color = colorSettings.planetColor;
}
}
}
And here's the Editor Script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(Planet))]
public class PlanetEditor : Editor
{
Planet planet;
Editor shapeEditor;
Editor colorEditor;
public override void OnInspectorGUI()
{
using (var check = new EditorGUI.ChangeCheckScope())
{
base.OnInspectorGUI();
if (check.changed)
{
planet.GeneratePlanet();
}
}
if (GUILayout.Button("Generate Planet"))
{
planet.GeneratePlanet();
}
DrawSettingsEditor(planet.shapeSettings, planet.OnShapeSetingsUpdate, ref planet.shapeSettingsFoldout, ref shapeEditor);
DrawSettingsEditor(planet.colorSettings, planet.OnColorSettingsUpdate, ref planet.colorSettingsFoldout, ref colorEditor);
}
void DrawSettingsEditor(Object settings, System.Action onSettingsUpdated, ref bool foldout, ref Editor editor)
{
if (settings != null)
{
foldout = EditorGUILayout.InspectorTitlebar(foldout, settings);
using (var check = new EditorGUI.ChangeCheckScope())
{
if (foldout)
{
CreateCachedEditor(settings, null, ref editor);
editor.OnInspectorGUI();
if (check.changed)
{
if (onSettingsUpdated != null)
{
onSettingsUpdated();
}
}
}
}
}
}
private void OnEnable()
{
planet = (Planet)target;
}
}
Can anyone help me here?
Comment
Your answer
Follow this Question
Related Questions
Components can finally be rearranged with the mouse, but since when? 1 Answer
Webview in custom Unity Editor Window? 0 Answers
Drawing a Mesh from an EditorTool 0 Answers
Create a greyed out value field in the editor? 2 Answers
,My Unity Editor is blurry 0 Answers