diff --git a/spine-unity/Assets/spine-unity/Mesh Generation/Arrays/ArraysSubmeshedMeshGenerator.cs b/spine-unity/Assets/spine-unity/Mesh Generation/Arrays/ArraysSubmeshedMeshGenerator.cs
index 2dd4c3903..6c9ef8d57 100644
--- a/spine-unity/Assets/spine-unity/Mesh Generation/Arrays/ArraysSubmeshedMeshGenerator.cs
+++ b/spine-unity/Assets/spine-unity/Mesh Generation/Arrays/ArraysSubmeshedMeshGenerator.cs
@@ -119,7 +119,7 @@ namespace Spine.Unity.MeshGeneration {
startSlot = submeshStartSlotIndex,
endSlot = i,
firstVertexIndex = submeshFirstVertex,
- separatedBySlot = separatedBySlot
+ forceSeparate = separatedBySlot
}
);
@@ -147,7 +147,7 @@ namespace Spine.Unity.MeshGeneration {
startSlot = submeshStartSlotIndex,
endSlot = drawOrderCount,
firstVertexIndex = submeshFirstVertex,
- separatedBySlot = false
+ forceSeparate = false
}
);
diff --git a/spine-unity/Assets/spine-unity/Mesh Generation/ISubmeshedMeshGenerator.cs b/spine-unity/Assets/spine-unity/Mesh Generation/ISubmeshedMeshGenerator.cs
index 3662f3aac..285653ad7 100644
--- a/spine-unity/Assets/spine-unity/Mesh Generation/ISubmeshedMeshGenerator.cs
+++ b/spine-unity/Assets/spine-unity/Mesh Generation/ISubmeshedMeshGenerator.cs
@@ -51,7 +51,7 @@ namespace Spine.Unity.MeshGeneration {
// Vertex index offset. Used by submesh generation if part of a bigger mesh.
public int firstVertexIndex;
- public bool separatedBySlot;
+ public bool forceSeparate;
/// The number of slots in this SubmeshInstruction's range. Not necessarily the number of attachments.
public int SlotCount { get { return endSlot - startSlot; } }
diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Editor/SkeletonGraphicInspector.cs b/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Editor/SkeletonGraphicInspector.cs
index 639b9af05..3f80d3efc 100644
--- a/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Editor/SkeletonGraphicInspector.cs
+++ b/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Editor/SkeletonGraphicInspector.cs
@@ -36,10 +36,10 @@ using UnityEngine;
using UnityEditor;
using Spine;
-namespace Spine.Unity {
+namespace Spine.Unity.Editor {
[CustomEditor(typeof(SkeletonGraphic))]
- public class SkeletonGraphicInspector : Editor {
+ public class SkeletonGraphicInspector : UnityEditor.Editor {
SerializedProperty material_, color_;
SerializedProperty skeletonDataAsset_, initialSkinName_;
SerializedProperty startingAnimation_, startingLoop_, timeScale_, freeze_;
@@ -133,7 +133,7 @@ namespace Spine.Unity {
}
}
- [MenuItem("GameObject/Spine/SkeletonGraphic (UnityUI)", false, 10)]
+ [MenuItem("GameObject/Spine/SkeletonGraphic (UnityUI)", false, 15)]
static public void SkeletonGraphicCreateMenuItem () {
var parentGameObject = Selection.activeObject as GameObject;
var parentTransform = parentGameObject == null ? null : parentGameObject.GetComponent();
@@ -149,7 +149,7 @@ namespace Spine.Unity {
EditorGUIUtility.PingObject(Selection.activeObject);
}
- [MenuItem("Assets/Spine/Instantiate (UnityUI)", false, 10)]
+ [MenuItem("Assets/Spine/Instantiate (UnityUI)", false, 20)]
static void InstantiateSkeletonGraphic () {
Object[] arr = Selection.objects;
foreach (Object o in arr) {
@@ -161,7 +161,7 @@ namespace Spine.Unity {
}
}
- [MenuItem("Assets/Spine/Instantiate (UnityUI)", true, 10)]
+ [MenuItem("Assets/Spine/Instantiate (UnityUI)", true, 20)]
static bool ValidateInstantiateSkeletonGraphic () {
Object[] arr = Selection.objects;
diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonRenderSeparator/Editor/SkeletonPartsRendererInspector.cs b/spine-unity/Assets/spine-unity/Modules/SkeletonRenderSeparator/Editor/SkeletonPartsRendererInspector.cs
index fe9afbd72..15db2ef77 100644
--- a/spine-unity/Assets/spine-unity/Modules/SkeletonRenderSeparator/Editor/SkeletonPartsRendererInspector.cs
+++ b/spine-unity/Assets/spine-unity/Modules/SkeletonRenderSeparator/Editor/SkeletonPartsRendererInspector.cs
@@ -3,17 +3,19 @@ using System.Collections;
using UnityEditor;
using Spine.Unity;
-[CustomEditor(typeof(SkeletonPartsRenderer))]
-public class SkeletonRenderPartInspector : Editor {
- SpineInspectorUtility.SerializedSortingProperties sortingProperties;
+namespace Spine.Unity.Editor {
+ [CustomEditor(typeof(SkeletonPartsRenderer))]
+ public class SkeletonRenderPartInspector : UnityEditor.Editor {
+ SpineInspectorUtility.SerializedSortingProperties sortingProperties;
- void OnEnable () {
- var component = target as Component;
- sortingProperties = new SpineInspectorUtility.SerializedSortingProperties(component.GetComponent());
+ void OnEnable () {
+ sortingProperties = new SpineInspectorUtility.SerializedSortingProperties((target as Component).GetComponent());
+ }
+
+ public override void OnInspectorGUI () {
+ DrawDefaultInspector();
+ SpineInspectorUtility.SortingPropertyFields(sortingProperties, true);
+ }
}
- public override void OnInspectorGUI () {
- DrawDefaultInspector();
- SpineInspectorUtility.SortingPropertyFields(sortingProperties, true);
- }
}
diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonRenderSeparator/Editor/SkeletonRenderSeparatorInspector.cs b/spine-unity/Assets/spine-unity/Modules/SkeletonRenderSeparator/Editor/SkeletonRenderSeparatorInspector.cs
index 3ce84e85a..95eb165f4 100644
--- a/spine-unity/Assets/spine-unity/Modules/SkeletonRenderSeparator/Editor/SkeletonRenderSeparatorInspector.cs
+++ b/spine-unity/Assets/spine-unity/Modules/SkeletonRenderSeparator/Editor/SkeletonRenderSeparatorInspector.cs
@@ -1,20 +1,22 @@
using UnityEngine;
using UnityEditor;
-namespace Spine.Unity {
+using Spine.Unity;
+
+namespace Spine.Unity.Editor {
[CustomEditor(typeof(SkeletonRenderSeparator))]
- public class SkeletonRenderSeparatorInspector : Editor {
+ public class SkeletonRenderSeparatorInspector : UnityEditor.Editor {
SkeletonRenderSeparator component;
// Properties
SerializedProperty skeletonRenderer_, copyPropertyBlock_, copyMeshRendererFlags_, partsRenderers_;
+ static bool partsRenderersExpanded = false;
// For separator field.
SerializedObject skeletonRendererSerializedObject;
SerializedProperty separatorNamesProp;
- bool separatorExpanded = true;
- System.Func Plural = SpineInspectorUtility.Pluralize;
+ static bool skeletonRendererExpanded = true;
void OnEnable () {
if (component == null)
@@ -23,14 +25,28 @@ namespace Spine.Unity {
skeletonRenderer_ = serializedObject.FindProperty("skeletonRenderer");
copyPropertyBlock_ = serializedObject.FindProperty("copyPropertyBlock");
copyMeshRendererFlags_ = serializedObject.FindProperty("copyMeshRendererFlags");
+
+ var partsRenderers = component.partsRenderers;
partsRenderers_ = serializedObject.FindProperty("partsRenderers");
- partsRenderers_.isExpanded = true;
+ partsRenderers_.isExpanded = partsRenderersExpanded || // last state
+ partsRenderers.Contains(null) || // null items found
+ partsRenderers.Count < 1 || // no parts renderers
+ (skeletonRenderer_.objectReferenceValue != null && SkeletonRendererSeparatorCount + 1 > partsRenderers.Count); // not enough parts renderers
+ }
+
+ int SkeletonRendererSeparatorCount {
+ get {
+ if (Application.isPlaying) {
+ return component.SkeletonRenderer.separatorSlots.Count;
+ } else {
+ return separatorNamesProp == null ? 0 : separatorNamesProp.arraySize;
+ }
+ }
}
public override void OnInspectorGUI () {
// TODO: Add Undo support
var componentRenderers = component.partsRenderers;
- int separatorCount = 0;
int totalParts;
bool componentEnabled = component.enabled;
@@ -42,6 +58,7 @@ namespace Spine.Unity {
EditorGUILayout.PropertyField(copyPropertyBlock_);
EditorGUILayout.PropertyField(copyMeshRendererFlags_);
+ // SkeletonRenderer Box
using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox)) {
// Fancy SkeletonRenderer foldout reference field
{
@@ -52,14 +69,15 @@ namespace Spine.Unity {
if (EditorGUI.EndChangeCheck())
serializedObject.ApplyModifiedProperties();
if (component.SkeletonRenderer != null) {
- separatorExpanded = EditorGUI.Foldout(foldoutSkeletonRendererRect, separatorExpanded, "");
+ skeletonRendererExpanded = EditorGUI.Foldout(foldoutSkeletonRendererRect, skeletonRendererExpanded, "");
}
EditorGUI.indentLevel--;
}
+ int separatorCount = 0;
EditorGUI.BeginChangeCheck();
if (component.SkeletonRenderer != null) {
- // SubmeshSeparators from SkeletonRenderer
+ // Separators from SkeletonRenderer
{
bool skeletonRendererMismatch = skeletonRendererSerializedObject != null && skeletonRendererSerializedObject.targetObject != component.SkeletonRenderer;
if (separatorNamesProp == null || skeletonRendererMismatch) {
@@ -71,21 +89,16 @@ namespace Spine.Unity {
}
if (separatorNamesProp != null) {
- if (separatorExpanded) {
+ if (skeletonRendererExpanded) {
EditorGUI.indentLevel++;
SkeletonRendererInspector.SeparatorsField(separatorNamesProp);
EditorGUI.indentLevel--;
}
-
- if (Application.isPlaying)
- separatorCount = component.SkeletonRenderer.separatorSlots.Count;
- else
- separatorCount = separatorNamesProp.arraySize;
-
+ separatorCount = this.SkeletonRendererSeparatorCount;
}
}
- if (separatorCount == 0) {
+ 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);
}
}
@@ -93,8 +106,8 @@ namespace Spine.Unity {
skeletonRendererSerializedObject.ApplyModifiedProperties();
totalParts = separatorCount + 1;
- var counterStyle = separatorExpanded ? EditorStyles.label : EditorStyles.miniLabel;
- EditorGUILayout.LabelField(string.Format("{0}: separates into {1}.", Plural(separatorCount, "separator", "separators"), Plural(totalParts, "part", "parts") ), counterStyle);
+ 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
@@ -103,6 +116,11 @@ namespace Spine.Unity {
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;
@@ -110,39 +128,40 @@ namespace Spine.Unity {
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));
- //var addMissingContentButtonContent = new GUIContent("Add", GUIUtility.)
if (GUILayout.Button(addMissingLabel, GUILayout.Height(40f))) {
AddPartsRenderer(extraRenderersNeeded);
DetectOrphanedPartsRenderers(component);
}
}
}
-
- 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?
- if (EditorUtility.DisplayDialog("Destroy Renderers", "Do you really want to destroy all the Parts Renderer GameObjects in the list? (Undo will not work.)", "Destroy", "Cancel")) {
- foreach (var r in componentRenderers) {
- if (r != null)
- DestroyImmediate(r.gameObject, allowDestroyingAssets: false);
+
+ 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?
+ if (EditorUtility.DisplayDialog("Destroy Renderers", "Do you really want to destroy all the Parts Renderer GameObjects in the list? (Undo will not work.)", "Destroy", "Cancel")) {
+ foreach (var r in componentRenderers) {
+ if (r != null)
+ DestroyImmediate(r.gameObject, allowDestroyingAssets: false);
+ }
+ componentRenderers.Clear();
+ // Do you also want to destroy orphans? (You monster.)
+ DetectOrphanedPartsRenderers(component);
}
- componentRenderers.Clear();
- // Do you also want to destroy orphans? (You monster.)
- DetectOrphanedPartsRenderers(component);
}
}
- }
- // (Button) Add Part Renderer button
- if (GUILayout.Button("Add (1) Parts Renderer"))
- AddPartsRenderer(1);
+ // (Button) Add Part Renderer button
+ if (GUILayout.Button("Add Parts Renderer"))
+ AddPartsRenderer(1);
+ }
}
}
@@ -151,7 +170,7 @@ namespace Spine.Unity {
public void AddPartsRenderer (int count) {
var componentRenderers = component.partsRenderers;
- bool emptyFound = componentRenderers.Exists(x => x == null);
+ bool emptyFound = componentRenderers.Contains(null);
if (emptyFound) {
bool userClearEntries = EditorUtility.DisplayDialog("Empty entries found", "Null entries found. Do you want to remove null entries before adding the new renderer? ", "Clear Empty Entries", "Don't Clear");
if (userClearEntries) componentRenderers.RemoveAll(x => x == null);
@@ -164,20 +183,17 @@ namespace Spine.Unity {
EditorGUIUtility.PingObject(smr);
// increment renderer sorting order.
- if (index != 0) {
- var prev = componentRenderers[index - 1];
- if (prev != null) {
- var prevMeshRenderer = prev.GetComponent();
- var currentMeshRenderer = smr.GetComponent();
- if (prevMeshRenderer != null && currentMeshRenderer != null) {
- int prevSortingLayer = prevMeshRenderer.sortingLayerID;
- int prevSortingOrder = prevMeshRenderer.sortingOrder;
+ if (index == 0) continue;
+ var prev = componentRenderers[index - 1]; if (prev == null) continue;
- currentMeshRenderer.sortingLayerID = prevSortingLayer;
- currentMeshRenderer.sortingOrder = prevSortingOrder + SkeletonRenderSeparator.DefaultSortingOrderIncrement;
- }
- }
- }
+ var prevMeshRenderer = prev.GetComponent();
+ var currentMeshRenderer = smr.GetComponent();
+ if (prevMeshRenderer == null || currentMeshRenderer == null) continue;
+
+ int prevSortingLayer = prevMeshRenderer.sortingLayerID;
+ int prevSortingOrder = prevMeshRenderer.sortingOrder;
+ currentMeshRenderer.sortingLayerID = prevSortingLayer;
+ currentMeshRenderer.sortingOrder = prevSortingOrder + SkeletonRenderSeparator.DefaultSortingOrderIncrement;
}
}
@@ -188,9 +204,8 @@ namespace Spine.Unity {
var orphans = new System.Collections.Generic.List();
foreach (var r in children) {
- if (!component.partsRenderers.Contains(r)) {
+ if (!component.partsRenderers.Contains(r))
orphans.Add(r);
- }
}
if (orphans.Count > 0) {
@@ -202,7 +217,6 @@ namespace Spine.Unity {
}
}
-
#region SkeletonRenderer Context Menu Item
[MenuItem ("CONTEXT/SkeletonRenderer/Add Skeleton Render Separator")]
static void AddRenderSeparatorComponent (MenuCommand cmd) {
diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonRenderSeparator/SkeletonRenderSeparator.cs b/spine-unity/Assets/spine-unity/Modules/SkeletonRenderSeparator/SkeletonRenderSeparator.cs
index 21053876e..29bee2a67 100644
--- a/spine-unity/Assets/spine-unity/Modules/SkeletonRenderSeparator/SkeletonRenderSeparator.cs
+++ b/spine-unity/Assets/spine-unity/Modules/SkeletonRenderSeparator/SkeletonRenderSeparator.cs
@@ -5,8 +5,8 @@ using Spine.Unity;
namespace Spine.Unity {
- [HelpURL("")]
[ExecuteInEditMode]
+ [HelpURL("https://github.com/pharan/spine-unity-docs/blob/master/SkeletonRenderSeparator.md")]
public class SkeletonRenderSeparator : MonoBehaviour {
public const int DefaultSortingOrderIncrement = 5;
@@ -17,7 +17,7 @@ namespace Spine.Unity {
get { return skeletonRenderer; }
set {
if (skeletonRenderer != null)
- skeletonRenderer.GenerateMeshOverride -= SeparateSkeletonRender;
+ skeletonRenderer.GenerateMeshOverride -= HandleRender;
skeletonRenderer = value;
this.enabled = false; // Disable if nulled.
@@ -26,6 +26,7 @@ namespace Spine.Unity {
MeshRenderer mainMeshRenderer;
public bool copyPropertyBlock = false;
+ [Tooltip("Copies MeshRenderer flags into ")]
public bool copyMeshRendererFlags = false;
public List partsRenderers = new List();
@@ -42,13 +43,28 @@ namespace Spine.Unity {
if (block == null) block = new MaterialPropertyBlock();
mainMeshRenderer = skeletonRenderer.GetComponent();
- skeletonRenderer.GenerateMeshOverride -= SeparateSkeletonRender;
- skeletonRenderer.GenerateMeshOverride += SeparateSkeletonRender;
+ skeletonRenderer.GenerateMeshOverride -= HandleRender;
+ skeletonRenderer.GenerateMeshOverride += HandleRender;
+
+ if (copyMeshRendererFlags) {
+ bool useLightProbes = mainMeshRenderer.useLightProbes;
+ bool receiveShadows = mainMeshRenderer.receiveShadows;
+
+ for (int i = 0; i < partsRenderers.Count; i++) {
+ var currentRenderer = partsRenderers[i];
+ if (currentRenderer == null) continue; // skip null items.
+
+ var mr = currentRenderer.MeshRenderer;
+ mr.useLightProbes = useLightProbes;
+ mr.receiveShadows = receiveShadows;
+ }
+ }
+
}
void OnDisable () {
if (skeletonRenderer == null) return;
- skeletonRenderer.GenerateMeshOverride -= SeparateSkeletonRender;
+ skeletonRenderer.GenerateMeshOverride -= HandleRender;
#if UNITY_EDITOR
skeletonRenderer.LateUpdate();
@@ -60,7 +76,7 @@ namespace Spine.Unity {
MaterialPropertyBlock block;
- void SeparateSkeletonRender (SkeletonRenderer.SmartMesh.Instruction instruction) {
+ void HandleRender (SkeletonRenderer.SmartMesh.Instruction instruction) {
int rendererCount = partsRenderers.Count;
if (rendererCount <= 0) return;
@@ -75,24 +91,11 @@ namespace Spine.Unity {
var currentRenderer = partsRenderers[rendererIndex];
bool skeletonRendererCalculateNormals = skeletonRenderer.calculateNormals;
-
- bool useLightProbes = false;
- bool receiveShadows = false;
-
- if (copyMeshRendererFlags) {
- useLightProbes = mainMeshRenderer.useLightProbes;
- receiveShadows = mainMeshRenderer.receiveShadows;
- }
for (int i = 0, start = 0; i <= lastSubmeshInstruction; i++) {
- if (submeshInstructionsItems[i].separatedBySlot) {
+ if (submeshInstructionsItems[i].forceSeparate) {
currentRenderer.RenderParts(instruction.submeshInstructions, start, i + 1);
currentRenderer.MeshGenerator.GenerateNormals = skeletonRendererCalculateNormals;
- if (copyMeshRendererFlags) {
- var mr = currentRenderer.MeshRenderer;
- mr.useLightProbes = useLightProbes;
- mr.receiveShadows = receiveShadows;
- }
if (copyPropertyBlock)
currentRenderer.SetPropertyBlock(block);
@@ -107,19 +110,13 @@ namespace Spine.Unity {
} else if (i == lastSubmeshInstruction) {
currentRenderer.RenderParts(instruction.submeshInstructions, start, i + 1);
currentRenderer.MeshGenerator.GenerateNormals = skeletonRendererCalculateNormals;
- if (copyMeshRendererFlags) {
- var mr = currentRenderer.MeshRenderer;
- mr.useLightProbes = useLightProbes;
- mr.receiveShadows = receiveShadows;
- }
if (copyPropertyBlock)
currentRenderer.SetPropertyBlock(block);
-
- rendererIndex++;
}
}
-
- // Too many renderers. Clear the rest.
+
+ // If too many renderers. Clear the rest.
+ rendererIndex++;
if (rendererIndex < rendererCount - 1) {
for (int i = rendererIndex; i < rendererCount; i++) {
currentRenderer = partsRenderers[i];