mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-04 22:34:53 +08:00
[unity] Fixed exception after changing animation name with existing custom mix duration, closes #1874. Displaying animation/bone/etc name in red in Inspector fields when it no longer exists at the skeleton data.
This commit is contained in:
parent
a23217c8f7
commit
f04a7b38ca
@ -80,6 +80,7 @@
|
||||
* Added another fadeout example component named `SkeletonRenderTextureFadeout` which takes over transparency fadeout when enabled. You can use this component as-is, attach it in disabled state and enable it to start a fadeout effect.
|
||||
* Timeline clips now offer an additional `Alpha` parameter for setting a custom constant mix alpha value other than 1.0, just as `TrackEntry.Alpha`. Defaults to 1.0.
|
||||
* `GetRemappedClone` copying from `Sprite` now provides additional `pmaCloneTextureFormat` and `pmaCloneMipmaps` parameters to explicitly specify the texture format of a newly created PMA texture.
|
||||
* Spine property Inspector fields (`Animation Name`, `Bone Name`, `Slot` and similar) now display the name in red when the respective animation/bone/etc no longer exists at the skeleton data. This may be helpful when such items have been renamed or deleted.
|
||||
|
||||
* **Breaking changes**
|
||||
|
||||
|
||||
@ -455,7 +455,7 @@ namespace Spine.Unity.Editor {
|
||||
}
|
||||
|
||||
if (cc.changed) {
|
||||
targetSkeletonDataAsset.FillStateData();
|
||||
targetSkeletonDataAsset.FillStateData(quiet: true);
|
||||
EditorUtility.SetDirty(targetSkeletonDataAsset);
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
@ -61,11 +61,34 @@ namespace Spine.Unity.Editor {
|
||||
return noneLabel;
|
||||
}
|
||||
|
||||
static GUIStyle errorPopupStyle;
|
||||
GUIStyle ErrorPopupStyle {
|
||||
get {
|
||||
if (errorPopupStyle == null) errorPopupStyle = new GUIStyle(EditorStyles.popup);
|
||||
errorPopupStyle.normal.textColor = Color.red;
|
||||
errorPopupStyle.hover.textColor = Color.red;
|
||||
errorPopupStyle.focused.textColor = Color.red;
|
||||
errorPopupStyle.active.textColor = Color.red;
|
||||
return errorPopupStyle;
|
||||
}
|
||||
}
|
||||
|
||||
protected T TargetAttribute { get { return (T)attribute; } }
|
||||
protected SerializedProperty SerializedProperty { get; private set; }
|
||||
|
||||
protected abstract Texture2D Icon { get; }
|
||||
|
||||
protected bool IsValueValid (SerializedProperty property) {
|
||||
if (skeletonDataAsset != null) {
|
||||
SkeletonData skeletonData = skeletonDataAsset.GetSkeletonData(true);
|
||||
if (skeletonData != null && !string.IsNullOrEmpty(property.stringValue))
|
||||
return IsValueValid(skeletonData, property);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected virtual bool IsValueValid (SkeletonData skeletonData, SerializedProperty property) { return true; }
|
||||
|
||||
public override void OnGUI (Rect position, SerializedProperty property, GUIContent label) {
|
||||
SerializedProperty = property;
|
||||
|
||||
@ -123,8 +146,10 @@ namespace Spine.Unity.Editor {
|
||||
position = EditorGUI.PrefixLabel(position, label);
|
||||
|
||||
Texture2D image = Icon;
|
||||
GUIStyle usedStyle = IsValueValid(property) ? EditorStyles.popup : ErrorPopupStyle;
|
||||
string propertyStringValue = (property.hasMultipleDifferentValues) ? SpineInspectorUtility.EmDash : property.stringValue;
|
||||
if (GUI.Button(position, string.IsNullOrEmpty(propertyStringValue) ? NoneLabel(image) : SpineInspectorUtility.TempContent(propertyStringValue, image), EditorStyles.popup))
|
||||
if (GUI.Button(position, string.IsNullOrEmpty(propertyStringValue) ? NoneLabel(image) :
|
||||
SpineInspectorUtility.TempContent(propertyStringValue, image), usedStyle))
|
||||
Selector(property);
|
||||
}
|
||||
|
||||
@ -174,6 +199,10 @@ namespace Spine.Unity.Editor {
|
||||
|
||||
protected override Texture2D Icon { get { return SpineEditorUtilities.Icons.slot; } }
|
||||
|
||||
protected override bool IsValueValid (SkeletonData skeletonData, SerializedProperty property) {
|
||||
return skeletonData.FindSlot(property.stringValue) != null;
|
||||
}
|
||||
|
||||
protected override void PopulateMenu (GenericMenu menu, SerializedProperty property, SpineSlot targetAttribute, SkeletonData data) {
|
||||
if (TargetAttribute.includeNone)
|
||||
menu.AddItem(new GUIContent(NoneString), !property.hasMultipleDifferentValues && string.IsNullOrEmpty(property.stringValue), HandleSelect, new SpineDrawerValuePair(string.Empty, property));
|
||||
@ -223,6 +252,10 @@ namespace Spine.Unity.Editor {
|
||||
|
||||
internal override string NoneString { get { return TargetAttribute.defaultAsEmptyString ? DefaultSkinName : NoneStringConstant; } }
|
||||
|
||||
protected override bool IsValueValid (SkeletonData skeletonData, SerializedProperty property) {
|
||||
return skeletonData.FindSkin(property.stringValue) != null;
|
||||
}
|
||||
|
||||
public static void GetSkinMenuItems (SkeletonData data, List<string> outputNames, List<GUIContent> outputMenuItems, bool includeNone = true) {
|
||||
if (data == null) return;
|
||||
if (outputNames == null) return;
|
||||
@ -269,6 +302,10 @@ namespace Spine.Unity.Editor {
|
||||
|
||||
protected override Texture2D Icon { get { return SpineEditorUtilities.Icons.animation; } }
|
||||
|
||||
protected override bool IsValueValid (SkeletonData skeletonData, SerializedProperty property) {
|
||||
return skeletonData.FindAnimation(property.stringValue) != null;
|
||||
}
|
||||
|
||||
public static void GetAnimationMenuItems (SkeletonData data, List<string> outputNames, List<GUIContent> outputMenuItems, bool includeNone = true) {
|
||||
if (data == null) return;
|
||||
if (outputNames == null) return;
|
||||
@ -311,6 +348,10 @@ namespace Spine.Unity.Editor {
|
||||
|
||||
protected override Texture2D Icon { get { return SpineEditorUtilities.Icons.userEvent; } }
|
||||
|
||||
protected override bool IsValueValid (SkeletonData skeletonData, SerializedProperty property) {
|
||||
return skeletonData.FindEvent(property.stringValue) != null;
|
||||
}
|
||||
|
||||
public static void GetEventMenuItems (SkeletonData data, List<string> eventNames, List<GUIContent> menuItems, bool includeNone = true) {
|
||||
if (data == null) return;
|
||||
|
||||
@ -356,6 +397,10 @@ namespace Spine.Unity.Editor {
|
||||
|
||||
protected override Texture2D Icon { get { return SpineEditorUtilities.Icons.constraintIK; } }
|
||||
|
||||
protected override bool IsValueValid (SkeletonData skeletonData, SerializedProperty property) {
|
||||
return skeletonData.FindIkConstraint(property.stringValue) != null;
|
||||
}
|
||||
|
||||
protected override void PopulateMenu (GenericMenu menu, SerializedProperty property, SpineIkConstraint targetAttribute, SkeletonData data) {
|
||||
var constraints = skeletonDataAsset.GetSkeletonData(false).IkConstraints;
|
||||
|
||||
@ -376,6 +421,10 @@ namespace Spine.Unity.Editor {
|
||||
|
||||
protected override Texture2D Icon { get { return SpineEditorUtilities.Icons.constraintTransform; } }
|
||||
|
||||
protected override bool IsValueValid (SkeletonData skeletonData, SerializedProperty property) {
|
||||
return skeletonData.FindTransformConstraint(property.stringValue) != null;
|
||||
}
|
||||
|
||||
protected override void PopulateMenu (GenericMenu menu, SerializedProperty property, SpineTransformConstraint targetAttribute, SkeletonData data) {
|
||||
var constraints = skeletonDataAsset.GetSkeletonData(false).TransformConstraints;
|
||||
|
||||
@ -395,6 +444,10 @@ namespace Spine.Unity.Editor {
|
||||
|
||||
protected override Texture2D Icon { get { return SpineEditorUtilities.Icons.constraintPath; } }
|
||||
|
||||
protected override bool IsValueValid (SkeletonData skeletonData, SerializedProperty property) {
|
||||
return skeletonData.FindPathConstraint(property.stringValue) != null;
|
||||
}
|
||||
|
||||
protected override void PopulateMenu (GenericMenu menu, SerializedProperty property, SpinePathConstraint targetAttribute, SkeletonData data) {
|
||||
var constraints = skeletonDataAsset.GetSkeletonData(false).PathConstraints;
|
||||
|
||||
@ -516,6 +569,10 @@ namespace Spine.Unity.Editor {
|
||||
|
||||
protected override Texture2D Icon { get { return SpineEditorUtilities.Icons.bone; } }
|
||||
|
||||
protected override bool IsValueValid (SkeletonData skeletonData, SerializedProperty property) {
|
||||
return skeletonData.FindBone(property.stringValue) != null;
|
||||
}
|
||||
|
||||
protected override void PopulateMenu (GenericMenu menu, SerializedProperty property, SpineBone targetAttribute, SkeletonData data) {
|
||||
menu.AddDisabledItem(new GUIContent(skeletonDataAsset.name));
|
||||
menu.AddSeparator("");
|
||||
|
||||
@ -217,14 +217,30 @@ namespace Spine.Unity {
|
||||
FillStateData();
|
||||
}
|
||||
|
||||
public void FillStateData () {
|
||||
public void FillStateData (bool quiet = false) {
|
||||
if (stateData != null) {
|
||||
stateData.DefaultMix = defaultMix;
|
||||
|
||||
for (int i = 0, n = fromAnimation.Length; i < n; i++) {
|
||||
if (fromAnimation[i].Length == 0 || toAnimation[i].Length == 0)
|
||||
string fromAnimationName = fromAnimation[i];
|
||||
string toAnimationName = toAnimation[i];
|
||||
if (fromAnimationName.Length == 0 || toAnimationName.Length == 0)
|
||||
continue;
|
||||
stateData.SetMix(fromAnimation[i], toAnimation[i], duration[i]);
|
||||
#if UNITY_EDITOR
|
||||
if (skeletonData.FindAnimation(fromAnimationName) == null) {
|
||||
if (!quiet) Debug.LogError(
|
||||
string.Format("Custom Mix Durations: Animation '{0}' not found, was it renamed?",
|
||||
fromAnimationName), this);
|
||||
continue;
|
||||
}
|
||||
if (skeletonData.FindAnimation(toAnimationName) == null) {
|
||||
if (!quiet) Debug.LogError(
|
||||
string.Format("Custom Mix Durations: Animation '{0}' not found, was it renamed?",
|
||||
toAnimationName), this);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
stateData.SetMix(fromAnimationName, toAnimationName, duration[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user