diff --git a/spine-unity/Assets/spine-unity/Asset Types/Editor/SkeletonDataAssetInspector.cs b/spine-unity/Assets/spine-unity/Asset Types/Editor/SkeletonDataAssetInspector.cs
index c6d0bbc95..608327135 100644
--- a/spine-unity/Assets/spine-unity/Asset Types/Editor/SkeletonDataAssetInspector.cs
+++ b/spine-unity/Assets/spine-unity/Asset Types/Editor/SkeletonDataAssetInspector.cs
@@ -387,6 +387,9 @@ namespace Spine.Unity.Editor {
}
EditorGUILayout.LabelField("Name", " Duration");
+ bool nonessential = m_skeletonData.ImagesPath != null;
+ float fps = m_skeletonData.Fps;
+ if (nonessential && fps == 0) fps = 30;
foreach (Spine.Animation animation in m_skeletonData.Animations) {
using (new GUILayout.HorizontalScope()) {
if (m_skeletonAnimation != null && m_skeletonAnimation.state != null) {
@@ -403,7 +406,8 @@ namespace Spine.Unity.Editor {
} else {
GUILayout.Label("-", GUILayout.Width(24));
}
- EditorGUILayout.LabelField(new GUIContent(animation.Name, Icons.animation), SpineInspectorUtility.TempContent(animation.Duration.ToString("f3") + "s" + ("(" + (Mathf.RoundToInt(animation.Duration * 30)) + ")").PadLeft(12, ' ')));
+ string frameCountString = (fps > 0) ? ("(" + (Mathf.RoundToInt(animation.Duration * fps)) + ")").PadLeft(12, ' ') : string.Empty;
+ EditorGUILayout.LabelField(new GUIContent(animation.Name, Icons.animation), SpineInspectorUtility.TempContent(animation.Duration.ToString("f3") + "s" + frameCountString));
}
}
}
diff --git a/spine-unity/Assets/spine-unity/Editor/SpineAttributeDrawers.cs b/spine-unity/Assets/spine-unity/Editor/SpineAttributeDrawers.cs
index fd8c13d94..55d1f3ae8 100644
--- a/spine-unity/Assets/spine-unity/Editor/SpineAttributeDrawers.cs
+++ b/spine-unity/Assets/spine-unity/Editor/SpineAttributeDrawers.cs
@@ -74,15 +74,16 @@ namespace Spine.Unity.Editor {
return;
}
- var dataField = property.FindBaseOrSiblingProperty(TargetAttribute.dataField);
+ SerializedProperty dataField = property.FindBaseOrSiblingProperty(TargetAttribute.dataField);
if (dataField != null) {
- if (dataField.objectReferenceValue is SkeletonDataAsset) {
- skeletonDataAsset = (SkeletonDataAsset)dataField.objectReferenceValue;
- } else if (dataField.objectReferenceValue is ISkeletonComponent) {
- var skeletonComponent = (ISkeletonComponent)dataField.objectReferenceValue;
+ var objectReferenceValue = dataField.objectReferenceValue;
+ if (objectReferenceValue is SkeletonDataAsset) {
+ skeletonDataAsset = (SkeletonDataAsset)objectReferenceValue;
+ } else if (objectReferenceValue is ISkeletonComponent) {
+ var skeletonComponent = (ISkeletonComponent)objectReferenceValue;
if (skeletonComponent != null)
skeletonDataAsset = skeletonComponent.SkeletonDataAsset;
- } else {
+ } else if (objectReferenceValue != null) {
EditorGUI.LabelField(position, "ERROR:", "Invalid reference type");
return;
}
@@ -95,7 +96,12 @@ namespace Spine.Unity.Editor {
}
if (skeletonDataAsset == null) {
- EditorGUI.LabelField(position, "ERROR:", "Must have reference to a SkeletonDataAsset");
+ if (TargetAttribute.fallbackToTextField) {
+ EditorGUI.PropertyField(position, property); //EditorGUI.TextField(position, label, property.stringValue);
+ } else {
+ EditorGUI.LabelField(position, "ERROR:", "Must have reference to a SkeletonDataAsset");
+ }
+
skeletonDataAsset = property.serializedObject.targetObject as SkeletonDataAsset;
if (skeletonDataAsset == null) return;
}
diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteVertexLighting.cginc b/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteVertexLighting.cginc
index 749b91bae..0ffa2776b 100644
--- a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteVertexLighting.cginc
+++ b/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteVertexLighting.cginc
@@ -345,7 +345,7 @@ VertexOutput vert(VertexInput input)
output.color = calculateVertexColor(input.color);
output.texcoord = float3(calculateTextureCoord(input.texcoord), 0);
- float3 viewPos = UnityObjectViewPos(input.vertex); //float3 viewPos = mul(UNITY_MATRIX_MV, input.vertex);
+ float3 viewPos = UnityObjectToViewPos(input.vertex); //float3 viewPos = mul(UNITY_MATRIX_MV, input.vertex); //
#if defined(FIXED_NORMALS_BACKFACE_RENDERING) || defined(_RIM_LIGHTING)
float4 powWorld = calculateWorldPos(input.vertex);
#endif
diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Shaders/SkeletonGraphicDefault.mat b/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Shaders/SkeletonGraphicDefault.mat
index a8d591f48..08d7764ce 100644
--- a/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Shaders/SkeletonGraphicDefault.mat
+++ b/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Shaders/SkeletonGraphicDefault.mat
@@ -10,127 +10,78 @@ Material:
m_Shader: {fileID: 4800000, guid: fa95b0fb6983c0f40a152e6f9aa82bfb, type: 3}
m_ShaderKeywords:
m_LightmapFlags: 5
- m_CustomRenderQueue: 3000
+ m_EnableInstancingVariants: 0
+ m_DoubleSidedGI: 0
+ m_CustomRenderQueue: -1
stringTagMap: {}
+ disabledShaderPasses: []
m_SavedProperties:
- serializedVersion: 2
+ serializedVersion: 3
m_TexEnvs:
- - first:
- name: _BumpMap
- second:
+ - _AlphaTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- - first:
- name: _DetailAlbedoMap
- second:
+ - _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- - first:
- name: _DetailMask
- second:
+ - _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- - first:
- name: _DetailNormalMap
- second:
+ - _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- - first:
- name: _EmissionMap
- second:
+ - _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- - first:
- name: _MainTex
- second:
+ - _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- - first:
- name: _MetallicGlossMap
- second:
+ - _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- - first:
- name: _OcclusionMap
- second:
+ - _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- - first:
- name: _ParallaxMap
- second:
+ - _OcclusionMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- - first:
- name: _BumpScale
- second: 1
- - first:
- name: _ColorMask
- second: 15
- - first:
- name: _Cutoff
- second: 0.5
- - first:
- name: _DetailNormalMapScale
- second: 1
- - first:
- name: _DstBlend
- second: 0
- - first:
- name: _Glossiness
- second: 0.5
- - first:
- name: _Metallic
- second: 0
- - first:
- name: _Mode
- second: 0
- - first:
- name: _OcclusionStrength
- second: 1
- - first:
- name: _Parallax
- second: 0.02
- - first:
- name: _SrcBlend
- second: 1
- - first:
- name: _Stencil
- second: 0
- - first:
- name: _StencilComp
- second: 8
- - first:
- name: _StencilOp
- second: 0
- - first:
- name: _StencilReadMask
- second: 255
- - first:
- name: _StencilWriteMask
- second: 255
- - first:
- name: _UVSec
- second: 0
- - first:
- name: _UseUIAlphaClip
- second: 0
- - first:
- name: _ZWrite
- second: 1
+ - PixelSnap: 0
+ - _BumpScale: 1
+ - _ColorMask: 15
+ - _Cutoff: 0.5
+ - _DetailNormalMapScale: 1
+ - _DstBlend: 0
+ - _EnableExternalAlpha: 0
+ - _Glossiness: 0.5
+ - _Metallic: 0
+ - _Mode: 0
+ - _OcclusionStrength: 1
+ - _Parallax: 0.02
+ - _SrcBlend: 1
+ - _Stencil: 0
+ - _StencilComp: 8
+ - _StencilOp: 0
+ - _StencilReadMask: 255
+ - _StencilWriteMask: 255
+ - _UVSec: 0
+ - _UseUIAlphaClip: 0
+ - _ZWrite: 1
m_Colors:
- - first:
- name: _Color
- second: {r: 1, g: 1, b: 1, a: 1}
- - first:
- name: _EmissionColor
- second: {r: 0, g: 0, b: 0, a: 1}
+ - _Color: {r: 1, g: 1, b: 1, a: 1}
+ - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
+ - _Flip: {r: 1, g: 1, b: 1, a: 1}
+ - _RendererColor: {r: 1, g: 1, b: 1, a: 1}
diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Shaders/Spine-SkeletonGraphic.shader b/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Shaders/Spine-SkeletonGraphic.shader
index 2993e815a..fa25e7ba6 100644
--- a/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Shaders/Spine-SkeletonGraphic.shader
+++ b/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Shaders/Spine-SkeletonGraphic.shader
@@ -112,4 +112,4 @@ Shader "Spine/SkeletonGraphic (Premultiply Alpha)"
ENDCG
}
}
-}
+}
\ No newline at end of file
diff --git a/spine-unity/Assets/spine-unity/SpineAttributes.cs b/spine-unity/Assets/spine-unity/SpineAttributes.cs
index 8836c0a43..5f3d7ed91 100644
--- a/spine-unity/Assets/spine-unity/SpineAttributes.cs
+++ b/spine-unity/Assets/spine-unity/SpineAttributes.cs
@@ -41,6 +41,7 @@ namespace Spine.Unity {
public string dataField = "";
public string startsWith = "";
public bool includeNone = true;
+ public bool fallbackToTextField = false;
}
public class SpineSlot : SpineAttributeBase {
@@ -52,15 +53,17 @@ namespace Spine.Unity {
/// Filters popup results to elements that begin with supplied string.
/// Disables popup results that don't contain bounding box attachments when true.
/// If true, the dropdown list will include a "none" option which stored as an empty string.
+ /// If true, and an animation list source can't be found, the field will fall back to a normal text field. If false, it will show an error.
/// If specified, a locally scoped field with the name supplied by in dataField will be used to fill the popup results.
/// Valid types are SkeletonDataAsset and SkeletonRenderer (and derivatives).
/// If left empty and the script the attribute is applied to is derived from Component, GetComponent() will be called as a fallback.
///
- public SpineSlot(string startsWith = "", string dataField = "", bool containsBoundingBoxes = false, bool includeNone = true) {
+ public SpineSlot (string startsWith = "", string dataField = "", bool containsBoundingBoxes = false, bool includeNone = true, bool fallbackToTextField = false) {
this.startsWith = startsWith;
this.dataField = dataField;
this.containsBoundingBoxes = containsBoundingBoxes;
this.includeNone = includeNone;
+ this.fallbackToTextField = fallbackToTextField;
}
}
@@ -72,12 +75,14 @@ namespace Spine.Unity {
/// If true, the dropdown list will include a "none" option which stored as an empty string.
/// If specified, a locally scoped field with the name supplied by in dataField will be used to fill the popup results.
/// Valid types are SkeletonDataAsset and SkeletonRenderer (and derivatives).
- /// If left empty and the script the attribute is applied to is derived from Component, GetComponent() will be called as a fallback.
+ /// If left empty and the script the attribute is applied to is derived from Component, GetComponent(SkeletonRenderer)() will be called as a fallback.
///
- public SpineEvent(string startsWith = "", string dataField = "", bool includeNone = true) {
+ /// If true, and an animation list source can't be found, the field will fall back to a normal text field. If false, it will show an error.
+ public SpineEvent (string startsWith = "", string dataField = "", bool includeNone = true, bool fallbackToTextField = false) {
this.startsWith = startsWith;
this.dataField = dataField;
this.includeNone = includeNone;
+ this.fallbackToTextField = fallbackToTextField;
}
}
@@ -89,12 +94,14 @@ namespace Spine.Unity {
/// If true, the dropdown list will include a "none" option which stored as an empty string.
/// If specified, a locally scoped field with the name supplied by in dataField will be used to fill the popup results.
/// Valid types are SkeletonDataAsset and SkeletonRenderer (and derivatives).
- /// If left empty and the script the attribute is applied to is derived from Component, GetComponent() will be called as a fallback.
+ /// If left empty and the script the attribute is applied to is derived from Component, GetComponent(SkeletonRenderer)() will be called as a fallback.
///
- public SpineIkConstraint(string startsWith = "", string dataField = "", bool includeNone = true) {
+ /// If true, and an animation list source can't be found, the field will fall back to a normal text field. If false, it will show an error.
+ public SpineIkConstraint (string startsWith = "", string dataField = "", bool includeNone = true, bool fallbackToTextField = false) {
this.startsWith = startsWith;
this.dataField = dataField;
this.includeNone = includeNone;
+ this.fallbackToTextField = fallbackToTextField;
}
}
@@ -106,12 +113,13 @@ namespace Spine.Unity {
/// If true, the dropdown list will include a "none" option which stored as an empty string.
/// If specified, a locally scoped field with the name supplied by in dataField will be used to fill the popup results.
/// Valid types are SkeletonDataAsset and SkeletonRenderer (and derivatives).
- /// If left empty and the script the attribute is applied to is derived from Component, GetComponent() will be called as a fallback.
+ /// If left empty and the script the attribute is applied to is derived from Component, GetComponent(SkeletonRenderer)() will be called as a fallback.
///
- public SpinePathConstraint(string startsWith = "", string dataField = "", bool includeNone = true) {
+ public SpinePathConstraint (string startsWith = "", string dataField = "", bool includeNone = true, bool fallbackToTextField = false) {
this.startsWith = startsWith;
this.dataField = dataField;
this.includeNone = includeNone;
+ this.fallbackToTextField = fallbackToTextField;
}
}
@@ -121,14 +129,16 @@ namespace Spine.Unity {
///
/// Filters popup results to elements that begin with supplied string.
/// If true, the dropdown list will include a "none" option which stored as an empty string.
+ /// If true, and an animation list source can't be found, the field will fall back to a normal text field. If false, it will show an error.
/// If specified, a locally scoped field with the name supplied by in dataField will be used to fill the popup results.
/// Valid types are SkeletonDataAsset and SkeletonRenderer (and derivatives).
/// If left empty and the script the attribute is applied to is derived from Component, GetComponent() will be called as a fallback.
///
- public SpineTransformConstraint(string startsWith = "", string dataField = "", bool includeNone = true) {
+ public SpineTransformConstraint (string startsWith = "", string dataField = "", bool includeNone = true, bool fallbackToTextField = false) {
this.startsWith = startsWith;
this.dataField = dataField;
this.includeNone = includeNone;
+ this.fallbackToTextField = fallbackToTextField;
}
}
@@ -138,14 +148,16 @@ namespace Spine.Unity {
///
/// Filters popup results to elements that begin with supplied string.
/// If true, the dropdown list will include a "none" option which stored as an empty string.
+ /// If true, and an animation list source can't be found, the field will fall back to a normal text field. If false, it will show an error.
/// If specified, a locally scoped field with the name supplied by in dataField will be used to fill the popup results.
/// Valid types are SkeletonDataAsset and SkeletonRenderer (and derivatives)
/// If left empty and the script the attribute is applied to is derived from Component, GetComponent() will be called as a fallback.
///
- public SpineSkin(string startsWith = "", string dataField = "", bool includeNone = true) {
+ public SpineSkin (string startsWith = "", string dataField = "", bool includeNone = true, bool fallbackToTextField = false) {
this.startsWith = startsWith;
this.dataField = dataField;
this.includeNone = includeNone;
+ this.fallbackToTextField = fallbackToTextField;
}
}
public class SpineAnimation : SpineAttributeBase {
@@ -153,15 +165,17 @@ namespace Spine.Unity {
/// Smart popup menu for Spine Animations
///
/// Filters popup results to elements that begin with supplied string.
- /// If specified, a locally scoped field with the name supplied by in dataField will be used to fill the popup results.
+ /// If true, and an animation list source can't be found, the field will fall back to a normal text field. If false, it will show an error.
/// If true, the dropdown list will include a "none" option which stored as an empty string.
+ /// If specified, a locally scoped field with the name supplied by in dataField will be used to fill the popup results.
/// Valid types are SkeletonDataAsset and SkeletonRenderer (and derivatives)
/// If left empty and the script the attribute is applied to is derived from Component, GetComponent() will be called as a fallback.
///
- public SpineAnimation(string startsWith = "", string dataField = "", bool includeNone = true) {
+ public SpineAnimation (string startsWith = "", string dataField = "", bool includeNone = true, bool fallbackToTextField = false) {
this.startsWith = startsWith;
this.dataField = dataField;
this.includeNone = includeNone;
+ this.fallbackToTextField = fallbackToTextField;
}
}
@@ -181,11 +195,12 @@ namespace Spine.Unity {
/// If specified, a locally scoped field with the name supplied by in slotField will be used to limit the popup results to children of a named slot
/// If specified, a locally scoped field with the name supplied by in skinField will be used to limit the popup results to entries of the named skin
/// If true, the dropdown list will include a "none" option which stored as an empty string.
+ /// If true, and an animation list source can't be found, the field will fall back to a normal text field. If false, it will show an error.
/// If specified, a locally scoped field with the name supplied by in dataField will be used to fill the popup results.
/// Valid types are SkeletonDataAsset and SkeletonRenderer (and derivatives)
/// If left empty and the script the attribute is applied to is derived from Component, GetComponent() will be called as a fallback.
///
- public SpineAttachment (bool currentSkinOnly = true, bool returnAttachmentPath = false, bool placeholdersOnly = false, string slotField = "", string dataField = "", string skinField = "", bool includeNone = true) {
+ public SpineAttachment (bool currentSkinOnly = true, bool returnAttachmentPath = false, bool placeholdersOnly = false, string slotField = "", string dataField = "", string skinField = "", bool includeNone = true, bool fallbackToTextField = false) {
this.currentSkinOnly = currentSkinOnly;
this.returnAttachmentPath = returnAttachmentPath;
this.placeholdersOnly = placeholdersOnly;
@@ -193,6 +208,7 @@ namespace Spine.Unity {
this.dataField = dataField;
this.skinField = skinField;
this.includeNone = includeNone;
+ this.fallbackToTextField = fallbackToTextField;
}
public static SpineAttachment.Hierarchy GetHierarchy (string fullPath) {
@@ -241,15 +257,17 @@ namespace Spine.Unity {
/// Smart popup menu for Spine Bones
///
/// Filters popup results to elements that begin with supplied string.
- /// /// If true, the dropdown list will include a "none" option which stored as an empty string.
+ /// If true, the dropdown list will include a "none" option which stored as an empty string.
+ /// If true, and an animation list source can't be found, the field will fall back to a normal text field. If false, it will show an error.
/// If specified, a locally scoped field with the name supplied by in dataField will be used to fill the popup results.
/// Valid types are SkeletonDataAsset and SkeletonRenderer (and derivatives)
/// If left empty and the script the attribute is applied to is derived from Component, GetComponent() will be called as a fallback.
///
- public SpineBone(string startsWith = "", string dataField = "", bool includeNone = true) {
+ public SpineBone (string startsWith = "", string dataField = "", bool includeNone = true, bool fallbackToTextField = false) {
this.startsWith = startsWith;
this.dataField = dataField;
this.includeNone = includeNone;
+ this.fallbackToTextField = fallbackToTextField;
}
public static Spine.Bone GetBone(string boneName, SkeletonRenderer renderer) {
@@ -265,7 +283,7 @@ namespace Spine.Unity {
public class SpineAtlasRegion : PropertyAttribute {
public string atlasAssetField;
- public SpineAtlasRegion(string atlasAssetField = "") {
+ public SpineAtlasRegion (string atlasAssetField = "") {
this.atlasAssetField = atlasAssetField;
}
}