From 315337aa871e1586d3a2ee534090cd648ae30b84 Mon Sep 17 00:00:00 2001 From: Mario Zechner Date: Wed, 1 Feb 2017 14:11:33 +0100 Subject: [PATCH 1/8] Update README.md --- spine-ue4/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spine-ue4/README.md b/spine-ue4/README.md index 2bf134974..15f78d977 100644 --- a/spine-ue4/README.md +++ b/spine-ue4/README.md @@ -1,7 +1,7 @@ # spine-ue4 The spine-ue4 runtime provides functionality to load, manipulate and render [Spine](http://esotericsoftware.com) skeletal animation data using [Unreal Engine 4.15+](https://www.unrealengine.com/). spine-ue4 is based on [spine-c](https://github.com/EsotericSoftware/spine-runtimes/tree/master/spine-c). -# WARNING This plugin will only work with Unreal Engine 4.15 and later versions as these include a [fix](https://github.com/EpicGames/UnrealEngine/pull/3015) for compiling plain `.c` files in Visual Studio. +### WARNING This plugin will only work with Unreal Engine 4.15 and later when this [fix](https://github.com/EpicGames/UnrealEngine/pull/3185) for compiling plain `.c` files is applied. ## Licensing From 95527b630a0c50b2eec41a988c971688e9f0f49e Mon Sep 17 00:00:00 2001 From: Mario Zechner Date: Thu, 2 Feb 2017 10:56:46 +0100 Subject: [PATCH 2/8] [c] Added void* userData field to spTrackEntry. Can be fetched in listeners. --- spine-c/spine-c/include/spine/AnimationState.h | 1 + 1 file changed, 1 insertion(+) diff --git a/spine-c/spine-c/include/spine/AnimationState.h b/spine-c/spine-c/include/spine/AnimationState.h index ebfba21f8..a2d68500d 100644 --- a/spine-c/spine-c/include/spine/AnimationState.h +++ b/spine-c/spine-c/include/spine/AnimationState.h @@ -64,6 +64,7 @@ struct spTrackEntry { float* timelinesRotation; int timelinesRotationCount; void* rendererObject; + void* userData; #ifdef __cplusplus spTrackEntry() : From 986e74f62b1739e6ec2dbe28e81cd2a275eb8e76 Mon Sep 17 00:00:00 2001 From: pharan Date: Mon, 6 Feb 2017 06:48:47 +0800 Subject: [PATCH 3/8] [unity] Sample scripts now use properties. --- .../Scripts/BasicPlatformerController.cs | 2 +- .../Getting Started/Scripts/SpineBeginnerTwo.cs | 4 ++-- .../Getting Started/Scripts/SpineBlinkPlayer.cs | 2 +- .../Scripts/SpineboyBeginnerView.cs | 10 +++++----- .../Assets/Examples/Scripts/AttackSpineboy.cs | 6 +++--- .../Examples/Scripts/FootSoldierExample.cs | 8 ++++---- spine-unity/Assets/Examples/Scripts/Goblins.cs | 12 ++++++------ .../Assets/Examples/Scripts/MixAndMatch.cs | 2 +- spine-unity/Assets/Examples/Scripts/Spineboy.cs | 16 ++++++++-------- 9 files changed, 31 insertions(+), 31 deletions(-) diff --git a/spine-unity/Assets/Examples/Getting Started/Scripts/BasicPlatformerController.cs b/spine-unity/Assets/Examples/Getting Started/Scripts/BasicPlatformerController.cs index 9209dbc73..63590c0fe 100644 --- a/spine-unity/Assets/Examples/Getting Started/Scripts/BasicPlatformerController.cs +++ b/spine-unity/Assets/Examples/Getting Started/Scripts/BasicPlatformerController.cs @@ -93,7 +93,7 @@ namespace Spine.Unity.Examples { void Start () { // Register a callback for Spine Events (in this case, Footstep) - skeletonAnimation.state.Event += HandleEvent; + skeletonAnimation.AnimationState.Event += HandleEvent; } void HandleEvent (Spine.TrackEntry trackEntry, Spine.Event e) { diff --git a/spine-unity/Assets/Examples/Getting Started/Scripts/SpineBeginnerTwo.cs b/spine-unity/Assets/Examples/Getting Started/Scripts/SpineBeginnerTwo.cs index b53e1613f..ab89ae727 100644 --- a/spine-unity/Assets/Examples/Getting Started/Scripts/SpineBeginnerTwo.cs +++ b/spine-unity/Assets/Examples/Getting Started/Scripts/SpineBeginnerTwo.cs @@ -59,8 +59,8 @@ namespace Spine.Unity.Examples { void Start () { // Make sure you get these AnimationState and Skeleton references in Start or Later. Getting and using them in Awake is not guaranteed by default execution order. skeletonAnimation = GetComponent(); - spineAnimationState = skeletonAnimation.state; - skeleton = skeletonAnimation.skeleton; + spineAnimationState = skeletonAnimation.AnimationState; + skeleton = skeletonAnimation.Skeleton; StartCoroutine(DoDemoRoutine()); } diff --git a/spine-unity/Assets/Examples/Getting Started/Scripts/SpineBlinkPlayer.cs b/spine-unity/Assets/Examples/Getting Started/Scripts/SpineBlinkPlayer.cs index cf9393511..8b815702b 100644 --- a/spine-unity/Assets/Examples/Getting Started/Scripts/SpineBlinkPlayer.cs +++ b/spine-unity/Assets/Examples/Getting Started/Scripts/SpineBlinkPlayer.cs @@ -44,7 +44,7 @@ namespace Spine.Unity.Examples { IEnumerator Start () { var skeletonAnimation = GetComponent(); if (skeletonAnimation == null) yield break; while (true) { - skeletonAnimation.state.SetAnimation(SpineBlinkPlayer.BlinkTrack, blinkAnimation, false); + skeletonAnimation.AnimationState.SetAnimation(SpineBlinkPlayer.BlinkTrack, blinkAnimation, false); yield return new WaitForSeconds(Random.Range(minimumDelay, maximumDelay)); } } diff --git a/spine-unity/Assets/Examples/Getting Started/Scripts/SpineboyBeginnerView.cs b/spine-unity/Assets/Examples/Getting Started/Scripts/SpineboyBeginnerView.cs index 8c382c534..e5a711123 100644 --- a/spine-unity/Assets/Examples/Getting Started/Scripts/SpineboyBeginnerView.cs +++ b/spine-unity/Assets/Examples/Getting Started/Scripts/SpineboyBeginnerView.cs @@ -57,7 +57,7 @@ namespace Spine.Unity.Examples { void Start () { if (skeletonAnimation == null) return; model.ShootEvent += PlayShoot; - skeletonAnimation.state.Event += HandleEvent; + skeletonAnimation.AnimationState.Event += HandleEvent; } void HandleEvent (Spine.TrackEntry trackEntry, Spine.Event e) { @@ -104,7 +104,7 @@ namespace Spine.Unity.Examples { } } - skeletonAnimation.state.SetAnimation(0, nextAnimation, true); + skeletonAnimation.AnimationState.SetAnimation(0, nextAnimation, true); } void PlayFootstepSound () { @@ -114,7 +114,7 @@ namespace Spine.Unity.Examples { [ContextMenu("Check Tracks")] void CheckTracks () { - var state = skeletonAnimation.state; + var state = skeletonAnimation.AnimationState; Debug.Log(state.GetCurrent(0)); Debug.Log(state.GetCurrent(1)); } @@ -122,7 +122,7 @@ namespace Spine.Unity.Examples { #region Transient Actions public void PlayShoot () { // Play the shoot animation on track 1. - skeletonAnimation.state.SetAnimation(1, shoot, false); + skeletonAnimation.AnimationState.SetAnimation(1, shoot, false); //skeletonAnimation.state.AddEmptyAnimation(1, 0.1f, 0f); gunSource.pitch = GetRandomPitch(gunsoundPitchOffset); gunSource.Play(); @@ -131,7 +131,7 @@ namespace Spine.Unity.Examples { } public void Turn (bool facingLeft) { - skeletonAnimation.skeleton.FlipX = facingLeft; + skeletonAnimation.Skeleton.FlipX = facingLeft; // Maybe play a transient turning animation too, then call ChangeStableAnimation. } #endregion diff --git a/spine-unity/Assets/Examples/Scripts/AttackSpineboy.cs b/spine-unity/Assets/Examples/Scripts/AttackSpineboy.cs index 5579ed32d..ef50581e6 100644 --- a/spine-unity/Assets/Examples/Scripts/AttackSpineboy.cs +++ b/spine-unity/Assets/Examples/Scripts/AttackSpineboy.cs @@ -47,13 +47,13 @@ namespace Spine.Unity.Examples { healthText.text = currentHealth + "/" + maxHealth; if (currentHealth > 0) { - spineboy.state.SetAnimation(0, "hit", false); - spineboy.state.AddAnimation(0, "idle", true, 0); + spineboy.AnimationState.SetAnimation(0, "hit", false); + spineboy.AnimationState.AddAnimation(0, "idle", true, 0); gauge.fillPercent = (float)currentHealth/(float)maxHealth; } else { if (currentHealth >= 0) { gauge.fillPercent = 0; - spineboy.state.SetAnimation(0, "death", false).TrackEnd = float.PositiveInfinity; + spineboy.AnimationState.SetAnimation(0, "death", false).TrackEnd = float.PositiveInfinity; } } } diff --git a/spine-unity/Assets/Examples/Scripts/FootSoldierExample.cs b/spine-unity/Assets/Examples/Scripts/FootSoldierExample.cs index 4ae760744..08cf1a6a7 100644 --- a/spine-unity/Assets/Examples/Scripts/FootSoldierExample.cs +++ b/spine-unity/Assets/Examples/Scripts/FootSoldierExample.cs @@ -80,11 +80,11 @@ namespace Spine.Unity.Examples { } else { if (Input.GetKey(rightKey)) { skeletonAnimation.AnimationName = moveAnimation; - skeletonAnimation.skeleton.FlipX = false; + skeletonAnimation.Skeleton.FlipX = false; transform.Translate(moveSpeed * Time.deltaTime, 0, 0); } else if(Input.GetKey(leftKey)) { skeletonAnimation.AnimationName = moveAnimation; - skeletonAnimation.skeleton.FlipX = true; + skeletonAnimation.Skeleton.FlipX = true; transform.Translate(-moveSpeed * Time.deltaTime, 0, 0); } else { skeletonAnimation.AnimationName = idleAnimation; @@ -95,9 +95,9 @@ namespace Spine.Unity.Examples { IEnumerator Blink() { while (true) { yield return new WaitForSeconds(Random.Range(0.25f, 3f)); - skeletonAnimation.skeleton.SetAttachment(eyesSlot, blinkAttachment); + skeletonAnimation.Skeleton.SetAttachment(eyesSlot, blinkAttachment); yield return new WaitForSeconds(blinkDuration); - skeletonAnimation.skeleton.SetAttachment(eyesSlot, eyesOpenAttachment); + skeletonAnimation.Skeleton.SetAttachment(eyesSlot, eyesOpenAttachment); } } } diff --git a/spine-unity/Assets/Examples/Scripts/Goblins.cs b/spine-unity/Assets/Examples/Scripts/Goblins.cs index 2dc3232c3..1fe1f5b55 100644 --- a/spine-unity/Assets/Examples/Scripts/Goblins.cs +++ b/spine-unity/Assets/Examples/Scripts/Goblins.cs @@ -43,7 +43,7 @@ namespace Spine.Unity.Examples { public void Start () { skeletonAnimation = GetComponent(); - headBone = skeletonAnimation.skeleton.FindBone("head"); + headBone = skeletonAnimation.Skeleton.FindBone("head"); skeletonAnimation.UpdateLocal += UpdateLocal; } @@ -53,16 +53,16 @@ namespace Spine.Unity.Examples { } public void OnMouseDown () { - skeletonAnimation.skeleton.SetSkin(girlSkin ? "goblin" : "goblingirl"); - skeletonAnimation.skeleton.SetSlotsToSetupPose(); + skeletonAnimation.Skeleton.SetSkin(girlSkin ? "goblin" : "goblingirl"); + skeletonAnimation.Skeleton.SetSlotsToSetupPose(); girlSkin = !girlSkin; if (girlSkin) { - skeletonAnimation.skeleton.SetAttachment("right hand item", null); - skeletonAnimation.skeleton.SetAttachment("left hand item", "spear"); + skeletonAnimation.Skeleton.SetAttachment("right hand item", null); + skeletonAnimation.Skeleton.SetAttachment("left hand item", "spear"); } else - skeletonAnimation.skeleton.SetAttachment("left hand item", "dagger"); + skeletonAnimation.Skeleton.SetAttachment("left hand item", "dagger"); } } } \ No newline at end of file diff --git a/spine-unity/Assets/Examples/Scripts/MixAndMatch.cs b/spine-unity/Assets/Examples/Scripts/MixAndMatch.cs index c404dbdc2..35dd08d9a 100644 --- a/spine-unity/Assets/Examples/Scripts/MixAndMatch.cs +++ b/spine-unity/Assets/Examples/Scripts/MixAndMatch.cs @@ -76,7 +76,7 @@ namespace Spine.Unity.Examples { // Case 1: Create an attachment from an atlas. RegionAttachment newHand = handSource.GetAtlas().FindRegion(handRegion).ToRegionAttachment("new hand"); newHand.SetPositionOffset(newHandOffset); - newHand.rotation = newHandRotation; + newHand.Rotation = newHandRotation; newHand.UpdateOffset(); int handSlotIndex = skeleton.FindSlotIndex(handSlot); handTexture = newHand.GetRegion().ToTexture(); diff --git a/spine-unity/Assets/Examples/Scripts/Spineboy.cs b/spine-unity/Assets/Examples/Scripts/Spineboy.cs index 3705ad99e..5afc98e8c 100644 --- a/spine-unity/Assets/Examples/Scripts/Spineboy.cs +++ b/spine-unity/Assets/Examples/Scripts/Spineboy.cs @@ -29,7 +29,6 @@ *****************************************************************************/ using UnityEngine; - using Spine; using Spine.Unity; @@ -39,21 +38,22 @@ namespace Spine.Unity.Examples { public void Start () { skeletonAnimation = GetComponent(); // Get the SkeletonAnimation component for the GameObject this script is attached to. + var animationState = skeletonAnimation.AnimationState; - skeletonAnimation.state.Event += HandleEvent;; // Call our method any time an animation fires an event. - skeletonAnimation.state.End += (entry) => Debug.Log("start: " + entry.trackIndex); // A lambda can be used for the callback instead of a method. + animationState.Event += HandleEvent;; // Call our method any time an animation fires an event. + animationState.End += (entry) => Debug.Log("start: " + entry.TrackIndex); // A lambda can be used for the callback instead of a method. - skeletonAnimation.state.AddAnimation(0, "jump", false, 2); // Queue jump to be played on track 0 two seconds after the starting animation. - skeletonAnimation.state.AddAnimation(0, "run", true, 0); // Queue walk to be looped on track 0 after the jump animation. + animationState.AddAnimation(0, "jump", false, 2); // Queue jump to be played on track 0 two seconds after the starting animation. + animationState.AddAnimation(0, "run", true, 0); // Queue walk to be looped on track 0 after the jump animation. } void HandleEvent (TrackEntry trackEntry, Spine.Event e) { - Debug.Log(trackEntry.trackIndex + " " + trackEntry.animation.name + ": event " + e + ", " + e.Int); + Debug.Log(trackEntry.TrackIndex + " " + trackEntry.Animation.Name + ": event " + e + ", " + e.Int); } public void OnMouseDown () { - skeletonAnimation.state.SetAnimation(0, "jump", false); // Set jump to be played on track 0 immediately. - skeletonAnimation.state.AddAnimation(0, "run", true, 0); // Queue walk to be looped on track 0 after the jump animation. + skeletonAnimation.AnimationState.SetAnimation(0, "jump", false); // Set jump to be played on track 0 immediately. + skeletonAnimation.AnimationState.AddAnimation(0, "run", true, 0); // Queue walk to be looped on track 0 after the jump animation. } } From 1650b2bd209631a05b9d9c009227195c1ead9726 Mon Sep 17 00:00:00 2001 From: John Date: Mon, 6 Feb 2017 07:02:04 +0800 Subject: [PATCH 4/8] [csharp] Added to docs in Skin.cs --- spine-csharp/src/Skin.cs | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/spine-csharp/src/Skin.cs b/spine-csharp/src/Skin.cs index 318779f77..973e49129 100644 --- a/spine-csharp/src/Skin.cs +++ b/spine-csharp/src/Skin.cs @@ -32,38 +32,47 @@ using System; using System.Collections.Generic; namespace Spine { - /// Stores attachments by slot index and attachment name. + /// Stores attachments by slot index and attachment name. + /// See SkeletonData , Skeleton , and + /// Runtime skins in the Spine Runtimes Guide. + /// public class Skin { internal String name; private Dictionary attachments = new Dictionary(AttachmentKeyTupleComparer.Instance); - public String Name { get { return name; } } + public string Name { get { return name; } } public Dictionary Attachments { get { return attachments; } } - public Skin (String name) { + public Skin (string name) { if (name == null) throw new ArgumentNullException("name", "name cannot be null."); this.name = name; } - public void AddAttachment (int slotIndex, String name, Attachment attachment) { + public void AddAttachment (int slotIndex, string name, Attachment attachment) { if (attachment == null) throw new ArgumentNullException("attachment", "attachment cannot be null."); attachments[new AttachmentKeyTuple(slotIndex, name)] = attachment; } /// May be null. - public Attachment GetAttachment (int slotIndex, String name) { + public Attachment GetAttachment (int slotIndex, string name) { Attachment attachment; attachments.TryGetValue(new AttachmentKeyTuple(slotIndex, name), out attachment); return attachment; } - public void FindNamesForSlot (int slotIndex, List names) { + /// Finds the skin keys for a given slot. The results are added to the passed List(names). + /// The target slotIndex. To find the slot index, use or + /// Found skin key names will be added to this list. + public void FindNamesForSlot (int slotIndex, List names) { if (names == null) throw new ArgumentNullException("names", "names cannot be null."); foreach (AttachmentKeyTuple key in attachments.Keys) if (key.slotIndex == slotIndex) names.Add(key.name); } + /// Finds the attachments for a given slot. The results are added to the passed List(Attachment). + /// The target slotIndex. To find the slot index, use or + /// Found Attachments will be added to this list. public void FindAttachmentsForSlot (int slotIndex, List attachments) { if (attachments == null) throw new ArgumentNullException("attachments", "attachments cannot be null."); foreach (KeyValuePair entry in this.attachments) From 30fcad4718a6aec028a4916d6c7b9c5a0e7cd65c Mon Sep 17 00:00:00 2001 From: pharan Date: Thu, 9 Feb 2017 07:46:57 +0800 Subject: [PATCH 5/8] [unity] Fix BoneFollower inspector. --- .../Editor/BoneFollowerInspector.cs | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/spine-unity/Assets/spine-unity/Editor/BoneFollowerInspector.cs b/spine-unity/Assets/spine-unity/Editor/BoneFollowerInspector.cs index f7ecf47d9..58ac0fce0 100644 --- a/spine-unity/Assets/spine-unity/Editor/BoneFollowerInspector.cs +++ b/spine-unity/Assets/spine-unity/Editor/BoneFollowerInspector.cs @@ -74,6 +74,13 @@ namespace Spine.Unity.Editor { targetBoneFollower = (BoneFollower)target; if (targetBoneFollower.SkeletonRenderer != null) targetBoneFollower.SkeletonRenderer.Initialize(false); + + if (!targetBoneFollower.valid || needsReset) { + targetBoneFollower.Initialize(); + targetBoneFollower.LateUpdate(); + needsReset = false; + SceneView.RepaintAll(); + } } public void OnSceneGUI () { @@ -114,7 +121,7 @@ namespace Spine.Unity.Editor { return; } - if (needsReset) { + if (needsReset && UnityEngine.Event.current.type == EventType.Layout) { targetBoneFollower.Initialize(); targetBoneFollower.LateUpdate(); needsReset = false; @@ -143,11 +150,8 @@ namespace Spine.Unity.Editor { if (targetBoneFollower.valid) { EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(boneName); - if (EditorGUI.EndChangeCheck()) { - serializedObject.ApplyModifiedProperties(); - needsReset = true; - serializedObject.Update(); - } + needsReset |= EditorGUI.EndChangeCheck(); + EditorGUILayout.PropertyField(followBoneRotation); EditorGUILayout.PropertyField(followZPosition); EditorGUILayout.PropertyField(followLocalScale); @@ -169,8 +173,10 @@ namespace Spine.Unity.Editor { var current = UnityEngine.Event.current; bool wasUndo = (current.type == EventType.ValidateCommand && current.commandName == "UndoRedoPerformed"); - if (serializedObject.ApplyModifiedProperties() || wasUndo) + if (wasUndo) targetBoneFollower.Initialize(); + + serializedObject.ApplyModifiedProperties(); } } From 444ef0feeeb129bc2dbcd42da40d0b5a1018c20d Mon Sep 17 00:00:00 2001 From: pharan Date: Thu, 9 Feb 2017 07:47:52 +0800 Subject: [PATCH 6/8] [unity] Added version.txt --- spine-unity/Assets/spine-unity/version.txt | 1 + spine-unity/Assets/spine-unity/version.txt.meta | 8 ++++++++ 2 files changed, 9 insertions(+) create mode 100644 spine-unity/Assets/spine-unity/version.txt create mode 100644 spine-unity/Assets/spine-unity/version.txt.meta diff --git a/spine-unity/Assets/spine-unity/version.txt b/spine-unity/Assets/spine-unity/version.txt new file mode 100644 index 000000000..dedefb0b3 --- /dev/null +++ b/spine-unity/Assets/spine-unity/version.txt @@ -0,0 +1 @@ +This Spine-Unity runtime works with data exported from Spine Editor version: 3.5.xx \ No newline at end of file diff --git a/spine-unity/Assets/spine-unity/version.txt.meta b/spine-unity/Assets/spine-unity/version.txt.meta new file mode 100644 index 000000000..d34c5b7dc --- /dev/null +++ b/spine-unity/Assets/spine-unity/version.txt.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 80c06a67282e71043a4b1fad3e0c5654 +timeCreated: 1485965987 +licenseType: Free +TextScriptImporter: + userData: + assetBundleName: + assetBundleVariant: From 0ebc2e471f22a6f8fb510ce8757a0c683a64333c Mon Sep 17 00:00:00 2001 From: pharan Date: Thu, 9 Feb 2017 07:48:46 +0800 Subject: [PATCH 7/8] [unity] Fixed AtlasRegion.ToTexture scope. --- .../spine-unity/Modules/AttachmentTools/AttachmentTools.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spine-unity/Assets/spine-unity/Modules/AttachmentTools/AttachmentTools.cs b/spine-unity/Assets/spine-unity/Modules/AttachmentTools/AttachmentTools.cs index 09d7e3c08..b94145e19 100644 --- a/spine-unity/Assets/spine-unity/Modules/AttachmentTools/AttachmentTools.cs +++ b/spine-unity/Assets/spine-unity/Modules/AttachmentTools/AttachmentTools.cs @@ -341,7 +341,7 @@ namespace Spine.Unity.Modules.AttachmentTools { return Sprite.Create(ar.GetMainTexture(), ar.GetUnityRect(), new Vector2(0.5f, 0.5f), pixelsPerUnit); } - internal static Texture2D ToTexture (this AtlasRegion ar, bool applyImmediately = true) { + public static Texture2D ToTexture (this AtlasRegion ar, bool applyImmediately = true) { Texture2D sourceTexture = ar.GetMainTexture(); Rect r = ar.GetUnityRect(sourceTexture.height); Texture2D output = new Texture2D((int)r.width, (int)r.height); From 80a0bc90abfad55545e011a8fb8b2f974d880474 Mon Sep 17 00:00:00 2001 From: badlogic Date: Thu, 9 Feb 2017 11:21:42 +0100 Subject: [PATCH 8/8] Fixed pan in SkeletonViewer --- .../esotericsoftware/spine/SkeletonViewer.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/spine-libgdx/spine-skeletonviewer/src/com/esotericsoftware/spine/SkeletonViewer.java b/spine-libgdx/spine-skeletonviewer/src/com/esotericsoftware/spine/SkeletonViewer.java index 9937a5ec5..40c6fda83 100644 --- a/spine-libgdx/spine-skeletonviewer/src/com/esotericsoftware/spine/SkeletonViewer.java +++ b/spine-libgdx/spine-skeletonviewer/src/com/esotericsoftware/spine/SkeletonViewer.java @@ -661,14 +661,24 @@ public class SkeletonViewer extends ApplicationAdapter { button.addListener(trackButtonListener); Gdx.input.setInputProcessor(new InputMultiplexer(stage, new InputAdapter() { + float offsetX; + float offsetY; + public boolean touchDown (int screenX, int screenY, int pointer, int button) { - touchDragged(screenX, screenY, pointer); + offsetX = screenX; + offsetY = Gdx.graphics.getHeight() - screenY; return false; } public boolean touchDragged (int screenX, int screenY, int pointer) { - skeletonX = screenX; - skeletonY = Gdx.graphics.getHeight() - screenY; + float deltaX = screenX - offsetX; + float deltaY = Gdx.graphics.getHeight() - screenY - offsetY; + + skeletonX += deltaX; + skeletonY += deltaY; + + offsetX = screenX; + offsetY = Gdx.graphics.getHeight() - screenY; return false; }