提交Spine插件
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated May 1, 2019. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2019, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
* NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS
|
||||
* INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#if UNITY_2017 || UNITY_2018 || (UNITY_2019_1_OR_NEWER && SPINE_TIMELINE_PACKAGE_DOWNLOADED)
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Playables;
|
||||
using UnityEngine.Timeline;
|
||||
using Spine;
|
||||
using Spine.Unity;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Spine.Unity.Playables {
|
||||
|
||||
using Animation = Spine.Animation;
|
||||
|
||||
[Serializable]
|
||||
public class SpineAnimationStateBehaviour : PlayableBehaviour {
|
||||
public AnimationReferenceAsset animationReference;
|
||||
public bool loop;
|
||||
|
||||
[Header("Mix Properties")]
|
||||
public bool customDuration = false;
|
||||
public float mixDuration = 0.1f;
|
||||
|
||||
[Range(0, 1f)]
|
||||
public float attachmentThreshold = 0.5f;
|
||||
|
||||
[Range(0, 1f)]
|
||||
public float eventThreshold = 0.5f;
|
||||
|
||||
[Range(0, 1f)]
|
||||
public float drawOrderThreshold = 0.5f;
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 82bd6e7ec1121b5428c447b7bd16b042
|
||||
timeCreated: 1510816616
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,51 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated May 1, 2019. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2019, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
* NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS
|
||||
* INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#if UNITY_2017 || UNITY_2018 || (UNITY_2019_1_OR_NEWER && SPINE_TIMELINE_PACKAGE_DOWNLOADED)
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Playables;
|
||||
using UnityEngine.Timeline;
|
||||
|
||||
namespace Spine.Unity.Playables {
|
||||
[Serializable]
|
||||
public class SpineAnimationStateClip : PlayableAsset, ITimelineClipAsset {
|
||||
public SpineAnimationStateBehaviour template = new SpineAnimationStateBehaviour();
|
||||
|
||||
public ClipCaps clipCaps { get { return ClipCaps.None; } }
|
||||
|
||||
public override Playable CreatePlayable (PlayableGraph graph, GameObject owner) {
|
||||
var playable = ScriptPlayable<SpineAnimationStateBehaviour>.Create(graph, template);
|
||||
playable.GetBehaviour(); //SpineAnimationStateBehaviour clone = playable.GetBehaviour();
|
||||
return playable;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 585e20c924ba86a44926c850aa8e1d84
|
||||
timeCreated: 1510816616
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,195 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated May 1, 2019. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2019, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
* NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS
|
||||
* INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#define SPINE_EDITMODEPOSE
|
||||
|
||||
#if UNITY_2017 || UNITY_2018 || (UNITY_2019_1_OR_NEWER && SPINE_TIMELINE_PACKAGE_DOWNLOADED)
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Playables;
|
||||
using UnityEngine.Timeline;
|
||||
|
||||
namespace Spine.Unity.Playables {
|
||||
public class SpineAnimationStateMixerBehaviour : PlayableBehaviour {
|
||||
|
||||
float[] lastInputWeights;
|
||||
public int trackIndex;
|
||||
|
||||
// NOTE: This function is called at runtime and edit time. Keep that in mind when setting the values of properties.
|
||||
public override void ProcessFrame (Playable playable, FrameData info, object playerData) {
|
||||
var spineComponent = playerData as SkeletonAnimation;
|
||||
if (spineComponent == null) return;
|
||||
|
||||
var skeleton = spineComponent.Skeleton;
|
||||
var state = spineComponent.AnimationState;
|
||||
|
||||
if (!Application.isPlaying) {
|
||||
#if SPINE_EDITMODEPOSE
|
||||
PreviewEditModePose(playable, spineComponent);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
int inputCount = playable.GetInputCount();
|
||||
|
||||
// Ensure correct buffer size.
|
||||
if (this.lastInputWeights == null || this.lastInputWeights.Length < inputCount) {
|
||||
this.lastInputWeights = new float[inputCount];
|
||||
|
||||
for (int i = 0; i < inputCount; i++)
|
||||
this.lastInputWeights[i] = default(float);
|
||||
}
|
||||
var lastInputWeights = this.lastInputWeights;
|
||||
|
||||
// Check all clips. If a clip that was weight 0 turned into weight 1, call SetAnimation.
|
||||
for (int i = 0; i < inputCount; i++) {
|
||||
float lastInputWeight = lastInputWeights[i];
|
||||
float inputWeight = playable.GetInputWeight(i);
|
||||
bool trackStarted = inputWeight > lastInputWeight;
|
||||
lastInputWeights[i] = inputWeight;
|
||||
|
||||
if (trackStarted) {
|
||||
ScriptPlayable<SpineAnimationStateBehaviour> inputPlayable = (ScriptPlayable<SpineAnimationStateBehaviour>)playable.GetInput(i);
|
||||
SpineAnimationStateBehaviour clipData = inputPlayable.GetBehaviour();
|
||||
|
||||
if (clipData.animationReference == null) {
|
||||
float mixDuration = clipData.customDuration ? clipData.mixDuration : state.Data.DefaultMix;
|
||||
state.SetEmptyAnimation(trackIndex, mixDuration);
|
||||
} else {
|
||||
if (clipData.animationReference.Animation != null) {
|
||||
Spine.TrackEntry trackEntry = state.SetAnimation(trackIndex, clipData.animationReference.Animation, clipData.loop);
|
||||
|
||||
//trackEntry.TrackTime = (float)inputPlayable.GetTime(); // More accurate time-start?
|
||||
trackEntry.EventThreshold = clipData.eventThreshold;
|
||||
trackEntry.DrawOrderThreshold = clipData.drawOrderThreshold;
|
||||
trackEntry.AttachmentThreshold = clipData.attachmentThreshold;
|
||||
|
||||
if (clipData.customDuration)
|
||||
trackEntry.MixDuration = clipData.mixDuration;
|
||||
}
|
||||
//else Debug.LogWarningFormat("Animation named '{0}' not found", clipData.animationName);
|
||||
}
|
||||
|
||||
// Ensure that the first frame ends with an updated mesh.
|
||||
spineComponent.Update(0);
|
||||
spineComponent.LateUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if SPINE_EDITMODEPOSE
|
||||
|
||||
AnimationState dummyAnimationState;
|
||||
|
||||
public void PreviewEditModePose (Playable playable, SkeletonAnimation spineComponent) {
|
||||
if (Application.isPlaying) return;
|
||||
if (spineComponent == null) return;
|
||||
|
||||
int inputCount = playable.GetInputCount();
|
||||
int lastOneWeight = -1;
|
||||
|
||||
for (int i = 0; i < inputCount; i++) {
|
||||
float inputWeight = playable.GetInputWeight(i);
|
||||
if (inputWeight >= 1) lastOneWeight = i;
|
||||
}
|
||||
|
||||
if (lastOneWeight != -1) {
|
||||
ScriptPlayable<SpineAnimationStateBehaviour> inputPlayableClip = (ScriptPlayable<SpineAnimationStateBehaviour>)playable.GetInput(lastOneWeight);
|
||||
SpineAnimationStateBehaviour clipData = inputPlayableClip.GetBehaviour();
|
||||
|
||||
var skeleton = spineComponent.Skeleton;
|
||||
|
||||
bool skeletonDataMismatch = clipData.animationReference != null && spineComponent.SkeletonDataAsset.GetSkeletonData(true) != clipData.animationReference.SkeletonDataAsset.GetSkeletonData(true);
|
||||
if (skeletonDataMismatch) {
|
||||
Debug.LogWarningFormat("SpineAnimationStateMixerBehaviour tried to apply an animation for the wrong skeleton. Expected {0}. Was {1}", spineComponent.SkeletonDataAsset, clipData.animationReference.SkeletonDataAsset);
|
||||
}
|
||||
|
||||
// Getting the from-animation here because it's required to get the mix information from AnimationStateData.
|
||||
Animation fromAnimation = null;
|
||||
float fromClipTime = 0;
|
||||
bool fromClipLoop = false;
|
||||
if (lastOneWeight != 0 && inputCount > 1) {
|
||||
var fromClip = (ScriptPlayable<SpineAnimationStateBehaviour>)playable.GetInput(lastOneWeight - 1);
|
||||
var fromClipData = fromClip.GetBehaviour();
|
||||
fromAnimation = fromClipData.animationReference != null ? fromClipData.animationReference.Animation : null;
|
||||
fromClipTime = (float)fromClip.GetTime();
|
||||
fromClipLoop = fromClipData.loop;
|
||||
}
|
||||
|
||||
Animation toAnimation = clipData.animationReference != null ? clipData.animationReference.Animation : null;
|
||||
float toClipTime = (float)inputPlayableClip.GetTime();
|
||||
float mixDuration = clipData.mixDuration;
|
||||
|
||||
if (!clipData.customDuration && fromAnimation != null && toAnimation != null) {
|
||||
mixDuration = spineComponent.AnimationState.Data.GetMix(fromAnimation, toAnimation);
|
||||
}
|
||||
|
||||
// Approximate what AnimationState might do at runtime.
|
||||
if (fromAnimation != null && mixDuration > 0 && toClipTime < mixDuration) {
|
||||
dummyAnimationState = dummyAnimationState ?? new AnimationState(spineComponent.skeletonDataAsset.GetAnimationStateData());
|
||||
|
||||
var toTrack = dummyAnimationState.GetCurrent(0);
|
||||
var fromTrack = toTrack != null ? toTrack.mixingFrom : null;
|
||||
bool isAnimationTransitionMatch = (toTrack != null && toTrack.animation == toAnimation && fromTrack != null && fromTrack.animation == fromAnimation);
|
||||
|
||||
if (!isAnimationTransitionMatch) {
|
||||
dummyAnimationState.ClearTracks();
|
||||
fromTrack = dummyAnimationState.SetAnimation(0, fromAnimation, fromClipLoop);
|
||||
fromTrack.AllowImmediateQueue();
|
||||
if (toAnimation != null)
|
||||
toTrack = dummyAnimationState.SetAnimation(0, toAnimation, clipData.loop);
|
||||
}
|
||||
|
||||
// Update track times.
|
||||
fromTrack.trackTime = fromClipTime;
|
||||
if (toTrack != null) {
|
||||
toTrack.trackTime = toClipTime;
|
||||
toTrack.mixTime = toClipTime;
|
||||
}
|
||||
|
||||
// Apply Pose
|
||||
skeleton.SetToSetupPose();
|
||||
dummyAnimationState.Update(0);
|
||||
dummyAnimationState.Apply(skeleton);
|
||||
} else {
|
||||
skeleton.SetToSetupPose();
|
||||
if (toAnimation != null)
|
||||
toAnimation.PoseSkeleton(skeleton, toClipTime, clipData.loop);
|
||||
}
|
||||
|
||||
}
|
||||
// Do nothing outside of the first clip and the last clip.
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f61d2f4ac1c4ad044bf4ae6e63b0eca8
|
||||
timeCreated: 1510816616
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,50 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated May 1, 2019. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2019, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
* NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS
|
||||
* INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#if UNITY_2017 || UNITY_2018 || (UNITY_2019_1_OR_NEWER && SPINE_TIMELINE_PACKAGE_DOWNLOADED)
|
||||
using UnityEngine;
|
||||
using UnityEngine.Playables;
|
||||
using UnityEngine.Timeline;
|
||||
|
||||
namespace Spine.Unity.Playables {
|
||||
[TrackColor(0.9960785f, 0.2509804f, 0.003921569f)]
|
||||
[TrackClipType(typeof(SpineAnimationStateClip))]
|
||||
[TrackBindingType(typeof(SkeletonAnimation))]
|
||||
public class SpineAnimationStateTrack : TrackAsset {
|
||||
public int trackIndex = 0;
|
||||
|
||||
public override Playable CreateTrackMixer(PlayableGraph graph, GameObject go, int inputCount) {
|
||||
var scriptPlayable = ScriptPlayable<SpineAnimationStateMixerBehaviour>.Create(graph, inputCount);
|
||||
var mixerBehaviour = scriptPlayable.GetBehaviour();
|
||||
mixerBehaviour.trackIndex = this.trackIndex;
|
||||
return scriptPlayable;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dfabb056a779ae34b9ebd7de425c868b
|
||||
timeCreated: 1510816616
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user