Pārlūkot izejas kodu

Merge remote-tracking branch 'origin/master'

NathanSweet 8 gadi atpakaļ
vecāks
revīzija
65982c7eca

+ 1 - 1
spine-csharp/src/Animation.cs

@@ -581,7 +581,7 @@ namespace Spine {
 			}
 
 			float[] frames = this.frames;
-			if (time < frames[0]) {
+			if (time < frames[0]) { // Time is before first frame.
 				if (setupPose) {
 					attachmentName = slot.data.attachmentName;
 					slot.Attachment = attachmentName == null ? null : skeleton.GetAttachment(slotIndex, attachmentName);

+ 2 - 2
spine-csharp/src/AnimationState.cs

@@ -228,7 +228,7 @@ namespace Spine {
 				if (rotateTimeline != null) {
 					ApplyRotateTimeline(rotateTimeline, skeleton, animationTime, alpha, setupPose, timelinesRotation, i << 1, firstFrame);
 				} else {
-					if (setupPose) {
+					if (!setupPose) {
 						if (!attachments && timeline is AttachmentTimeline) continue;
 						if (!drawOrder && timeline is DrawOrderTimeline) continue;
 					}
@@ -236,7 +236,7 @@ namespace Spine {
 				}
 			}
 
-			QueueEvents(entry, animationTime);
+			QueueEvents(from, animationTime);
 			from.nextAnimationLast = animationTime;
 			from.nextTrackLast = from.trackTime;
 

+ 3 - 3
spine-csharp/src/SkeletonBounds.cs

@@ -82,7 +82,7 @@ namespace Spine {
 			}
 
 			if (updateAabb) {
-				aabbCompute();
+				AabbCompute();
 			} else {
 				minX = int.MinValue;
 				minY = int.MinValue;
@@ -91,7 +91,7 @@ namespace Spine {
 			}
 		}
 
-		private void aabbCompute () {
+		private void AabbCompute () {
 			float minX = int.MaxValue, minY = int.MaxValue, maxX = int.MinValue, maxY = int.MinValue;
 			ExposedList<Polygon> polygons = Polygons;
 			for (int i = 0, n = polygons.Count; i < n; i++) {
@@ -204,7 +204,7 @@ namespace Spine {
 			return false;
 		}
 
-		public Polygon getPolygon (BoundingBoxAttachment attachment) {
+		public Polygon GetPolygon (BoundingBoxAttachment attachment) {
 			int index = BoundingBoxes.IndexOf(attachment);
 			return index == -1 ? null : Polygons.Items[index];
 		}

+ 6 - 6
spine-unity/Assets/spine-unity/Asset Types/Editor/SkeletonDataAssetInspector.cs

@@ -263,12 +263,12 @@ namespace Spine.Unity.Editor {
 			if (isBakingExpanded) {
 				EditorGUI.indentLevel++;
 				const string BakingWarningMessage =
-					"WARNING!" +
-					"\nBaking is NOT the same as SkeletonAnimator!" +
+//					"WARNING!" +
+//					"\nBaking is NOT the same as SkeletonAnimator!" +
+//					"\n\n" + 
+					"The main use of Baking is to export Spine projects to be used without the Spine Runtime (ie: for sale on the Asset Store, or background objects that are animated only with a wind noise generator)" +
 
-					"\n\nThe main use of Baking is to export Spine projects to be used without the Spine Runtime (ie: for sale on the Asset Store, or background objects that are animated only with a wind noise generator)" +
-
-					"\n\nBaking also does not support the following:" +
+					"\n\nBaking does not support the following:" +
 					"\n\tDisabled transform inheritance" +
 					"\n\tShear" +
 					"\n\tColor Keys" +
@@ -277,7 +277,7 @@ namespace Spine.Unity.Editor {
 
 					"\n\nCurves are sampled at 60fps and are not realtime." +
 					"\nPlease read SkeletonBaker.cs comments for full details.";
-				EditorGUILayout.HelpBox(BakingWarningMessage, MessageType.Warning, true);
+				EditorGUILayout.HelpBox(BakingWarningMessage, MessageType.Info, true);
 
 				EditorGUI.indentLevel++;
 				bakeAnimations = EditorGUILayout.Toggle("Bake Animations", bakeAnimations);

+ 2 - 0
spine-unity/Assets/spine-unity/Editor/SpineEditorUtilities.cs

@@ -28,6 +28,8 @@
  * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
+#pragma warning disable 0219
+
 // Contributed by: Mitch Thompson
 
 #define SPINE_SKELETONANIMATOR

+ 233 - 251
spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/Editor/SpineSpriteShaderGUI.cs

@@ -32,6 +32,8 @@ using System;
 using UnityEngine;
 using UnityEditor;
 
+using SpineInspectorUtility = Spine.Unity.Editor.SpineInspectorUtility;
+
 public class SpineSpriteShaderGUI : ShaderGUI {
 	static readonly string kShaderVertexLit = "Spine/Sprite/Vertex Lit";
 	static readonly string kShaderPixelLit = "Spine/Sprite/Pixel Lit";
@@ -90,9 +92,10 @@ public class SpineSpriteShaderGUI : ShaderGUI {
 	//Blend texture
 	MaterialProperty _blendTexture = null;
 	MaterialProperty _blendTextureLerp = null;
-	
+
 	bool _firstTimeApply = true;
 	eLightMode _lightMode;
+	static bool showAdvanced = false;
 
 	#region ShaderGUI
 	public override void OnGUI (MaterialEditor materialEditor, MaterialProperty[] properties)	{
@@ -119,14 +122,14 @@ public class SpineSpriteShaderGUI : ShaderGUI {
 	#endregion
 
 	#region Virtual Interface
-	protected virtual void FindProperties(MaterialProperty[] props) {
+	protected virtual void FindProperties (MaterialProperty[] props) {
 		_mainTexture = FindProperty("_MainTex", props);
 		_color = FindProperty("_Color", props);
 		_blendMode = FindProperty("_BlendMode", props);
 
 		_emissionMap = FindProperty("_EmissionMap", props, false);
 		_emissionColor = FindProperty("_EmissionColor", props, false);
-		_emissionPower = FindProperty("_EmissionPower", props, false);		
+		_emissionPower = FindProperty("_EmissionPower", props, false);
 
 		_writeToDepth = FindProperty("_ZWrite", props);
 		_depthAlphaCutoff = FindProperty("_Cutoff", props);
@@ -149,259 +152,204 @@ public class SpineSpriteShaderGUI : ShaderGUI {
 		_rimColor = FindProperty("_RimColor", props, false);
 	}
 
-	protected virtual void ShaderPropertiesGUI(Material material) {
-		// Use default labelWidth
-		EditorGUIUtility.labelWidth = 0f;
+	protected virtual void ShaderPropertiesGUI (Material material) {
+		using (new EditorGUILayout.HorizontalScope()) {
+			GUILayout.FlexibleSpace();
+			var showAdvancedLabel = new GUIContent("Show Advanced", "Show extra options under all sections. This only affects the inspector. The Material's resulting shader is still compiled/optimized based on what features you actually use and don't use.");
+			float lw = GUI.skin.toggle.CalcSize(showAdvancedLabel).x;
+
+			EditorGUIUtility.labelWidth = lw;
+			showAdvanced = EditorGUILayout.Toggle(showAdvancedLabel, showAdvanced);
+			EditorGUIUtility.labelWidth = 0f;
+		}
+
+		EditorGUILayout.Space();
 
-		// Detect any changes to the material
 		EditorGUI.BeginChangeCheck();
 		{
-			//GUILayout.Label("Rendering", EditorStyles.boldLabel);
-			{
-				RenderModes(material);
+			LightingModePopup();
+			BlendModePopup();
+
+			if (showAdvanced) {
+				EditorGUILayout.Space();
+				EditorGUI.BeginChangeCheck();
+				int renderQueue = EditorGUILayout.IntSlider("Renderer Queue Offset", (int)_renderQueue.floatValue, 0, 49);
+				if (EditorGUI.EndChangeCheck()) material.SetInt("_RenderQueue", renderQueue);
+
+				EditorGUI.BeginChangeCheck();
+				eCulling culling = (eCulling)Mathf.RoundToInt(_culling.floatValue);
+				culling = (eCulling)EditorGUILayout.EnumPopup("Culling", culling);
+				if (EditorGUI.EndChangeCheck()) material.SetInt("_Cull", (int)culling);
+
+				EditorGUI.BeginChangeCheck();
+				bool fog = EditorGUILayout.Toggle("Use fog", material.IsKeywordEnabled("_FOG"));
+				if (EditorGUI.EndChangeCheck()) SetKeyword(material, "_FOG", fog);
 			}
 
-			GUILayout.Label("Main Maps", EditorStyles.boldLabel);
-			{
-				RenderTextureProperties(material);
-			}
+			using (new SpineInspectorUtility.BoxScope())
+				RenderTextureProperties("Main Maps", material);
 
-			GUILayout.Label("Depth", EditorStyles.boldLabel);
-			{
-				RenderDepthProperties(material);
-			}
+			if (showAdvanced) {
+				using (new SpineInspectorUtility.BoxScope()) {
+					Heading("Depth and Cast Shadow");
+					EditorGUI.BeginChangeCheck();
+					bool writeTodepth = EditorGUILayout.Toggle(new GUIContent("Write to Depth", "Write to Depth Buffer by clipping alpha."), _writeToDepth.floatValue != 0.0f);
+					if (EditorGUI.EndChangeCheck())
+						material.SetInt("_ZWrite", writeTodepth ? 1 : 0);
 
-			if (_fixedNormal != null)
-			{
-				GUILayout.Label("Normals", EditorStyles.boldLabel);
-				RenderNormalsProperties(material);
-			}
+					if (writeTodepth)
+						_materialEditor.RangeProperty(_depthAlphaCutoff, "Depth Alpha Cutoff");
 
-			GUILayout.Label("Shadows", EditorStyles.boldLabel);
-			{
-				RenderShadowsProperties(material);
-			}
+					EditorGUILayout.Space();
 
-			GUILayout.Label("Color Adjustment", EditorStyles.boldLabel);
-			{
-				RenderColorProperties(material);
-			}
+					_materialEditor.RangeProperty(_shadowAlphaCutoff, "Shadow Alpha Cutoff");
+				}
 
-			if (_emissionMap != null && _emissionColor != null)
-			{
-				GUILayout.Label("Emission", EditorStyles.boldLabel);
-				{
-					RenderEmissionProperties(material);
+				if (_fixedNormal != null) {
+					using (new SpineInspectorUtility.BoxScope()) {
+						Heading("Normals");
+						bool meshNormals = UseMeshNormalsCheckbox(material);
+						if (!meshNormals) {
+							Vector3 normal;
+							EditorGUI.BeginChangeCheck();
+							normal = showAdvanced ? EditorGUILayout.Vector3Field(new GUIContent("Fixed Normal", "Defined in Camera Space. Should normally be (0,0,-1)."), _fixedNormal.vectorValue) : (Vector3)_fixedNormal.vectorValue;
+							if (EditorGUI.EndChangeCheck())
+								_fixedNormal.vectorValue = new Vector4(normal.x, normal.y, normal.z, 1.0f);
+
+							bool backRendering;
+							EditorGUI.BeginChangeCheck();
+							if (showAdvanced) {
+								backRendering = EditorGUILayout.Toggle(new GUIContent("Fixed Normal Back Rendering", "Tick only if you are going to rotate the sprite to face away from the camera, the fixed normal will be flipped to compensate."), 
+									material.IsKeywordEnabled("_FIXED_NORMALS_BACK_RENDERING"));
+							} else {
+								backRendering = material.IsKeywordEnabled("_FIXED_NORMALS_BACK_RENDERING");
+							}
+							if (EditorGUI.EndChangeCheck()) {
+								SetKeyword(material, "_FIXED_NORMALS_BACK_RENDERING", backRendering);
+								SetKeyword(material, "_FIXED_NORMALS", !backRendering);
+							}
+						}
+					}
+				}
+			} else {
+				using (new SpineInspectorUtility.BoxScope()) {
+					EditorGUI.BeginChangeCheck();
+					bool writeTodepth = EditorGUILayout.Toggle(new GUIContent("Write to Depth", "Write to Depth Buffer by clipping alpha."), _writeToDepth.floatValue != 0.0f);
+					if (EditorGUI.EndChangeCheck())
+						material.SetInt("_ZWrite", writeTodepth ? 1 : 0);
+
+					if (_fixedNormal != null)
+						UseMeshNormalsCheckbox(material);
 				}
 			}
 
-			if (_rimColor != null)
-			{
-				GUILayout.Label("Rim Lighting", EditorStyles.boldLabel);
-				RenderRimLightingProperties(material);
-			}
+			using (new SpineInspectorUtility.BoxScope())
+				RenderColorProperties("Color Adjustment", material);
 
-			GUILayout.Label("Fog", EditorStyles.boldLabel);
-			{
-				RenderFogProperties(material);
+			if (_emissionMap != null && _emissionColor != null && _rimColor != null) {
+				Heading("Extra Lighting");
+
+				if (_emissionMap != null && _emissionColor != null)
+					using (new SpineInspectorUtility.BoxScope())
+						RenderEmissionProperties(material);
+
+				if (_rimColor != null)
+					using (new SpineInspectorUtility.BoxScope())
+						RenderRimLightingProperties(material);
 			}
 		}
-
-		if (EditorGUI.EndChangeCheck())
-		{
+		if (EditorGUI.EndChangeCheck())	{
 			foreach (var obj in _blendMode.targets)
 				MaterialChanged((Material)obj);
 		}
 	}
 
-	protected virtual void RenderModes (Material material) {
-		LightingModePopup();
-		BlendModePopup();
-
-		EditorGUI.BeginChangeCheck();
-		int renderQueue = EditorGUILayout.IntSlider("Renderer Queue", (int)_renderQueue.floatValue, 0, 49);
-		if (EditorGUI.EndChangeCheck())
-		{
-			material.SetInt("_RenderQueue", renderQueue);
-		}
-
-		EditorGUI.BeginChangeCheck();
-		eCulling culling = (eCulling)Mathf.RoundToInt(_culling.floatValue);
-		culling = (eCulling)EditorGUILayout.EnumPopup("Culling", culling);
-		if (EditorGUI.EndChangeCheck())
-		{
-			material.SetInt("_Cull", (int)culling);
-		}
-	}
-
-	protected virtual void RenderTextureProperties (Material material) {
-		_materialEditor.TexturePropertySingleLine(new GUIContent("Albedo"), _mainTexture, _color);
+	protected virtual void RenderTextureProperties (string label, Material material) {
+		if (showAdvanced)
+			Heading(label);
+		
+		_materialEditor.TexturePropertySingleLine(new GUIContent(showAdvanced ? "Albedo" : "Main Texture"), _mainTexture, _color);
 
 		if (_bumpMap != null)
 			_materialEditor.TexturePropertySingleLine(new GUIContent("Normal Map"), _bumpMap);
 
-		if (_diffuseRamp != null)
-			_materialEditor.TexturePropertySingleLine(new GUIContent("Diffuse Ramp", "A black and white gradient can be used to create a 'Toon Shading' effect."), _diffuseRamp);
-
-		if (_blendTexture != null)
-		{
-			EditorGUI.BeginChangeCheck();
-			_materialEditor.TexturePropertySingleLine(new GUIContent("Blend Texture", "When a blend texture is set the albedo will be a mix of the blend texture and main texture based on the blend amount."), _blendTexture, _blendTextureLerp);
-			if (EditorGUI.EndChangeCheck())
-			{
-				SetKeyword(material, "_TEXTURE_BLEND", _blendTexture != null);
+		if (showAdvanced) {
+			if (_blendTexture != null) {
+				EditorGUI.BeginChangeCheck();
+				_materialEditor.TexturePropertySingleLine(new GUIContent("Blend Texture", "When a blend texture is set the albedo will be a mix of the blend texture and main texture based on the blend amount."), _blendTexture, _blendTextureLerp);
+				if (EditorGUI.EndChangeCheck())
+					SetKeyword(material, "_TEXTURE_BLEND", _blendTexture != null);
 			}
 		}
 
-		_materialEditor.TextureScaleOffsetProperty(_mainTexture);
+		if (_diffuseRamp != null) {
+			EditorGUILayout.Space();
+			_materialEditor.TexturePropertySingleLine(new GUIContent("Diffuse Ramp", "A gradient can be used to create a 'Toon Shading' effect."), _diffuseRamp);
+		}
+
+		//		if (showAdvanced)
+		//			_materialEditor.TextureScaleOffsetProperty(_mainTexture);
 	}
-	
-	protected virtual void RenderEmissionProperties (Material material) {
-		bool emission = material.IsKeywordEnabled("_EMISSION");
 
-		EditorGUI.BeginChangeCheck();
-		emission = EditorGUILayout.Toggle("Enable Emission", emission);
-		if (EditorGUI.EndChangeCheck())
-		{
-			SetKeyword(material, "_EMISSION", emission);
-		}
+	protected virtual void RenderDepthProperties (string label, Material material) {
+
 
-		if (emission)
-		{
-			_materialEditor.TexturePropertyWithHDRColor(new GUIContent("Emission"), _emissionMap, _emissionColor, new ColorPickerHDRConfig(0,1, 0.01010101f, 3), true);
-			_materialEditor.FloatProperty(_emissionPower, "Emission Power");				
-		}
 	}
 
-	protected virtual void RenderDepthProperties (Material material) {
-		EditorGUI.BeginChangeCheck();
-		bool writeTodepth = EditorGUILayout.Toggle(new GUIContent("Write to Depth", "Write to Depth Buffer by clipping alpha."), _writeToDepth.floatValue != 0.0f);
-		if (EditorGUI.EndChangeCheck())
-		{
-			material.SetInt("_ZWrite", writeTodepth ? 1 : 0);
-		}
+	protected virtual void RenderNormalsProperties (string label, Material material) {
 
-		if (writeTodepth)
-		{
-			_materialEditor.RangeProperty(_depthAlphaCutoff, "Depth Alpha Cutoff");
-		}
 	}
 
-	protected virtual void RenderNormalsProperties (Material material) {
+	bool UseMeshNormalsCheckbox (Material material) {
 		EditorGUI.BeginChangeCheck();
 		bool fixedNormals = material.IsKeywordEnabled("_FIXED_NORMALS");
 		bool fixedNormalsBackRendering = material.IsKeywordEnabled("_FIXED_NORMALS_BACK_RENDERING");
-
-		bool meshNormals = EditorGUILayout.Toggle(new GUIContent("Use Mesh Normals", "If this is unticked instead of requiring mesh normals a Fixed Normal will be used instead (it's quicker and can result in better looking lighting effects on 2d objects)."), 
-													!fixedNormals && !fixedNormalsBackRendering);
-		if (EditorGUI.EndChangeCheck())
-		{
+		bool meshNormals = EditorGUILayout.Toggle(new GUIContent("Use Mesh Normals", "If this is unticked, a Fixed Normal value will be used instead of the vertex normals on the mesh. Using a fixed normal is better for performance and can result in better looking lighting effects on 2d objects."), 
+			!fixedNormals && !fixedNormalsBackRendering);
+		if (EditorGUI.EndChangeCheck()) {
 			SetKeyword(material, "_FIXED_NORMALS", meshNormals ? false : fixedNormalsBackRendering ? false : true);
 			SetKeyword(material, "_FIXED_NORMALS_BACK_RENDERING", meshNormals ? false : fixedNormalsBackRendering);
 		}
+		return meshNormals;
+	}
 
-		if (!meshNormals)
-		{
-			Vector3 normal = EditorGUILayout.Vector3Field(new GUIContent("Fixed Normal", "Defined in Camera Space. Should normally be (0,0,-1)."), _fixedNormal.vectorValue);
-			_fixedNormal.vectorValue = new Vector4(normal.x, normal.y, normal.z, 1.0f);
-
-			EditorGUI.BeginChangeCheck();
-
-			
-
-			bool backRendering = EditorGUILayout.Toggle(new GUIContent("Fixed Normal Back Rendering", "Tick only if you are going to rotate the sprite to face away from the camera, the fixed normal will be flipped to compensate."), 
-														material.IsKeywordEnabled("_FIXED_NORMALS_BACK_RENDERING"));
-			if (EditorGUI.EndChangeCheck())
-			{
-				SetKeyword(material, "_FIXED_NORMALS_BACK_RENDERING", backRendering);
-				SetKeyword(material, "_FIXED_NORMALS", !backRendering);
+	protected virtual void RenderColorProperties (string label, Material material) {
+		if (ToggleHeadingKeyword(label, material, "_COLOR_ADJUST")) {
+			_materialEditor.ColorProperty(_overlayColor, "Overlay Color");
+			EditorGUILayout.Space();
+			using (new SpineInspectorUtility.IndentScope()) {
+				_materialEditor.RangeProperty(_hue, "Hue");
+				_materialEditor.RangeProperty(_saturation, "Saturation");
+				_materialEditor.RangeProperty(_brightness, "Brightness");
 			}
 		}
 	}
 
-	protected virtual void RenderShadowsProperties (Material material) {
-		_materialEditor.FloatProperty(_shadowAlphaCutoff, "Shadow Alpha Cutoff");
-	}
-
-	protected virtual void RenderColorProperties (Material material) {
-		EditorGUI.BeginChangeCheck();
-		bool colorAdjust = EditorGUILayout.Toggle("Enable Color Adjustment", material.IsKeywordEnabled("_COLOR_ADJUST"));
-		if (EditorGUI.EndChangeCheck())
-		{
-			SetKeyword(material, "_COLOR_ADJUST", colorAdjust);	
-		}
-
-		if (colorAdjust) {
-			_materialEditor.ColorProperty(_overlayColor, "Overlay Color");
-			_materialEditor.RangeProperty(_hue, "Hue");
-			_materialEditor.RangeProperty(_saturation, "Saturation");
-			_materialEditor.RangeProperty(_brightness, "Brightness");
+	protected virtual void RenderEmissionProperties (Material material) {
+		if (ToggleHeadingKeyword("Emission", material, "_EMISSION")) {
+			_materialEditor.TexturePropertyWithHDRColor(new GUIContent("Emission"), _emissionMap, _emissionColor, new ColorPickerHDRConfig(0,1, 0.01010101f, 3), true);
+			_materialEditor.FloatProperty(_emissionPower, "Emission Power");
 		}
 	}
 
 	protected virtual void RenderRimLightingProperties (Material material) {
-		EditorGUI.BeginChangeCheck();
-		bool rimLighting = EditorGUILayout.Toggle("Enable Rim Lighting", material.IsKeywordEnabled("_RIM_LIGHTING"));
-		if (EditorGUI.EndChangeCheck())
-		{
-			SetKeyword(material, "_RIM_LIGHTING", rimLighting);
-		}
-
-		if (rimLighting)
-		{
+		if (ToggleHeadingKeyword("Rim Lighting", material, "_RIM_LIGHTING")) {
 			_materialEditor.ColorProperty(_rimColor, "Rim Color");
 			_materialEditor.FloatProperty(_rimPower, "Rim Power");
 		}
 	}
-
-	protected virtual void RenderFogProperties (Material material) {
-		EditorGUI.BeginChangeCheck();
-		bool fog = EditorGUILayout.Toggle("Enable Fog", material.IsKeywordEnabled("_FOG"));
-		if (EditorGUI.EndChangeCheck())
-		{
-			SetKeyword(material, "_FOG", fog);
-		}
-	}
 	#endregion
 
 	void SetLightModeFromShader (Material material) {
 		if (material.shader.name == kShaderPixelLit)
-		{
 			_lightMode = eLightMode.PixelLit;
-		}
 		else if (material.shader.name == kShaderUnlit)
-		{
 			_lightMode = eLightMode.Unlit;
-		}
 		else
-		{
 			_lightMode = eLightMode.VertexLit;
-		}
 	}
 
-	void SetShaderFromLightMode() {
-		Material material = _materialEditor.target as Material;
-
-		switch (_lightMode)
-		{
-			case eLightMode.VertexLit:
-				if (material.shader.name != kShaderVertexLit)
-					_materialEditor.SetShader(Shader.Find(kShaderVertexLit), false);
-				break;
-			case eLightMode.PixelLit:
-				if (material.shader.name != kShaderPixelLit)
-					_materialEditor.SetShader(Shader.Find(kShaderPixelLit), false);
-				break;
-			case eLightMode.Unlit:
-				if (material.shader.name != kShaderUnlit)
-					_materialEditor.SetShader(Shader.Find(kShaderUnlit), false);
-				break;
-		}
-
-		MaterialChanged(material);
-	}
-
-	static void SetMaterialKeywords(Material material) {
+	static void SetMaterialKeywords (Material material) {
 		eBlendMode blendMode = (eBlendMode)material.GetFloat("_BlendMode");
 
 		bool normalMap = material.HasProperty("_BumpMap") && material.GetTexture("_BumpMap") != null;
@@ -426,79 +374,114 @@ public class SpineSpriteShaderGUI : ShaderGUI {
 		int renderQueue;
 
 		switch (blendMode) {
-			case eBlendMode.Solid:
-				{
-					material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
-					material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
-					material.SetOverrideTag("RenderType", "Opaque");
-					renderQueue = kSolidQueue;
-				}
-				break;
-			case eBlendMode.Additive:
-				{ 
-					material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
-					material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.One);
-					material.SetOverrideTag("RenderType", "Transparent");
-					renderQueue = kTransparentQueue;
-				}
-				break;
-			case eBlendMode.SoftAdditive:
-				{
-					material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
-					material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcColor);
-					material.SetOverrideTag("RenderType", "Transparent");
-					renderQueue = kTransparentQueue;
-				}			
-				break;
-			case eBlendMode.Multiply:
-				{
-					material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
-					material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.SrcColor);
-					material.SetOverrideTag("RenderType", "Transparent");
-					renderQueue = kTransparentQueue;
-				}			
-				break;
-			case eBlendMode.Multiplyx2:
-				{
-					material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.DstColor);
-					material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.SrcColor);
-					material.SetOverrideTag("RenderType", "Transparent");
-					renderQueue = kTransparentQueue;
-				}			
-				break;
-			case eBlendMode.PreMultipliedAlpha:
-			case eBlendMode.StandardAlpha:
-			default:
-				{
-					material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
-					material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
-					material.SetOverrideTag("RenderType", zWrite ? "TransparentCutout" : "Transparent");
-					renderQueue = zWrite ? kAlphaTestQueue : kTransparentQueue;
-				}
-				break;
+		case eBlendMode.Solid:
+			{
+				material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
+				material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
+				material.SetOverrideTag("RenderType", "Opaque");
+				renderQueue = kSolidQueue;
+			}
+			break;
+		case eBlendMode.Additive:
+			{ 
+				material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
+				material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.One);
+				material.SetOverrideTag("RenderType", "Transparent");
+				renderQueue = kTransparentQueue;
+			}
+			break;
+		case eBlendMode.SoftAdditive:
+			{
+				material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
+				material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcColor);
+				material.SetOverrideTag("RenderType", "Transparent");
+				renderQueue = kTransparentQueue;
+			}
+			break;
+		case eBlendMode.Multiply:
+			{
+				material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
+				material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.SrcColor);
+				material.SetOverrideTag("RenderType", "Transparent");
+				renderQueue = kTransparentQueue;
+			}
+			break;
+		case eBlendMode.Multiplyx2:
+			{
+				material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.DstColor);
+				material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.SrcColor);
+				material.SetOverrideTag("RenderType", "Transparent");
+				renderQueue = kTransparentQueue;
+			}
+			break;
+		case eBlendMode.PreMultipliedAlpha:
+		case eBlendMode.StandardAlpha:
+		default:
+			{
+				material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
+				material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
+				material.SetOverrideTag("RenderType", zWrite ? "TransparentCutout" : "Transparent");
+				renderQueue = zWrite ? kAlphaTestQueue : kTransparentQueue;
+			}
+			break;
 		}
-		
+
 		material.renderQueue = renderQueue + material.GetInt("_RenderQueue");
 	}
 
-	static void MaterialChanged (Material material) {		
+	static void Heading (string label) {
+		GUILayout.Label(label, EditorStyles.boldLabel);
+	}
+
+	static bool ToggleHeadingKeyword (string label, Material material, string keyword) {
+		int i = EditorGUI.indentLevel;
+		var o = EditorStyles.label.fontStyle;
+		EditorGUI.indentLevel = 0;
+		EditorStyles.label.fontStyle = FontStyle.Bold;
+
+		EditorGUI.BeginChangeCheck();
+		bool r = EditorGUILayout.Toggle(new GUIContent(label, string.Format("This checkbox sets shader keyword: '{0}', which causes the Material to use extra shader features.", keyword)), material.IsKeywordEnabled(keyword));
+		if (EditorGUI.EndChangeCheck())
+			SetKeyword(material, keyword, r);
+
+		EditorStyles.label.fontStyle = o;
+		EditorGUI.indentLevel = i;
+		return r;
+	}
+
+	static void MaterialChanged (Material material) {
 		SetMaterialKeywords(material);
 	}
 
 	static void SetKeyword (Material m, string keyword, bool state) {
 		if (state)
-			m.EnableKeyword (keyword);
+			m.EnableKeyword(keyword);
 		else
-			m.DisableKeyword (keyword);
+			m.DisableKeyword(keyword);
 	}
 
-	void LightingModePopup ()
-	{
+	void LightingModePopup () {
 		EditorGUI.BeginChangeCheck();
 		_lightMode = (eLightMode)EditorGUILayout.Popup("Lighting Mode", (int)_lightMode, Enum.GetNames(typeof(eLightMode)));
-		if (EditorGUI.EndChangeCheck())
-		{
-			SetShaderFromLightMode();
+		if (EditorGUI.EndChangeCheck()) {
+			var material = _materialEditor.target as Material;
+
+			switch (_lightMode) {
+			case eLightMode.VertexLit:
+				if (material.shader.name != kShaderVertexLit)
+					_materialEditor.SetShader(Shader.Find(kShaderVertexLit), false);
+				break;
+			case eLightMode.PixelLit:
+				if (material.shader.name != kShaderPixelLit)
+					_materialEditor.SetShader(Shader.Find(kShaderPixelLit), false);
+				break;
+			case eLightMode.Unlit:
+				if (material.shader.name != kShaderUnlit)
+					_materialEditor.SetShader(Shader.Find(kShaderUnlit), false);
+				break;
+			}
+
+			MaterialChanged(material);
 		}
 	}
 
@@ -506,8 +489,7 @@ public class SpineSpriteShaderGUI : ShaderGUI {
 		eBlendMode mode = (eBlendMode)_blendMode.floatValue;
 		EditorGUI.BeginChangeCheck();
 		mode = (eBlendMode)EditorGUILayout.Popup("Blend Mode", (int)mode, Enum.GetNames(typeof(eBlendMode)));
-		if (EditorGUI.EndChangeCheck())
-		{
+		if (EditorGUI.EndChangeCheck()) {
 			_materialEditor.RegisterPropertyChangeUndo("Blend Mode");
 			_blendMode.floatValue = (float)mode;
 		}

+ 1 - 1
spine-unity/Assets/spine-unity/SkeletonExtensions.cs

@@ -180,7 +180,7 @@ namespace Spine.Unity {
 				for (int i = 0; i < bufferTargetSize; i++) {
 					int j = i * 2;
 					float x = floats[j] - bwx, y = floats[j+1] - bwy;
-					buffer[i] = new Vector2(x * ia + y * ic, x * ib + y * id);
+					buffer[i] = new Vector2(x * ia + y * ib, x * ic + y * id);
 				}
 			}
 

+ 13 - 11
spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityBoneInspector.cs

@@ -184,7 +184,7 @@ namespace Spine.Unity.Editor {
 			using (new EditorGUI.DisabledGroupScope(multiObject || boundingBoxTable.Count == 0)) {
 				EditorGUILayout.LabelField(new GUIContent("Bounding Boxes", SpineEditorUtilities.Icons.boundingBox), EditorStyles.boldLabel);
 
-				foreach(var entry in boundingBoxTable){
+				foreach (var entry in boundingBoxTable){
 					Slot slot = entry.Key;
 					var boundingBoxes = entry.Value;
 
@@ -195,19 +195,21 @@ namespace Spine.Unity.Editor {
 						foreach (var box in boundingBoxes) {
 							using (new GUILayout.HorizontalScope()) {
 								GUILayout.Space(30);
-								if (GUILayout.Button(box.Name, GUILayout.Width(200))) {
-									var child = utilityBone.transform.FindChild("[BoundingBox]" + box.Name);
-									if (child != null) {
-										var originalCollider = child.GetComponent<PolygonCollider2D>();
-										var updatedCollider = SkeletonUtility.AddBoundingBoxAsComponent(box, slot, child.gameObject, originalCollider.isTrigger);
-										originalCollider.points = updatedCollider.points;
-										if (EditorApplication.isPlaying)
-											Destroy(updatedCollider);
+								string buttonLabel = box.IsWeighted() ? box.Name + " (!)" : box.Name;
+								if (GUILayout.Button(buttonLabel, GUILayout.Width(200))) {
+									utilityBone.bone.Skeleton.UpdateWorldTransform();
+									var bbTransform = utilityBone.transform.FindChild("[BoundingBox]" + box.Name);
+									if (bbTransform != null) {
+										var originalCollider = bbTransform.GetComponent<PolygonCollider2D>();
+										if (originalCollider != null)
+											SkeletonUtility.SetColliderPointsLocal(originalCollider, slot, box);
 										else
-											DestroyImmediate(updatedCollider);
+											SkeletonUtility.AddBoundingBoxAsComponent(box, slot, bbTransform.gameObject);
 									} else {
-										utilityBone.AddBoundingBox(currentSkinName, slot.Data.Name, box.Name);
+										var newPolygonCollider = SkeletonUtility.AddBoundingBoxGameObject(null, box, slot, utilityBone.transform);
+										bbTransform = newPolygonCollider.transform;
 									}
+									EditorGUIUtility.PingObject(bbTransform);
 								}
 							}
 

+ 29 - 15
spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtility.cs

@@ -31,7 +31,6 @@
 // Contributed by: Mitch Thompson
 
 using UnityEngine;
-using System.Collections;
 using System.Collections.Generic;
 using Spine;
 
@@ -41,40 +40,55 @@ namespace Spine.Unity {
 	public class SkeletonUtility : MonoBehaviour {
 	
 		#region BoundingBoxAttachment
-		public static PolygonCollider2D AddBoundingBox (Skeleton skeleton, string skinName, string slotName, string attachmentName, Transform parent, bool isTrigger = true) {
-			skinName = string.IsNullOrEmpty(skinName) ? skinName : skeleton.Data.DefaultSkin.Name;
-			Skin skin = skeleton.Data.FindSkin(skinName);
+		public static PolygonCollider2D AddBoundingBoxGameObject (Skeleton skeleton, string skinName, string slotName, string attachmentName, Transform parent, bool isTrigger = true) {
+			Skin skin = string.IsNullOrEmpty(skinName) ? skeleton.data.defaultSkin : skeleton.data.FindSkin(skinName);
 			if (skin == null) {
 				Debug.LogError("Skin " + skinName + " not found!");
 				return null;
 			}
 
+			int slotIndex = skeleton.FindSlotIndex(slotName);
 			var attachment = skin.GetAttachment(skeleton.FindSlotIndex(slotName), attachmentName);
+			if (attachment == null) {
+				Debug.LogFormat("Attachment in slot '{0}' named '{1}' not found in skin '{2}'.", slotName, attachmentName, skin.name);
+				return null;
+			}
+
 			var box = attachment as BoundingBoxAttachment;
 			if (box != null) {
-				var go = new GameObject("[BoundingBox]" + attachmentName);
-				var got = go.transform;
-				got.parent = parent;
-				got.localPosition = Vector3.zero;
-				got.localRotation = Quaternion.identity;
-				got.localScale = Vector3.one;
 				var slot = skeleton.FindSlot(slotName);
-				return AddBoundingBoxAsComponent(box, slot, go, isTrigger);
+				return AddBoundingBoxGameObject(box.Name, box, slot, parent, isTrigger);
+			} else {
+				Debug.LogFormat("Attachment '{0}' was not a Bounding Box.", attachmentName);
+				return null;
 			}
+		}
 
-			return null;
+		public static PolygonCollider2D AddBoundingBoxGameObject (string name, BoundingBoxAttachment box, Slot slot, Transform parent, bool isTrigger = true) {
+			var go = new GameObject("[BoundingBox]" + (string.IsNullOrEmpty(name) ? box.Name : name));
+			var got = go.transform;
+			got.parent = parent;
+			got.localPosition = Vector3.zero;
+			got.localRotation = Quaternion.identity;
+			got.localScale = Vector3.one;
+			return AddBoundingBoxAsComponent(box, slot, go, isTrigger);
 		}
 
 		public static PolygonCollider2D AddBoundingBoxAsComponent (BoundingBoxAttachment box, Slot slot, GameObject gameObject, bool isTrigger = true) {
 			if (box == null) return null;
-			if (box.IsWeighted()) Debug.LogWarning("UnityEngine.PolygonCollider2D does not support weighted or animated points. Collider will not be animated. Please remove weights and animations from the bounding box in Spine editor.");
-			var verts = box.GetLocalVertices(slot, null);
 			var collider = gameObject.AddComponent<PolygonCollider2D>();
 			collider.isTrigger = isTrigger;
-			collider.SetPath(0, verts);
+			SetColliderPointsLocal(collider, slot, box);
 			return collider;
 		}
 
+		public static void SetColliderPointsLocal (PolygonCollider2D collider, Slot slot, BoundingBoxAttachment box) {
+			if (box == null) return;
+			if (box.IsWeighted()) Debug.LogWarning("UnityEngine.PolygonCollider2D does not support weighted or animated points. Collider points will not be animated and may have incorrect orientation. If you want to use it as a collider, please remove weights and animations from the bounding box in Spine editor.");
+			var verts = box.GetLocalVertices(slot, null);
+			collider.SetPath(0, verts);
+		}
+
 		public static Bounds GetBoundingBoxBounds (BoundingBoxAttachment boundingBox, float depth = 0) {
 			float[] floats = boundingBox.Vertices;
 			int floatCount = floats.Length;

+ 3 - 5
spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityBone.cs

@@ -63,9 +63,7 @@ namespace Spine.Unity {
 		Transform cachedTransform;
 		Transform skeletonTransform;
 		bool incompatibleTransformMode;
-		public bool IncompatibleTransformMode {
-			get { return incompatibleTransformMode; }
-		}
+		public bool IncompatibleTransformMode { get { return incompatibleTransformMode; } }
 
 		public void Reset () {
 			bone = null;
@@ -132,7 +130,7 @@ namespace Spine.Unity {
 				}
 
 				if (scale) {
-					cachedTransform.localScale = new Vector3(bone.scaleX, bone.scaleY, 1f);//, bone.WorldSignX);
+					cachedTransform.localScale = new Vector3(bone.scaleX, bone.scaleY, 1f);
 					incompatibleTransformMode = BoneTransformModeIncompatible(bone);
 				}
 			} else if (mode == Mode.Override) {
@@ -193,7 +191,7 @@ namespace Spine.Unity {
 		}
 
 		public void AddBoundingBox (string skinName, string slotName, string attachmentName) {
-			SkeletonUtility.AddBoundingBox(bone.skeleton, skinName, slotName, attachmentName, transform);
+			SkeletonUtility.AddBoundingBoxGameObject(bone.skeleton, skinName, slotName, attachmentName, transform);
 		}
 
 		#if UNITY_EDITOR