Просмотр исходного кода

[unity] Allow TextField fallback for attributes.

pharan 7 лет назад
Родитель
Сommit
164678163d

+ 13 - 7
spine-unity/Assets/spine-unity/Editor/SpineAttributeDrawers.cs

@@ -74,15 +74,16 @@ namespace Spine.Unity.Editor {
 				return;
 			}
 
-			var dataField = property.FindBaseOrSiblingProperty(TargetAttribute.dataField);
+			SerializedProperty dataField = property.FindBaseOrSiblingProperty(TargetAttribute.dataField);
 			if (dataField != null) {
-				if (dataField.objectReferenceValue is SkeletonDataAsset) {
-					skeletonDataAsset = (SkeletonDataAsset)dataField.objectReferenceValue;
-				} else if (dataField.objectReferenceValue is ISkeletonComponent) {
-					var skeletonComponent = (ISkeletonComponent)dataField.objectReferenceValue;
+				var objectReferenceValue = dataField.objectReferenceValue;
+				if (objectReferenceValue is SkeletonDataAsset) {
+					skeletonDataAsset = (SkeletonDataAsset)objectReferenceValue;
+				} else if (objectReferenceValue is ISkeletonComponent) {
+					var skeletonComponent = (ISkeletonComponent)objectReferenceValue;
 					if (skeletonComponent != null)
 						skeletonDataAsset = skeletonComponent.SkeletonDataAsset;
-				} else {
+				} else if (objectReferenceValue != null) {
 					EditorGUI.LabelField(position, "ERROR:", "Invalid reference type");
 					return;
 				}
@@ -95,7 +96,12 @@ namespace Spine.Unity.Editor {
 			}
 
 			if (skeletonDataAsset == null) {
-				EditorGUI.LabelField(position, "ERROR:", "Must have reference to a SkeletonDataAsset");
+				if (TargetAttribute.fallbackToTextField) {
+					EditorGUI.PropertyField(position, property); //EditorGUI.TextField(position, label, property.stringValue);
+				} else {
+					EditorGUI.LabelField(position, "ERROR:", "Must have reference to a SkeletonDataAsset");
+				}
+
 				skeletonDataAsset = property.serializedObject.targetObject as SkeletonDataAsset;
 				if (skeletonDataAsset == null) return;
 			}

+ 33 - 15
spine-unity/Assets/spine-unity/SpineAttributes.cs

@@ -41,6 +41,7 @@ namespace Spine.Unity {
 		public string dataField = "";
 		public string startsWith = "";
 		public bool includeNone = true;
+		public bool fallbackToTextField = false;
 	}
 
 	public class SpineSlot : SpineAttributeBase {
@@ -52,15 +53,17 @@ namespace Spine.Unity {
 		/// <param name="startsWith">Filters popup results to elements that begin with supplied string.</param>
 		/// <param name="containsBoundingBoxes">Disables popup results that don't contain bounding box attachments when true.</param>
 		/// <param name = "includeNone">If true, the dropdown list will include a "none" option which stored as an empty string.</param>
+		/// <param name = "fallbackToTextField">If true, and an animation list source can't be found, the field will fall back to a normal text field. If false, it will show an error.</param>
 		/// <param name="dataField">If specified, a locally scoped field with the name supplied by in dataField will be used to fill the popup results.
 		/// Valid types are SkeletonDataAsset and SkeletonRenderer (and derivatives).
 		/// If left empty and the script the attribute is applied to is derived from Component, GetComponent<SkeletonRenderer>() will be called as a fallback.
 		/// </param>
-		public SpineSlot(string startsWith = "", string dataField = "", bool containsBoundingBoxes = false, bool includeNone = true) {
+		public SpineSlot (string startsWith = "", string dataField = "", bool containsBoundingBoxes = false, bool includeNone = true, bool fallbackToTextField = false) {
 			this.startsWith = startsWith;
 			this.dataField = dataField;
 			this.containsBoundingBoxes = containsBoundingBoxes;
 			this.includeNone = includeNone;
+			this.fallbackToTextField = fallbackToTextField;
 		}
 	}
 
@@ -72,12 +75,14 @@ namespace Spine.Unity {
 		/// <param name = "includeNone">If true, the dropdown list will include a "none" option which stored as an empty string.</param>
 		/// <param name="dataField">If specified, a locally scoped field with the name supplied by in dataField will be used to fill the popup results.
 		/// Valid types are SkeletonDataAsset and SkeletonRenderer (and derivatives).
-		/// If left empty and the script the attribute is applied to is derived from Component, GetComponent<SkeletonRenderer>() will be called as a fallback.
+		/// If left empty and the script the attribute is applied to is derived from Component, GetComponent(SkeletonRenderer)() will be called as a fallback.
 		/// </param>
-		public SpineEvent(string startsWith = "", string dataField = "", bool includeNone = true) {
+		/// <param name="fallbackToTextField">If true, and an animation list source can't be found, the field will fall back to a normal text field. If false, it will show an error.</param>
+		public SpineEvent (string startsWith = "", string dataField = "", bool includeNone = true, bool fallbackToTextField = false) {
 			this.startsWith = startsWith;
 			this.dataField = dataField;
 			this.includeNone = includeNone;
+			this.fallbackToTextField = fallbackToTextField;
 		}
 	}
 
@@ -89,12 +94,14 @@ namespace Spine.Unity {
 		/// <param name = "includeNone">If true, the dropdown list will include a "none" option which stored as an empty string.</param>
 		/// <param name="dataField">If specified, a locally scoped field with the name supplied by in dataField will be used to fill the popup results.
 		/// Valid types are SkeletonDataAsset and SkeletonRenderer (and derivatives).
-		/// If left empty and the script the attribute is applied to is derived from Component, GetComponent<SkeletonRenderer>() will be called as a fallback.
+		/// If left empty and the script the attribute is applied to is derived from Component, GetComponent(SkeletonRenderer)() will be called as a fallback.
 		/// </param>
-		public SpineIkConstraint(string startsWith = "", string dataField = "", bool includeNone = true) {
+		/// <param name = "fallbackToTextField">If true, and an animation list source can't be found, the field will fall back to a normal text field. If false, it will show an error.</param>
+		public SpineIkConstraint (string startsWith = "", string dataField = "", bool includeNone = true, bool fallbackToTextField = false) {
 			this.startsWith = startsWith;
 			this.dataField = dataField;
 			this.includeNone = includeNone;
+			this.fallbackToTextField = fallbackToTextField;
 		}
 	}
 
@@ -106,12 +113,13 @@ namespace Spine.Unity {
 		/// <param name = "includeNone">If true, the dropdown list will include a "none" option which stored as an empty string.</param>
 		/// <param name="dataField">If specified, a locally scoped field with the name supplied by in dataField will be used to fill the popup results.
 		/// Valid types are SkeletonDataAsset and SkeletonRenderer (and derivatives).
-		/// If left empty and the script the attribute is applied to is derived from Component, GetComponent<SkeletonRenderer>() will be called as a fallback.
+		/// If left empty and the script the attribute is applied to is derived from Component, GetComponent(SkeletonRenderer)() will be called as a fallback.
 		/// </param>
-		public SpinePathConstraint(string startsWith = "", string dataField = "", bool includeNone = true) {
+		public SpinePathConstraint (string startsWith = "", string dataField = "", bool includeNone = true, bool fallbackToTextField = false) {
 			this.startsWith = startsWith;
 			this.dataField = dataField;
 			this.includeNone = includeNone;
+			this.fallbackToTextField = fallbackToTextField;
 		}
 	}
 
@@ -121,14 +129,16 @@ namespace Spine.Unity {
 		/// </summary>
 		/// <param name="startsWith">Filters popup results to elements that begin with supplied string.</param>
 		/// <param name = "includeNone">If true, the dropdown list will include a "none" option which stored as an empty string.</param>
+		/// <param name = "fallbackToTextField">If true, and an animation list source can't be found, the field will fall back to a normal text field. If false, it will show an error.</param>
 		/// <param name="dataField">If specified, a locally scoped field with the name supplied by in dataField will be used to fill the popup results.
 		/// Valid types are SkeletonDataAsset and SkeletonRenderer (and derivatives).
 		/// If left empty and the script the attribute is applied to is derived from Component, GetComponent<SkeletonRenderer>() will be called as a fallback.
 		/// </param>
-		public SpineTransformConstraint(string startsWith = "", string dataField = "", bool includeNone = true) {
+		public SpineTransformConstraint (string startsWith = "", string dataField = "", bool includeNone = true, bool fallbackToTextField = false) {
 			this.startsWith = startsWith;
 			this.dataField = dataField;
 			this.includeNone = includeNone;
+			this.fallbackToTextField = fallbackToTextField;
 		}
 	}
 
@@ -138,14 +148,16 @@ namespace Spine.Unity {
 		/// </summary>
 		/// <param name="startsWith">Filters popup results to elements that begin with supplied string.</param>
 		/// <param name = "includeNone">If true, the dropdown list will include a "none" option which stored as an empty string.</param>
+		/// <param name = "fallbackToTextField">If true, and an animation list source can't be found, the field will fall back to a normal text field. If false, it will show an error.</param>
 		/// <param name="dataField">If specified, a locally scoped field with the name supplied by in dataField will be used to fill the popup results.
 		/// Valid types are SkeletonDataAsset and SkeletonRenderer (and derivatives)
 		/// If left empty and the script the attribute is applied to is derived from Component, GetComponent<SkeletonRenderer>() will be called as a fallback.
 		/// </param>
-		public SpineSkin(string startsWith = "", string dataField = "", bool includeNone = true) {
+		public SpineSkin (string startsWith = "", string dataField = "", bool includeNone = true, bool fallbackToTextField = false) {
 			this.startsWith = startsWith;
 			this.dataField = dataField;
 			this.includeNone = includeNone;
+			this.fallbackToTextField = fallbackToTextField;
 		}
 	}
 	public class SpineAnimation : SpineAttributeBase {
@@ -153,15 +165,17 @@ namespace Spine.Unity {
 		/// Smart popup menu for Spine Animations
 		/// </summary>
 		/// <param name="startsWith">Filters popup results to elements that begin with supplied string.</param>
-		/// <param name="dataField">If specified, a locally scoped field with the name supplied by in dataField will be used to fill the popup results.
+		/// <param name = "fallbackToTextField">If true, and an animation list source can't be found, the field will fall back to a normal text field. If false, it will show an error.</param>
 		/// <param name="includeNone">If true, the dropdown list will include a "none" option which stored as an empty string.</param>
+		/// <param name="dataField">If specified, a locally scoped field with the name supplied by in dataField will be used to fill the popup results.
 		/// Valid types are SkeletonDataAsset and SkeletonRenderer (and derivatives)
 		/// If left empty and the script the attribute is applied to is derived from Component, GetComponent<SkeletonRenderer>() will be called as a fallback.
 		/// </param>
-		public SpineAnimation(string startsWith = "", string dataField = "", bool includeNone = true) {
+		public SpineAnimation (string startsWith = "", string dataField = "", bool includeNone = true, bool fallbackToTextField = false) {
 			this.startsWith = startsWith;
 			this.dataField = dataField;
 			this.includeNone = includeNone;
+			this.fallbackToTextField = fallbackToTextField;
 		}
 	}
 
@@ -181,11 +195,12 @@ namespace Spine.Unity {
 		/// <param name="slotField">If specified, a locally scoped field with the name supplied by in slotField will be used to limit the popup results to children of a named slot</param>
 		/// <param name="skinField">If specified, a locally scoped field with the name supplied by in skinField will be used to limit the popup results to entries of the named skin</param>
 		/// <param name="includeNone">If true, the dropdown list will include a "none" option which stored as an empty string.</param>
+		/// <param name = "fallbackToTextField">If true, and an animation list source can't be found, the field will fall back to a normal text field. If false, it will show an error.</param>
 		/// <param name="dataField">If specified, a locally scoped field with the name supplied by in dataField will be used to fill the popup results.
 		/// Valid types are SkeletonDataAsset and SkeletonRenderer (and derivatives)
 		/// If left empty and the script the attribute is applied to is derived from Component, GetComponent<SkeletonRenderer>() will be called as a fallback.
 		/// </param>
-		public SpineAttachment (bool currentSkinOnly = true, bool returnAttachmentPath = false, bool placeholdersOnly = false, string slotField = "", string dataField = "", string skinField = "", bool includeNone = true) {
+		public SpineAttachment (bool currentSkinOnly = true, bool returnAttachmentPath = false, bool placeholdersOnly = false, string slotField = "", string dataField = "", string skinField = "", bool includeNone = true, bool fallbackToTextField = false) {
 			this.currentSkinOnly = currentSkinOnly;
 			this.returnAttachmentPath = returnAttachmentPath;
 			this.placeholdersOnly = placeholdersOnly;
@@ -193,6 +208,7 @@ namespace Spine.Unity {
 			this.dataField = dataField;
 			this.skinField = skinField;
 			this.includeNone = includeNone;
+			this.fallbackToTextField = fallbackToTextField;
 		}
 
 		public static SpineAttachment.Hierarchy GetHierarchy (string fullPath) {
@@ -241,15 +257,17 @@ namespace Spine.Unity {
 		/// Smart popup menu for Spine Bones
 		/// </summary>
 		/// <param name="startsWith">Filters popup results to elements that begin with supplied string.</param>
-		/// /// <param name="includeNone">If true, the dropdown list will include a "none" option which stored as an empty string.</param>
+		/// <param name="includeNone">If true, the dropdown list will include a "none" option which stored as an empty string.</param>
+		/// <param name = "fallbackToTextField">If true, and an animation list source can't be found, the field will fall back to a normal text field. If false, it will show an error.</param>
 		/// <param name="dataField">If specified, a locally scoped field with the name supplied by in dataField will be used to fill the popup results.
 		/// Valid types are SkeletonDataAsset and SkeletonRenderer (and derivatives)
 		/// If left empty and the script the attribute is applied to is derived from Component, GetComponent<SkeletonRenderer>() will be called as a fallback.
 		/// </param>
-		public SpineBone(string startsWith = "", string dataField = "", bool includeNone = true) {
+		public SpineBone (string startsWith = "", string dataField = "", bool includeNone = true, bool fallbackToTextField = false) {
 			this.startsWith = startsWith;
 			this.dataField = dataField;
 			this.includeNone = includeNone;
+			this.fallbackToTextField = fallbackToTextField;
 		}
 
 		public static Spine.Bone GetBone(string boneName, SkeletonRenderer renderer) {
@@ -265,7 +283,7 @@ namespace Spine.Unity {
 	public class SpineAtlasRegion : PropertyAttribute {
 		public string atlasAssetField;
 
-		public SpineAtlasRegion(string atlasAssetField = "") {
+		public SpineAtlasRegion (string atlasAssetField = "") {
 			this.atlasAssetField = atlasAssetField;
 		}
 	}