[unity] Fixed SkeletonMecanim layer blend modes, now it detects Override/Add from the animation controller. Also fixed some animator related warnings in editor. Closes ##1317.

This commit is contained in:
Harald Csaszar 2019-04-02 19:46:33 +02:00
parent 0ab491491b
commit 9bb5a0d044

View File

@ -74,10 +74,13 @@ namespace Spine.Unity {
if (!valid) return; if (!valid) return;
#if UNITY_EDITOR #if UNITY_EDITOR
var translatorAnimator = translator.Animator;
if (translatorAnimator != null && !translatorAnimator.isInitialized)
translatorAnimator.Rebind();
if (Application.isPlaying) { if (Application.isPlaying) {
translator.Apply(skeleton); translator.Apply(skeleton);
} else { } else {
var translatorAnimator = translator.Animator;
if (translatorAnimator != null && translatorAnimator.isInitialized) if (translatorAnimator != null && translatorAnimator.isInitialized)
translator.Apply(skeleton); translator.Apply(skeleton);
} }
@ -107,6 +110,7 @@ namespace Spine.Unity {
#region Inspector #region Inspector
public bool autoReset = true; public bool autoReset = true;
public MixMode[] layerMixModes = new MixMode[0]; public MixMode[] layerMixModes = new MixMode[0];
public MixBlend[] layerBlendModes = new MixBlend[0];
#endregion #endregion
public enum MixMode { AlwaysMix, MixNext, SpineStyle } public enum MixMode { AlwaysMix, MixNext, SpineStyle }
@ -155,6 +159,11 @@ namespace Spine.Unity {
if (layerMixModes.Length < animator.layerCount) if (layerMixModes.Length < animator.layerCount)
System.Array.Resize<MixMode>(ref layerMixModes, animator.layerCount); System.Array.Resize<MixMode>(ref layerMixModes, animator.layerCount);
#if UNITY_EDITOR
if (!Application.isPlaying) {
GetLayerBlendModes();
}
#endif
InitClipInfosForLayers(); InitClipInfosForLayers();
for (int layer = 0, n = animator.layerCount; layer < n; layer++) { for (int layer = 0, n = animator.layerCount; layer < n; layer++) {
GetStateUpdatesFromAnimator(layer); GetStateUpdatesFromAnimator(layer);
@ -229,16 +238,17 @@ namespace Spine.Unity {
out clipInfo, out nextClipInfo, out interruptingClipInfo, out shallInterpolateWeightTo1); out clipInfo, out nextClipInfo, out interruptingClipInfo, out shallInterpolateWeightTo1);
MixMode mode = layerMixModes[layer]; MixMode mode = layerMixModes[layer];
MixBlend layerBlendMode = (layer < layerBlendModes.Length) ? layerBlendModes[layer] : MixBlend.Replace;
if (mode == MixMode.AlwaysMix) { if (mode == MixMode.AlwaysMix) {
// Always use Mix instead of Applying the first non-zero weighted clip. // Always use Mix instead of Applying the first non-zero weighted clip.
for (int c = 0; c < clipInfoCount; c++) { for (int c = 0; c < clipInfoCount; c++) {
var info = clipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue; var info = clipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue;
GetAnimation(info.clip).Apply(skeleton, 0, AnimationTime(stateInfo.normalizedTime, info.clip.length, stateInfo.loop, stateInfo.speed < 0), stateInfo.loop, null, weight, MixBlend.Replace, MixDirection.In); GetAnimation(info.clip).Apply(skeleton, 0, AnimationTime(stateInfo.normalizedTime, info.clip.length, stateInfo.loop, stateInfo.speed < 0), stateInfo.loop, null, weight, layerBlendMode, MixDirection.In);
} }
if (hasNext) { if (hasNext) {
for (int c = 0; c < nextClipInfoCount; c++) { for (int c = 0; c < nextClipInfoCount; c++) {
var info = nextClipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue; var info = nextClipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue;
GetAnimation(info.clip).Apply(skeleton, 0, AnimationTime(nextStateInfo.normalizedTime, info.clip.length, nextStateInfo.speed < 0), nextStateInfo.loop, null, weight, MixBlend.Replace, MixDirection.In); GetAnimation(info.clip).Apply(skeleton, 0, AnimationTime(nextStateInfo.normalizedTime, info.clip.length, nextStateInfo.speed < 0), nextStateInfo.loop, null, weight, layerBlendMode, MixDirection.In);
} }
} }
if (isInterruptionActive) { if (isInterruptionActive) {
@ -248,7 +258,7 @@ namespace Spine.Unity {
float clipWeight = shallInterpolateWeightTo1 ? (info.weight + 1.0f) * 0.5f : info.weight; float clipWeight = shallInterpolateWeightTo1 ? (info.weight + 1.0f) * 0.5f : info.weight;
float weight = clipWeight * layerWeight; if (weight == 0) continue; float weight = clipWeight * layerWeight; if (weight == 0) continue;
GetAnimation(info.clip).Apply(skeleton, 0, AnimationTime(interruptingStateInfo.normalizedTime + interruptingClipTimeAddition, info.clip.length, interruptingStateInfo.speed < 0), GetAnimation(info.clip).Apply(skeleton, 0, AnimationTime(interruptingStateInfo.normalizedTime + interruptingClipTimeAddition, info.clip.length, interruptingStateInfo.speed < 0),
interruptingStateInfo.loop, null, weight, MixBlend.Replace, MixDirection.In); interruptingStateInfo.loop, null, weight, layerBlendMode, MixDirection.In);
} }
} }
} else { // case MixNext || SpineStyle } else { // case MixNext || SpineStyle
@ -256,13 +266,13 @@ namespace Spine.Unity {
int c = 0; int c = 0;
for (; c < clipInfoCount; c++) { for (; c < clipInfoCount; c++) {
var info = clipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue; var info = clipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue;
GetAnimation(info.clip).Apply(skeleton, 0, AnimationTime(stateInfo.normalizedTime, info.clip.length, stateInfo.loop, stateInfo.speed < 0), stateInfo.loop, null, 1f, MixBlend.Replace, MixDirection.In); GetAnimation(info.clip).Apply(skeleton, 0, AnimationTime(stateInfo.normalizedTime, info.clip.length, stateInfo.loop, stateInfo.speed < 0), stateInfo.loop, null, 1f, layerBlendMode, MixDirection.In);
break; break;
} }
// Mix the rest // Mix the rest
for (; c < clipInfoCount; c++) { for (; c < clipInfoCount; c++) {
var info = clipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue; var info = clipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue;
GetAnimation(info.clip).Apply(skeleton, 0, AnimationTime(stateInfo.normalizedTime, info.clip.length, stateInfo.loop, stateInfo.speed < 0), stateInfo.loop, null, weight, MixBlend.Replace, MixDirection.In); GetAnimation(info.clip).Apply(skeleton, 0, AnimationTime(stateInfo.normalizedTime, info.clip.length, stateInfo.loop, stateInfo.speed < 0), stateInfo.loop, null, weight, layerBlendMode, MixDirection.In);
} }
c = 0; c = 0;
@ -271,14 +281,14 @@ namespace Spine.Unity {
if (mode == MixMode.SpineStyle) { if (mode == MixMode.SpineStyle) {
for (; c < nextClipInfoCount; c++) { for (; c < nextClipInfoCount; c++) {
var info = nextClipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue; var info = nextClipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue;
GetAnimation(info.clip).Apply(skeleton, 0, AnimationTime(nextStateInfo.normalizedTime, info.clip.length, nextStateInfo.speed < 0), nextStateInfo.loop, null, 1f, MixBlend.Replace, MixDirection.In); GetAnimation(info.clip).Apply(skeleton, 0, AnimationTime(nextStateInfo.normalizedTime, info.clip.length, nextStateInfo.speed < 0), nextStateInfo.loop, null, 1f, layerBlendMode, MixDirection.In);
break; break;
} }
} }
// Mix the rest // Mix the rest
for (; c < nextClipInfoCount; c++) { for (; c < nextClipInfoCount; c++) {
var info = nextClipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue; var info = nextClipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue;
GetAnimation(info.clip).Apply(skeleton, 0, AnimationTime(nextStateInfo.normalizedTime, info.clip.length, nextStateInfo.speed < 0), nextStateInfo.loop, null, weight, MixBlend.Replace, MixDirection.In); GetAnimation(info.clip).Apply(skeleton, 0, AnimationTime(nextStateInfo.normalizedTime, info.clip.length, nextStateInfo.speed < 0), nextStateInfo.loop, null, weight, layerBlendMode, MixDirection.In);
} }
} }
@ -290,7 +300,7 @@ namespace Spine.Unity {
var info = interruptingClipInfo[c]; var info = interruptingClipInfo[c];
float clipWeight = shallInterpolateWeightTo1 ? (info.weight + 1.0f) * 0.5f : info.weight; float clipWeight = shallInterpolateWeightTo1 ? (info.weight + 1.0f) * 0.5f : info.weight;
float weight = clipWeight * layerWeight; if (weight == 0) continue; float weight = clipWeight * layerWeight; if (weight == 0) continue;
GetAnimation(info.clip).Apply(skeleton, 0, AnimationTime(interruptingStateInfo.normalizedTime + interruptingClipTimeAddition, info.clip.length, interruptingStateInfo.speed < 0), interruptingStateInfo.loop, null, 1f, MixBlend.Replace, MixDirection.In); GetAnimation(info.clip).Apply(skeleton, 0, AnimationTime(interruptingStateInfo.normalizedTime + interruptingClipTimeAddition, info.clip.length, interruptingStateInfo.speed < 0), interruptingStateInfo.loop, null, 1f, layerBlendMode, MixDirection.In);
break; break;
} }
} }
@ -299,7 +309,7 @@ namespace Spine.Unity {
var info = interruptingClipInfo[c]; var info = interruptingClipInfo[c];
float clipWeight = shallInterpolateWeightTo1 ? (info.weight + 1.0f) * 0.5f : info.weight; float clipWeight = shallInterpolateWeightTo1 ? (info.weight + 1.0f) * 0.5f : info.weight;
float weight = clipWeight * layerWeight; if (weight == 0) continue; float weight = clipWeight * layerWeight; if (weight == 0) continue;
GetAnimation(info.clip).Apply(skeleton, 0, AnimationTime(interruptingStateInfo.normalizedTime + interruptingClipTimeAddition, info.clip.length, interruptingStateInfo.speed < 0), interruptingStateInfo.loop, null, weight, MixBlend.Replace, MixDirection.In); GetAnimation(info.clip).Apply(skeleton, 0, AnimationTime(interruptingStateInfo.normalizedTime + interruptingClipTimeAddition, info.clip.length, interruptingStateInfo.speed < 0), interruptingStateInfo.loop, null, weight, layerBlendMode, MixDirection.In);
} }
} }
} }
@ -346,6 +356,24 @@ namespace Spine.Unity {
} }
} }
#if UNITY_EDITOR
void GetLayerBlendModes() {
if (layerBlendModes.Length < animator.layerCount) {
System.Array.Resize<MixBlend>(ref layerBlendModes, animator.layerCount);
}
for (int layer = 0, n = animator.layerCount; layer < n; ++layer) {
var controller = animator.runtimeAnimatorController as UnityEditor.Animations.AnimatorController;
if (controller != null) {
layerBlendModes[layer] = MixBlend.Replace;
if (layer > 0) {
layerBlendModes[layer] = controller.layers[layer].blendingMode == UnityEditor.Animations.AnimatorLayerBlendingMode.Additive ?
MixBlend.Add : MixBlend.Replace;
}
}
}
}
#endif
void GetStateUpdatesFromAnimator (int layer) { void GetStateUpdatesFromAnimator (int layer) {
var layerInfos = layerClipInfos[layer]; var layerInfos = layerClipInfos[layer];