Explorar o código

[unity] BoneFollower can now optionally follow (uniform) world scale of the reference bone. Renamed BoneFollower.followLocalScale to followScale. Scenes and prefabs are automatically upgraded, code needs manual correction.

Harald Csaszar %!s(int64=5) %!d(string=hai) anos
pai
achega
cdcdb64a4f

+ 2 - 0
CHANGELOG.md

@@ -48,6 +48,7 @@
   * Removed rarely used `Spine.Unity.AttachmentTools.AttachmentRegionExtensions` extension methods `Attachment.GetRegion()`. Use `Attachment.RendererObject as AtlasRegion` instead.
   * Removed rarely used `Spine.Unity.AttachmentTools.AttachmentRegionExtensions` extension methods `Attachment.GetRegion()`. Use `Attachment.RendererObject as AtlasRegion` instead.
   * Removed redundant `Spine.SkeletonExtensions` extension methods `Skeleton.Set*ToSetupPose()`. Also removed less commonly used extension methods `TrackEntry.AllowImmediateQueue()` and `Attachment.IsRenderable()`.
   * Removed redundant `Spine.SkeletonExtensions` extension methods `Skeleton.Set*ToSetupPose()`. Also removed less commonly used extension methods `TrackEntry.AllowImmediateQueue()` and `Attachment.IsRenderable()`.
   * `Skin.Attachments` now replaces `Skin.GetAttachments()`, returning an `ICollection<SkinEntry>`. This makes access more consistent and intuitive. To fix any compile errors, replace any occurrances of `skin.GetAttachments()` by `skin.Attachments`.
   * `Skin.Attachments` now replaces `Skin.GetAttachments()`, returning an `ICollection<SkinEntry>`. This makes access more consistent and intuitive. To fix any compile errors, replace any occurrances of `skin.GetAttachments()` by `skin.Attachments`.
+  * `BoneFollower` property `followLocalScale` has been renamed to `followScale`. Serialized values (scenes and prefabs) will automatically be upgraded, only code accessing `followLocalScale` needs to be adapted.
 
 
 * **Additions**
 * **Additions**
   * Additional **Fix Draw Order** parameter at SkeletonRenderer, defaults to `disabled` (previous behaviour).
   * Additional **Fix Draw Order** parameter at SkeletonRenderer, defaults to `disabled` (previous behaviour).
@@ -62,6 +63,7 @@
   Outline rendering is fully supported on `SkeletonGraphic` shaders as well.
   Outline rendering is fully supported on `SkeletonGraphic` shaders as well.
   * Added `SkeletonRenderer.EditorSkipSkinSync` scripting API property to be able to set custom skins in editor scripts. Enable this property when overwriting the Skeleton's skin from an editor script. Without setting this parameter, changes will be overwritten by the next inspector update. Only affects Inspector synchronisation of skin with `initialSkinName`, not startup initialization.
   * Added `SkeletonRenderer.EditorSkipSkinSync` scripting API property to be able to set custom skins in editor scripts. Enable this property when overwriting the Skeleton's skin from an editor script. Without setting this parameter, changes will be overwritten by the next inspector update. Only affects Inspector synchronisation of skin with `initialSkinName`, not startup initialization.
   * `AtlasUtilities.GetRepackedAttachments()` and `AtlasUtilities.GetRepackedSkin()` provide support for additional texture channels such as normal maps via the optional parameter `additionalTexturePropertyIDsToCopy `. See the spine-unity runtime documentation, section [Combining Skins - Advanced - Runtime Repacking with Normalmaps](http://esotericsoftware.com/spine-unity#Combining-Skins) for further info and example usage code.
   * `AtlasUtilities.GetRepackedAttachments()` and `AtlasUtilities.GetRepackedSkin()` provide support for additional texture channels such as normal maps via the optional parameter `additionalTexturePropertyIDsToCopy `. See the spine-unity runtime documentation, section [Combining Skins - Advanced - Runtime Repacking with Normalmaps](http://esotericsoftware.com/spine-unity#Combining-Skins) for further info and example usage code.
+  * `BoneFollower` can now optionally follow (uniform) world scale of the reference bone. There is now a `Mode` dropdown selector in the Inspector which can be set to either `Local` or `World Uniform`.
 
 
 * **Changes of default values**
 * **Changes of default values**
 
 

+ 9 - 3
spine-unity/Assets/Spine/Editor/spine-unity/Editor/Components/BoneFollowerInspector.cs

@@ -37,7 +37,7 @@ namespace Spine.Unity.Editor {
 
 
 	[CustomEditor(typeof(BoneFollower)), CanEditMultipleObjects]
 	[CustomEditor(typeof(BoneFollower)), CanEditMultipleObjects]
 	public class BoneFollowerInspector : Editor {
 	public class BoneFollowerInspector : Editor {
-		SerializedProperty boneName, skeletonRenderer, followXYPosition, followZPosition, followBoneRotation, followLocalScale, followSkeletonFlip;
+		SerializedProperty boneName, skeletonRenderer, followXYPosition, followZPosition, followBoneRotation, followScale, followScaleMode, followSkeletonFlip;
 		BoneFollower targetBoneFollower;
 		BoneFollower targetBoneFollower;
 		bool needsReset;
 		bool needsReset;
 
 
@@ -84,7 +84,8 @@ namespace Spine.Unity.Editor {
 			followBoneRotation = serializedObject.FindProperty("followBoneRotation");
 			followBoneRotation = serializedObject.FindProperty("followBoneRotation");
 			followXYPosition = serializedObject.FindProperty("followXYPosition");
 			followXYPosition = serializedObject.FindProperty("followXYPosition");
 			followZPosition = serializedObject.FindProperty("followZPosition");
 			followZPosition = serializedObject.FindProperty("followZPosition");
-			followLocalScale = serializedObject.FindProperty("followLocalScale");
+			followScale = serializedObject.FindProperty("followScale");
+			followScaleMode = serializedObject.FindProperty("followScaleMode");
 			followSkeletonFlip = serializedObject.FindProperty("followSkeletonFlip");
 			followSkeletonFlip = serializedObject.FindProperty("followSkeletonFlip");
 
 
 			targetBoneFollower = (BoneFollower)target;
 			targetBoneFollower = (BoneFollower)target;
@@ -175,7 +176,12 @@ namespace Spine.Unity.Editor {
 				EditorGUILayout.PropertyField(followBoneRotation);
 				EditorGUILayout.PropertyField(followBoneRotation);
 				EditorGUILayout.PropertyField(followXYPosition);
 				EditorGUILayout.PropertyField(followXYPosition);
 				EditorGUILayout.PropertyField(followZPosition);
 				EditorGUILayout.PropertyField(followZPosition);
-				EditorGUILayout.PropertyField(followLocalScale);
+				EditorGUILayout.PropertyField(followScale);
+				if (followScale.boolValue == true || followScale.hasMultipleDifferentValues) {
+					using (new SpineInspectorUtility.IndentScope()) {
+						EditorGUILayout.PropertyField(followScaleMode, new GUIContent("Mode"));
+					}
+				}
 				EditorGUILayout.PropertyField(followSkeletonFlip);
 				EditorGUILayout.PropertyField(followSkeletonFlip);
 
 
 				BoneFollowerInspector.RecommendRigidbodyButton(targetBoneFollower);
 				BoneFollowerInspector.RecommendRigidbodyButton(targetBoneFollower);

+ 23 - 5
spine-unity/Assets/Spine/Runtime/spine-unity/Components/Following/BoneFollower.cs

@@ -46,6 +46,11 @@ namespace Spine.Unity {
 	public class BoneFollower : MonoBehaviour {
 	public class BoneFollower : MonoBehaviour {
 
 
 		#region Inspector
 		#region Inspector
+		public enum ScaleMode {
+			Local = 0,
+			WorldUniform
+		}
+
 		public SkeletonRenderer skeletonRenderer;
 		public SkeletonRenderer skeletonRenderer;
 		public SkeletonRenderer SkeletonRenderer {
 		public SkeletonRenderer SkeletonRenderer {
 			get { return skeletonRenderer; }
 			get { return skeletonRenderer; }
@@ -66,8 +71,12 @@ namespace Spine.Unity {
 		[Tooltip("Follows the skeleton's flip state by controlling this Transform's local scale.")]
 		[Tooltip("Follows the skeleton's flip state by controlling this Transform's local scale.")]
 		public bool followSkeletonFlip = true;
 		public bool followSkeletonFlip = true;
 
 
-		[Tooltip("Follows the target bone's local scale. BoneFollower cannot inherit world/skewed scale because of UnityEngine.Transform property limitations.")]
-		public bool followLocalScale = false;
+		[Tooltip("Follows the target bone's scale.")]
+		[UnityEngine.Serialization.FormerlySerializedAs("followLocalScale")]
+		public bool followScale = false;
+
+		[Tooltip("Follows the target bone's local or uniform world scale. Note: If world scale is non-uniform/skewed, you will receive incorrect results with WorldUniform.")]
+		public ScaleMode followScaleMode = ScaleMode.Local;
 
 
 		[UnityEngine.Serialization.FormerlySerializedAs("resetOnAwake")]
 		[UnityEngine.Serialization.FormerlySerializedAs("resetOnAwake")]
 		public bool initializeOnAwake = true;
 		public bool initializeOnAwake = true;
@@ -148,7 +157,10 @@ namespace Spine.Unity {
 														followZPosition ? 0f : thisTransform.localPosition.z);
 														followZPosition ? 0f : thisTransform.localPosition.z);
 				if (followBoneRotation) {
 				if (followBoneRotation) {
 					float halfRotation = Mathf.Atan2(bone.c, bone.a) * 0.5f;
 					float halfRotation = Mathf.Atan2(bone.c, bone.a) * 0.5f;
-					if (followLocalScale && bone.scaleX < 0) // Negate rotation from negative scaleX. Don't use negative determinant. local scaleY doesn't factor into used rotation.
+					if (followScale &&
+						(followScaleMode == ScaleMode.Local ?
+						 (bone.scaleX < 0) :
+						 (bone.WorldScaleX < 0))) // Negate rotation from negative scaleX. Don't use negative determinant. local scaleY doesn't factor into used rotation.
 						halfRotation += Mathf.PI * 0.5f;
 						halfRotation += Mathf.PI * 0.5f;
 
 
 					var q = default(Quaternion);
 					var q = default(Quaternion);
@@ -176,14 +188,20 @@ namespace Spine.Unity {
 
 
 				if (followBoneRotation) {
 				if (followBoneRotation) {
 					Vector3 worldRotation = skeletonTransform.rotation.eulerAngles;
 					Vector3 worldRotation = skeletonTransform.rotation.eulerAngles;
-					if (followLocalScale && bone.scaleX < 0) boneWorldRotation += 180f;
+					if (followScale &&
+						(followScaleMode == ScaleMode.Local ?
+						 (bone.scaleX < 0) :
+						 (bone.WorldScaleX < 0))) boneWorldRotation += 180f;
 					thisTransform.SetPositionAndRotation(targetWorldPosition, Quaternion.Euler(worldRotation.x, worldRotation.y, worldRotation.z + boneWorldRotation));
 					thisTransform.SetPositionAndRotation(targetWorldPosition, Quaternion.Euler(worldRotation.x, worldRotation.y, worldRotation.z + boneWorldRotation));
 				} else {
 				} else {
 					thisTransform.position = targetWorldPosition;
 					thisTransform.position = targetWorldPosition;
 				}
 				}
 			}
 			}
 
 
-			Vector3 localScale = followLocalScale ? new Vector3(bone.scaleX, bone.scaleY, 1f) : new Vector3(1f, 1f, 1f);
+			Vector3 localScale = followScale ? (followScaleMode == ScaleMode.Local ?
+				new Vector3(bone.scaleX, bone.scaleY, 1f) :
+				new Vector3(bone.WorldScaleX, bone.WorldScaleY, 1f)) :
+				new Vector3(1f, 1f, 1f);
 			if (followSkeletonFlip) localScale.y *= Mathf.Sign(bone.skeleton.ScaleX * bone.skeleton.ScaleY);
 			if (followSkeletonFlip) localScale.y *= Mathf.Sign(bone.skeleton.ScaleX * bone.skeleton.ScaleY);
 			thisTransform.localScale = localScale;
 			thisTransform.localScale = localScale;
 		}
 		}