public override void OnInspectorGUI()
{
// Restore mesh part for undo logic after undo of "Add Parts Renderer".
// Triggers regeneration and assignment of the mesh filter's mesh.
if (component.GetComponent <MeshFilter>() && component.GetComponent <MeshFilter>().sharedMesh == null)
{
component.OnDisable();
component.OnEnable();
}
var componentRenderers = component.partsRenderers;
int totalParts;
using (new SpineInspectorUtility.LabelWidthScope()) {
bool componentEnabled = component.enabled;
bool checkBox = EditorGUILayout.Toggle("Enable Separator", componentEnabled);
if (checkBox != componentEnabled)
{
component.enabled = checkBox;
}
if (component.SkeletonRenderer.disableRenderingOnOverride && !component.enabled)
{
EditorGUILayout.HelpBox("By default, SkeletonRenderer's MeshRenderer is disabled while the SkeletonRenderSeparator takes over rendering. It is re-enabled when SkeletonRenderSeparator is disabled.", MessageType.Info);
}
EditorGUILayout.PropertyField(copyPropertyBlock_);
EditorGUILayout.PropertyField(copyMeshRendererFlags_);
}
// SkeletonRenderer Box
using (new SpineInspectorUtility.BoxScope(false)) {
// Fancy SkeletonRenderer foldout reference field
{
EditorGUI.indentLevel++;
EditorGUI.BeginChangeCheck();
var foldoutSkeletonRendererRect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight);
EditorGUI.PropertyField(foldoutSkeletonRendererRect, skeletonRenderer_);
if (EditorGUI.EndChangeCheck())
{
serializedObject.ApplyModifiedProperties();
}
if (component.SkeletonRenderer != null)
{
skeletonRendererExpanded = EditorGUI.Foldout(foldoutSkeletonRendererRect, skeletonRendererExpanded, "");
}
EditorGUI.indentLevel--;
}
int separatorCount = 0;
EditorGUI.BeginChangeCheck();
if (component.SkeletonRenderer != null)
{
// Separators from SkeletonRenderer
{
bool skeletonRendererMismatch = skeletonRendererSerializedObject != null && skeletonRendererSerializedObject.targetObject != component.SkeletonRenderer;
if (separatorNamesProp == null || skeletonRendererMismatch)
{
if (component.SkeletonRenderer != null)
{
skeletonRendererSerializedObject = new SerializedObject(component.SkeletonRenderer);
separatorNamesProp = skeletonRendererSerializedObject.FindProperty("separatorSlotNames");
separatorNamesProp.isExpanded = true;
}
}
if (separatorNamesProp != null)
{
if (skeletonRendererExpanded)
{
EditorGUI.indentLevel++;
SkeletonRendererInspector.SeparatorsField(separatorNamesProp);
EditorGUI.indentLevel--;
}
separatorCount = this.SkeletonRendererSeparatorCount;
}
}
if (SkeletonRendererSeparatorCount == 0)
{
EditorGUILayout.HelpBox("Separators are empty. Change the size to 1 and choose a slot if you want the render to be separated.", MessageType.Info);
}
}
if (EditorGUI.EndChangeCheck())
{
skeletonRendererSerializedObject.ApplyModifiedProperties();
if (!Application.isPlaying)
{
slotsReapplyRequired = true;
}
}
totalParts = separatorCount + 1;
var counterStyle = skeletonRendererExpanded ? EditorStyles.label : EditorStyles.miniLabel;
EditorGUILayout.LabelField(string.Format("{0}: separates into {1}.", SpineInspectorUtility.Pluralize(separatorCount, "separator", "separators"), SpineInspectorUtility.Pluralize(totalParts, "part", "parts")), counterStyle);
}
// Parts renderers
using (new SpineInspectorUtility.BoxScope(false)) {
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(this.partsRenderers_, true);
EditorGUI.indentLevel--;
// Null items warning
bool nullItemsFound = componentRenderers.Contains(null);
if (nullItemsFound)
{
EditorGUILayout.HelpBox("Some items in the parts renderers list are null and may cause problems.\n\nYou can right-click on that element and choose 'Delete Array Element' to remove it.", MessageType.Warning);
}
// (Button) Match Separators count
if (separatorNamesProp != null)
{
int currentRenderers = 0;
foreach (var r in componentRenderers)
{
if (r != null)
{
currentRenderers++;
}
}
int extraRenderersNeeded = totalParts - currentRenderers;
if (component.enabled && component.SkeletonRenderer != null && extraRenderersNeeded > 0)
{
EditorGUILayout.HelpBox(string.Format("Insufficient parts renderers. Some parts will not be rendered."), MessageType.Warning);
string addMissingLabel = string.Format("Add the missing renderer{1} ({0}) ", extraRenderersNeeded, SpineInspectorUtility.PluralThenS(extraRenderersNeeded));
if (GUILayout.Button(addMissingLabel, GUILayout.Height(40f)))
{
AddPartsRenderer(extraRenderersNeeded);
DetectOrphanedPartsRenderers(component);
partsRendererInitRequired = true;
}
}
}
if (partsRenderers_.isExpanded != partsRenderersExpanded)
{
partsRenderersExpanded = partsRenderers_.isExpanded;
}
if (partsRenderers_.isExpanded)
{
using (new EditorGUILayout.HorizontalScope()) {
// (Button) Destroy Renderers button
if (componentRenderers.Count > 0)
{
if (GUILayout.Button("Clear Parts Renderers"))
{
// Do you really want to destroy all?
Undo.RegisterCompleteObjectUndo(component, "Clear Parts Renderers");
if (EditorUtility.DisplayDialog("Destroy Renderers", "Do you really want to destroy all the Parts Renderer GameObjects in the list?", "Destroy", "Cancel"))
{
foreach (var r in componentRenderers)
{
if (r != null)
{
Undo.DestroyObjectImmediate(r.gameObject);
}
}
componentRenderers.Clear();
// Do you also want to destroy orphans? (You monster.)
DetectOrphanedPartsRenderers(component);
}
}
}
// (Button) Add Part Renderer button
if (GUILayout.Button("Add Parts Renderer"))
{
AddPartsRenderer(1);
partsRendererInitRequired = true;
}
}
}
}
serializedObject.ApplyModifiedProperties();
if (partsRendererInitRequired)
{
Undo.RegisterCompleteObjectUndo(component.GetComponent <MeshRenderer>(), "Add Parts Renderers");
component.OnEnable();
partsRendererInitRequired = false;
}
if (slotsReapplyRequired && UnityEngine.Event.current.type == EventType.Repaint)
{
component.SkeletonRenderer.ReapplySeparatorSlotNames();
component.SkeletonRenderer.LateUpdate();
SceneView.RepaintAll();
slotsReapplyRequired = false;
}
}