mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-19 08:16:41 +08:00
more attributes
more bug fixes more helper menus even more examples
This commit is contained in:
parent
444a536dad
commit
d60bc9241c
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -71,17 +71,17 @@ public class BasicPlatformerController : MonoBehaviour {
|
||||
#if UNITY_4_5
|
||||
[Header("Animation")]
|
||||
#endif
|
||||
[SpineAnimation(dataSource: "skeletonAnimation")]
|
||||
[SpineAnimation(dataField: "skeletonAnimation")]
|
||||
public string walkName = "Walk";
|
||||
[SpineAnimation(dataSource: "skeletonAnimation")]
|
||||
[SpineAnimation(dataField: "skeletonAnimation")]
|
||||
public string runName = "Run";
|
||||
[SpineAnimation(dataSource: "skeletonAnimation")]
|
||||
[SpineAnimation(dataField: "skeletonAnimation")]
|
||||
public string idleName = "Idle";
|
||||
[SpineAnimation(dataSource: "skeletonAnimation")]
|
||||
[SpineAnimation(dataField: "skeletonAnimation")]
|
||||
public string jumpName = "Jump";
|
||||
[SpineAnimation(dataSource: "skeletonAnimation")]
|
||||
[SpineAnimation(dataField: "skeletonAnimation")]
|
||||
public string fallName = "Fall";
|
||||
[SpineAnimation(dataSource: "skeletonAnimation")]
|
||||
[SpineAnimation(dataField: "skeletonAnimation")]
|
||||
public string crouchName = "Crouch";
|
||||
|
||||
#if UNITY_4_5
|
||||
|
||||
@ -1,11 +1,45 @@
|
||||
using UnityEngine;
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License
|
||||
* Version 2.1
|
||||
*
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable and
|
||||
* non-transferable license to install, execute and perform the Spine Runtimes
|
||||
* Software (the "Software") solely for internal use. Without the written
|
||||
* permission of Esoteric Software (typically granted by licensing Spine), you
|
||||
* may not (a) modify, translate, adapt or otherwise create derivative works,
|
||||
* improvements of the Software or develop new applications using the Software
|
||||
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
|
||||
* trademark, patent or other intellectual property or proprietary rights
|
||||
* notices on or in the Software, including any copy thereof. Redistributions
|
||||
* in binary or source form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) 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.
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Basic Platformer Controller created by Mitch Thompson
|
||||
* Full irrevocable rights and permissions granted to Esoteric Software
|
||||
*****************************************************************************/
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
|
||||
public class Chimera : MonoBehaviour {
|
||||
|
||||
public SkeletonDataAsset skeletonDataSource;
|
||||
|
||||
[SpineAttachment(currentSkinOnly: false, returnFullPath: true, dataSource: "skeletonDataSource")]
|
||||
[SpineAttachment(currentSkinOnly: false, returnAttachmentPath: true, dataField: "skeletonDataSource")]
|
||||
public string attachmentPath;
|
||||
|
||||
[SpineSlot]
|
||||
|
||||
66
spine-unity/Assets/Examples/Scripts/DynamicSpineBone.cs
Normal file
66
spine-unity/Assets/Examples/Scripts/DynamicSpineBone.cs
Normal file
@ -0,0 +1,66 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
|
||||
public class DynamicSpineBone : MonoBehaviour {
|
||||
|
||||
public Transform speedReference;
|
||||
|
||||
[SpineBone]
|
||||
public string boneName;
|
||||
|
||||
[Range(-90, 90)]
|
||||
public float minRotation = -45;
|
||||
[Range(-90, 90)]
|
||||
public float maxRotation = 45;
|
||||
|
||||
[Range(-2000, 2000)]
|
||||
public float rotationFactor = 300;
|
||||
|
||||
[Range(5, 30)]
|
||||
public float returnSpeed = 10;
|
||||
|
||||
[Range(100, 1000)]
|
||||
public float boneSpeed = 300;
|
||||
|
||||
public float returnThreshhold = 0.01f;
|
||||
|
||||
public bool useAcceleration;
|
||||
|
||||
|
||||
SkeletonAnimation skeletonAnimation;
|
||||
float goalRotation;
|
||||
Spine.Bone bone;
|
||||
Vector3 velocity;
|
||||
Vector3 acceleration;
|
||||
Vector3 lastPosition;
|
||||
|
||||
void Start() {
|
||||
if (speedReference == null)
|
||||
speedReference = transform;
|
||||
|
||||
skeletonAnimation = GetComponent<SkeletonAnimation>();
|
||||
bone = SpineBone.GetBone(boneName, skeletonAnimation);
|
||||
skeletonAnimation.UpdateLocal += UpdateLocal;
|
||||
lastPosition = speedReference.position;
|
||||
}
|
||||
|
||||
void FixedUpdate() {
|
||||
acceleration = (speedReference.position - lastPosition) - velocity;
|
||||
velocity = speedReference.position - lastPosition;
|
||||
lastPosition = speedReference.position;
|
||||
}
|
||||
|
||||
void UpdateLocal(SkeletonAnimation animation) {
|
||||
Vector3 vec = useAcceleration ? acceleration : velocity;
|
||||
|
||||
if (Mathf.Abs(vec.x) < returnThreshhold)
|
||||
goalRotation = Mathf.Lerp(goalRotation, 0, returnSpeed * Time.deltaTime);
|
||||
else
|
||||
goalRotation += vec.x * rotationFactor * Time.deltaTime * (bone.WorldFlipX ? -1 : 1);
|
||||
|
||||
goalRotation = Mathf.Clamp(goalRotation, minRotation, maxRotation);
|
||||
|
||||
bone.Rotation = Mathf.Lerp(bone.Rotation, bone.Rotation + goalRotation, boneSpeed * Time.deltaTime);
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7dae3f4db9a24bf4abe2059526bfd689
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@ -1,4 +1,38 @@
|
||||
using UnityEngine;
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License
|
||||
* Version 2.1
|
||||
*
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable and
|
||||
* non-transferable license to install, execute and perform the Spine Runtimes
|
||||
* Software (the "Software") solely for internal use. Without the written
|
||||
* permission of Esoteric Software (typically granted by licensing Spine), you
|
||||
* may not (a) modify, translate, adapt or otherwise create derivative works,
|
||||
* improvements of the Software or develop new applications using the Software
|
||||
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
|
||||
* trademark, patent or other intellectual property or proprietary rights
|
||||
* notices on or in the Software, including any copy thereof. Redistributions
|
||||
* in binary or source form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) 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.
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* FootSoldierExample created by Mitch Thompson
|
||||
* Full irrevocable rights and permissions granted to Esoteric Software
|
||||
*****************************************************************************/
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
|
||||
public class FootSoldierExample : MonoBehaviour {
|
||||
@ -11,10 +45,10 @@ public class FootSoldierExample : MonoBehaviour {
|
||||
[SpineSlot]
|
||||
public string eyesSlot;
|
||||
|
||||
[SpineAttachment(currentSkinOnly: true, slot: "eyesSlot")]
|
||||
[SpineAttachment(currentSkinOnly: true, slotField: "eyesSlot")]
|
||||
public string eyesOpenAttachment;
|
||||
|
||||
[SpineAttachment(currentSkinOnly: true, slot: "eyesSlot")]
|
||||
[SpineAttachment(currentSkinOnly: true, slotField: "eyesSlot")]
|
||||
public string blinkAttachment;
|
||||
|
||||
[Range(0, 0.2f)]
|
||||
|
||||
@ -1,4 +1,38 @@
|
||||
using UnityEngine;
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License
|
||||
* Version 2.1
|
||||
*
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable and
|
||||
* non-transferable license to install, execute and perform the Spine Runtimes
|
||||
* Software (the "Software") solely for internal use. Without the written
|
||||
* permission of Esoteric Software (typically granted by licensing Spine), you
|
||||
* may not (a) modify, translate, adapt or otherwise create derivative works,
|
||||
* improvements of the Software or develop new applications using the Software
|
||||
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
|
||||
* trademark, patent or other intellectual property or proprietary rights
|
||||
* notices on or in the Software, including any copy thereof. Redistributions
|
||||
* in binary or source form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) 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.
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* SpineboyController created by Mitch Thompson
|
||||
* Full irrevocable rights and permissions granted to Esoteric Software
|
||||
*****************************************************************************/
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
|
||||
[RequireComponent(typeof(SkeletonAnimation), typeof(Rigidbody2D))]
|
||||
|
||||
Binary file not shown.
36
spine-unity/Assets/spine-unity/CustomSkin.cs
Normal file
36
spine-unity/Assets/spine-unity/CustomSkin.cs
Normal file
@ -0,0 +1,36 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using Spine;
|
||||
|
||||
public class CustomSkin : MonoBehaviour {
|
||||
|
||||
|
||||
[System.Serializable]
|
||||
public class SkinPair {
|
||||
[SpineAttachment(currentSkinOnly: false, returnAttachmentPath: true, dataField: "skinSource")]
|
||||
public string sourceAttachment;
|
||||
[SpineSlot]
|
||||
public string targetSlot;
|
||||
[SpineAttachment(currentSkinOnly: true, placeholdersOnly: true)]
|
||||
public string targetAttachment;
|
||||
}
|
||||
|
||||
public SkeletonDataAsset skinSource;
|
||||
public SkinPair[] skinning;
|
||||
public Skin customSkin;
|
||||
|
||||
SkeletonRenderer skeletonRenderer;
|
||||
void Start() {
|
||||
skeletonRenderer = GetComponent<SkeletonRenderer>();
|
||||
Skeleton skeleton = skeletonRenderer.skeleton;
|
||||
|
||||
customSkin = new Skin("CustomSkin");
|
||||
|
||||
foreach (var pair in skinning) {
|
||||
var attachment = SpineAttachment.GetAttachment(pair.sourceAttachment, skinSource);
|
||||
customSkin.AddAttachment(skeleton.FindSlotIndex(pair.targetSlot), pair.targetAttachment, attachment);
|
||||
}
|
||||
|
||||
skeleton.SetSkin(customSkin);
|
||||
}
|
||||
}
|
||||
8
spine-unity/Assets/spine-unity/CustomSkin.cs.meta
Normal file
8
spine-unity/Assets/spine-unity/CustomSkin.cs.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6e55c8477eccddc4cb5c3551a3945ca7
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@ -50,9 +50,27 @@ public class AtlasAssetInspector : Editor {
|
||||
serializedObject.Update();
|
||||
AtlasAsset asset = (AtlasAsset)target;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.PropertyField(atlasFile);
|
||||
EditorGUILayout.PropertyField(materials, true);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
if (materials.arraySize == 0) {
|
||||
EditorGUILayout.LabelField(new GUIContent("Error: Missing materials", SpineEditorUtilities.Icons.warning));
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < materials.arraySize; i++) {
|
||||
SerializedProperty prop = materials.GetArrayElementAtIndex(i);
|
||||
Material mat = (Material)prop.objectReferenceValue;
|
||||
if (mat == null) {
|
||||
EditorGUILayout.LabelField(new GUIContent("Error: Materials cannot be null", SpineEditorUtilities.Icons.warning));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (atlasFile.objectReferenceValue != null) {
|
||||
Atlas atlas = asset.GetAtlas();
|
||||
|
||||
@ -21,7 +21,7 @@ TextureImporter:
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -1
|
||||
textureFormat: -3
|
||||
maxTextureSize: 1024
|
||||
textureSettings:
|
||||
filterMode: -1
|
||||
|
||||
@ -102,12 +102,18 @@ public class SkeletonDataAssetInspector : Editor {
|
||||
EditorGUILayout.PropertyField(skeletonJSON);
|
||||
EditorGUILayout.PropertyField(scale);
|
||||
if (EditorGUI.EndChangeCheck()) {
|
||||
if (m_previewUtility != null) {
|
||||
m_previewUtility.Cleanup();
|
||||
m_previewUtility = null;
|
||||
}
|
||||
if (serializedObject.ApplyModifiedProperties()) {
|
||||
|
||||
RepopulateWarnings();
|
||||
if (m_previewUtility != null) {
|
||||
m_previewUtility.Cleanup();
|
||||
m_previewUtility = null;
|
||||
}
|
||||
|
||||
RepopulateWarnings();
|
||||
OnEnable();
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -118,6 +124,8 @@ public class SkeletonDataAssetInspector : Editor {
|
||||
DrawSlotList();
|
||||
|
||||
} else {
|
||||
|
||||
DrawReimportButton();
|
||||
//Show Warnings
|
||||
foreach (var str in warnings)
|
||||
EditorGUILayout.LabelField(new GUIContent(str, SpineEditorUtilities.Icons.warning));
|
||||
@ -132,6 +140,24 @@ public class SkeletonDataAssetInspector : Editor {
|
||||
}
|
||||
}
|
||||
|
||||
void DrawReimportButton() {
|
||||
EditorGUI.BeginDisabledGroup(skeletonJSON.objectReferenceValue == null);
|
||||
if (GUILayout.Button(new GUIContent("Attempt Reimport", SpineEditorUtilities.Icons.warning))) {
|
||||
SpineEditorUtilities.ImportSpineContent(new string[] { AssetDatabase.GetAssetPath(skeletonJSON.objectReferenceValue) }, true);
|
||||
|
||||
if (m_previewUtility != null) {
|
||||
m_previewUtility.Cleanup();
|
||||
m_previewUtility = null;
|
||||
}
|
||||
|
||||
RepopulateWarnings();
|
||||
OnEnable();
|
||||
return;
|
||||
|
||||
}
|
||||
EditorGUI.EndDisabledGroup();
|
||||
}
|
||||
|
||||
void DrawAnimationStateInfo() {
|
||||
showAnimationStateData = EditorGUILayout.Foldout(showAnimationStateData, "Animation State Data");
|
||||
if (!showAnimationStateData)
|
||||
|
||||
@ -1,4 +1,38 @@
|
||||
using UnityEngine;
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License
|
||||
* Version 2.1
|
||||
*
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable and
|
||||
* non-transferable license to install, execute and perform the Spine Runtimes
|
||||
* Software (the "Software") solely for internal use. Without the written
|
||||
* permission of Esoteric Software (typically granted by licensing Spine), you
|
||||
* may not (a) modify, translate, adapt or otherwise create derivative works,
|
||||
* improvements of the Software or develop new applications using the Software
|
||||
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
|
||||
* trademark, patent or other intellectual property or proprietary rights
|
||||
* notices on or in the Software, including any copy thereof. Redistributions
|
||||
* in binary or source form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) 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.
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Spine Attribute Drawers created by Mitch Thompson
|
||||
* Full irrevocable rights and permissions granted to Esoteric Software
|
||||
*****************************************************************************/
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
@ -32,13 +66,13 @@ public class SpineSlotDrawer : PropertyDrawer {
|
||||
|
||||
SpineSlot attrib = (SpineSlot)attribute;
|
||||
|
||||
var skeletonDataAssetProperty = property.serializedObject.FindProperty(attrib.dataSource);
|
||||
var dataProperty = property.serializedObject.FindProperty(attrib.dataField);
|
||||
|
||||
if (skeletonDataAssetProperty != null) {
|
||||
if (skeletonDataAssetProperty.objectReferenceValue is SkeletonDataAsset) {
|
||||
skeletonDataAsset = (SkeletonDataAsset)skeletonDataAssetProperty.objectReferenceValue;
|
||||
} else if (skeletonDataAssetProperty.objectReferenceValue is SkeletonRenderer) {
|
||||
var renderer = (SkeletonRenderer)skeletonDataAssetProperty.objectReferenceValue;
|
||||
if (dataProperty != null) {
|
||||
if (dataProperty.objectReferenceValue is SkeletonDataAsset) {
|
||||
skeletonDataAsset = (SkeletonDataAsset)dataProperty.objectReferenceValue;
|
||||
} else if (dataProperty.objectReferenceValue is SkeletonRenderer) {
|
||||
var renderer = (SkeletonRenderer)dataProperty.objectReferenceValue;
|
||||
if (renderer != null)
|
||||
skeletonDataAsset = renderer.skeletonDataAsset;
|
||||
} else {
|
||||
@ -102,7 +136,6 @@ public class SpineSlotDrawer : PropertyDrawer {
|
||||
public class SpineSkinDrawer : PropertyDrawer {
|
||||
SkeletonDataAsset skeletonDataAsset;
|
||||
|
||||
|
||||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
|
||||
if (property.propertyType != SerializedPropertyType.String) {
|
||||
EditorGUI.LabelField(position, "ERROR:", "May only apply to type string");
|
||||
@ -111,13 +144,13 @@ public class SpineSkinDrawer : PropertyDrawer {
|
||||
|
||||
SpineSkin attrib = (SpineSkin)attribute;
|
||||
|
||||
var skeletonDataAssetProperty = property.serializedObject.FindProperty(attrib.dataSource);
|
||||
var dataProperty = property.serializedObject.FindProperty(attrib.dataField);
|
||||
|
||||
if (skeletonDataAssetProperty != null) {
|
||||
if (skeletonDataAssetProperty.objectReferenceValue is SkeletonDataAsset) {
|
||||
skeletonDataAsset = (SkeletonDataAsset)skeletonDataAssetProperty.objectReferenceValue;
|
||||
} else if (skeletonDataAssetProperty.objectReferenceValue is SkeletonRenderer) {
|
||||
var renderer = (SkeletonRenderer)skeletonDataAssetProperty.objectReferenceValue;
|
||||
if (dataProperty != null) {
|
||||
if (dataProperty.objectReferenceValue is SkeletonDataAsset) {
|
||||
skeletonDataAsset = (SkeletonDataAsset)dataProperty.objectReferenceValue;
|
||||
} else if (dataProperty.objectReferenceValue is SkeletonRenderer) {
|
||||
var renderer = (SkeletonRenderer)dataProperty.objectReferenceValue;
|
||||
if (renderer != null)
|
||||
skeletonDataAsset = renderer.skeletonDataAsset;
|
||||
} else {
|
||||
@ -256,13 +289,13 @@ public class SpineAnimationDrawer : PropertyDrawer {
|
||||
|
||||
SpineAnimation attrib = (SpineAnimation)attribute;
|
||||
|
||||
var skeletonDataAssetProperty = property.serializedObject.FindProperty(attrib.dataSource);
|
||||
var dataProperty = property.serializedObject.FindProperty(attrib.dataField);
|
||||
|
||||
if (skeletonDataAssetProperty != null) {
|
||||
if (skeletonDataAssetProperty.objectReferenceValue is SkeletonDataAsset) {
|
||||
skeletonDataAsset = (SkeletonDataAsset)skeletonDataAssetProperty.objectReferenceValue;
|
||||
} else if (skeletonDataAssetProperty.objectReferenceValue is SkeletonRenderer) {
|
||||
var renderer = (SkeletonRenderer)skeletonDataAssetProperty.objectReferenceValue;
|
||||
if (dataProperty != null) {
|
||||
if (dataProperty.objectReferenceValue is SkeletonDataAsset) {
|
||||
skeletonDataAsset = (SkeletonDataAsset)dataProperty.objectReferenceValue;
|
||||
} else if (dataProperty.objectReferenceValue is SkeletonRenderer) {
|
||||
var renderer = (SkeletonRenderer)dataProperty.objectReferenceValue;
|
||||
if (renderer != null)
|
||||
skeletonDataAsset = renderer.skeletonDataAsset;
|
||||
} else {
|
||||
@ -332,13 +365,13 @@ public class SpineAttachmentDrawer : PropertyDrawer {
|
||||
|
||||
SpineAttachment attrib = (SpineAttachment)attribute;
|
||||
|
||||
var skeletonDataAssetProperty = property.serializedObject.FindProperty(attrib.dataSource);
|
||||
var dataProperty = property.serializedObject.FindProperty(attrib.dataField);
|
||||
|
||||
if (skeletonDataAssetProperty != null) {
|
||||
if (skeletonDataAssetProperty.objectReferenceValue is SkeletonDataAsset) {
|
||||
skeletonDataAsset = (SkeletonDataAsset)skeletonDataAssetProperty.objectReferenceValue;
|
||||
} else if (skeletonDataAssetProperty.objectReferenceValue is SkeletonRenderer) {
|
||||
var renderer = (SkeletonRenderer)skeletonDataAssetProperty.objectReferenceValue;
|
||||
if (dataProperty != null) {
|
||||
if (dataProperty.objectReferenceValue is SkeletonDataAsset) {
|
||||
skeletonDataAsset = (SkeletonDataAsset)dataProperty.objectReferenceValue;
|
||||
} else if (dataProperty.objectReferenceValue is SkeletonRenderer) {
|
||||
var renderer = (SkeletonRenderer)dataProperty.objectReferenceValue;
|
||||
if (renderer != null)
|
||||
skeletonDataAsset = renderer.skeletonDataAsset;
|
||||
else {
|
||||
@ -381,8 +414,11 @@ public class SpineAttachmentDrawer : PropertyDrawer {
|
||||
List<Skin> validSkins = new List<Skin>();
|
||||
|
||||
if (skeletonRenderer != null && attrib.currentSkinOnly) {
|
||||
if (skeletonRenderer.skeleton.Skin != null)
|
||||
if (skeletonRenderer.skeleton.Skin != null) {
|
||||
validSkins.Add(skeletonRenderer.skeleton.Skin);
|
||||
} else {
|
||||
validSkins.Add(data.Skins[0]);
|
||||
}
|
||||
} else {
|
||||
foreach (Skin skin in data.Skins) {
|
||||
if (skin != null)
|
||||
@ -392,6 +428,8 @@ public class SpineAttachmentDrawer : PropertyDrawer {
|
||||
|
||||
GenericMenu menu = new GenericMenu();
|
||||
List<string> attachmentNames = new List<string>();
|
||||
List<string> placeholderNames = new List<string>();
|
||||
|
||||
string prefix = "";
|
||||
|
||||
if (skeletonRenderer != null && attrib.currentSkinOnly)
|
||||
@ -405,7 +443,7 @@ public class SpineAttachmentDrawer : PropertyDrawer {
|
||||
|
||||
Skin defaultSkin = data.Skins[0];
|
||||
|
||||
SerializedProperty slotProperty = property.serializedObject.FindProperty(attrib.slotSource);
|
||||
SerializedProperty slotProperty = property.serializedObject.FindProperty(attrib.slotField);
|
||||
string slotMatch = "";
|
||||
if (slotProperty != null) {
|
||||
if (slotProperty.propertyType == SerializedPropertyType.String) {
|
||||
@ -424,18 +462,31 @@ public class SpineAttachmentDrawer : PropertyDrawer {
|
||||
continue;
|
||||
|
||||
attachmentNames.Clear();
|
||||
placeholderNames.Clear();
|
||||
|
||||
skin.FindNamesForSlot(i, attachmentNames);
|
||||
if (skin != defaultSkin)
|
||||
if (skin != defaultSkin) {
|
||||
defaultSkin.FindNamesForSlot(i, attachmentNames);
|
||||
skin.FindNamesForSlot(i, placeholderNames);
|
||||
}
|
||||
|
||||
|
||||
for (int a = 0; a < attachmentNames.Count; a++) {
|
||||
|
||||
string attachmentPath = attachmentNames[a];
|
||||
string menuPath = prefix + data.Slots[i].Name + "/" + attachmentPath;
|
||||
string name = attachmentNames[a];
|
||||
|
||||
if (attrib.returnFullPath)
|
||||
if (attrib.returnAttachmentPath)
|
||||
name = skin.Name + "/" + data.Slots[i].Name + "/" + attachmentPath;
|
||||
menu.AddItem(new GUIContent(menuPath), name == property.stringValue, HandleSelect, new SpineDrawerValuePair(name, property));
|
||||
|
||||
if (attrib.placeholdersOnly && placeholderNames.Contains(attachmentPath) == false) {
|
||||
menu.AddDisabledItem(new GUIContent(menuPath));
|
||||
} else {
|
||||
menu.AddItem(new GUIContent(menuPath), name == property.stringValue, HandleSelect, new SpineDrawerValuePair(name, property));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -454,3 +505,81 @@ public class SpineAttachmentDrawer : PropertyDrawer {
|
||||
return 18;
|
||||
}
|
||||
}
|
||||
|
||||
[CustomPropertyDrawer(typeof(SpineBone))]
|
||||
public class SpineBoneDrawer : PropertyDrawer {
|
||||
SkeletonDataAsset skeletonDataAsset;
|
||||
|
||||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
|
||||
if (property.propertyType != SerializedPropertyType.String) {
|
||||
EditorGUI.LabelField(position, "ERROR:", "May only apply to type string");
|
||||
return;
|
||||
}
|
||||
|
||||
SpineBone attrib = (SpineBone)attribute;
|
||||
|
||||
var dataProperty = property.serializedObject.FindProperty(attrib.dataField);
|
||||
|
||||
if (dataProperty != null) {
|
||||
if (dataProperty.objectReferenceValue is SkeletonDataAsset) {
|
||||
skeletonDataAsset = (SkeletonDataAsset)dataProperty.objectReferenceValue;
|
||||
} else if (dataProperty.objectReferenceValue is SkeletonRenderer) {
|
||||
var renderer = (SkeletonRenderer)dataProperty.objectReferenceValue;
|
||||
if (renderer != null)
|
||||
skeletonDataAsset = renderer.skeletonDataAsset;
|
||||
} else {
|
||||
EditorGUI.LabelField(position, "ERROR:", "Invalid reference type");
|
||||
return;
|
||||
}
|
||||
|
||||
} else if (property.serializedObject.targetObject is Component) {
|
||||
var component = (Component)property.serializedObject.targetObject;
|
||||
if (component.GetComponent<SkeletonRenderer>() != null) {
|
||||
var skeletonRenderer = component.GetComponent<SkeletonRenderer>();
|
||||
skeletonDataAsset = skeletonRenderer.skeletonDataAsset;
|
||||
}
|
||||
}
|
||||
|
||||
if (skeletonDataAsset == null) {
|
||||
EditorGUI.LabelField(position, "ERROR:", "Must have reference to a SkeletonDataAsset");
|
||||
return;
|
||||
}
|
||||
|
||||
position = EditorGUI.PrefixLabel(position, label);
|
||||
|
||||
if (GUI.Button(position, property.stringValue, EditorStyles.popup)) {
|
||||
Selector(property);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Selector(SerializedProperty property) {
|
||||
SpineBone attrib = (SpineBone)attribute;
|
||||
SkeletonData data = skeletonDataAsset.GetSkeletonData(true);
|
||||
if (data == null)
|
||||
return;
|
||||
|
||||
GenericMenu menu = new GenericMenu();
|
||||
|
||||
menu.AddDisabledItem(new GUIContent(skeletonDataAsset.name));
|
||||
menu.AddSeparator("");
|
||||
|
||||
for (int i = 0; i < data.Bones.Count; i++) {
|
||||
string name = data.Bones[i].Name;
|
||||
if (name.StartsWith(attrib.startsWith))
|
||||
menu.AddItem(new GUIContent(name), name == property.stringValue, HandleSelect, new SpineDrawerValuePair(name, property));
|
||||
}
|
||||
|
||||
menu.ShowAsContext();
|
||||
}
|
||||
|
||||
void HandleSelect(object val) {
|
||||
var pair = (SpineDrawerValuePair)val;
|
||||
pair.property.stringValue = pair.str;
|
||||
pair.property.serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
public override float GetPropertyHeight(SerializedProperty property, GUIContent label) {
|
||||
return 18;
|
||||
}
|
||||
}
|
||||
|
||||
@ -209,8 +209,10 @@ public class SpineEditorUtilities : AssetPostprocessor {
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void OnPostprocessAllAssets(string[] imported, string[] deleted, string[] moved, string[] movedFromAssetPaths) {
|
||||
ImportSpineContent(imported, false);
|
||||
}
|
||||
public static void ImportSpineContent(string[] imported, bool reimport = false) {
|
||||
|
||||
List<string> atlasPaths = new List<string>();
|
||||
List<string> imagePaths = new List<string>();
|
||||
@ -242,6 +244,9 @@ public class SpineEditorUtilities : AssetPostprocessor {
|
||||
|
||||
//import atlases first
|
||||
foreach (string ap in atlasPaths) {
|
||||
if (!reimport && CheckForValidAtlas(ap))
|
||||
continue;
|
||||
|
||||
TextAsset atlasText = (TextAsset)AssetDatabase.LoadAssetAtPath(ap, typeof(TextAsset));
|
||||
AtlasAsset atlas = IngestSpineAtlas(atlasText);
|
||||
atlases.Add(atlas);
|
||||
@ -250,7 +255,14 @@ public class SpineEditorUtilities : AssetPostprocessor {
|
||||
//import skeletons and match them with atlases
|
||||
bool abortSkeletonImport = false;
|
||||
foreach (string sp in skeletonPaths) {
|
||||
if (!reimport && CheckForValidSkeletonData(sp)) {
|
||||
Debug.Log("Automatically skipping: " + sp);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
string dir = Path.GetDirectoryName(sp);
|
||||
|
||||
var localAtlases = FindAtlasesAtPath(dir);
|
||||
var requiredPaths = GetRequiredAtlasRegions(sp);
|
||||
var atlasMatch = GetMatchingAtlas(requiredPaths, localAtlases);
|
||||
@ -307,6 +319,48 @@ public class SpineEditorUtilities : AssetPostprocessor {
|
||||
//TODO: any post processing of images
|
||||
}
|
||||
|
||||
static bool CheckForValidSkeletonData(string skeletonJSONPath) {
|
||||
|
||||
string dir = Path.GetDirectoryName(skeletonJSONPath);
|
||||
TextAsset textAsset = (TextAsset)AssetDatabase.LoadAssetAtPath(skeletonJSONPath, typeof(TextAsset));
|
||||
DirectoryInfo dirInfo = new DirectoryInfo(dir);
|
||||
|
||||
FileInfo[] files = dirInfo.GetFiles("*.asset");
|
||||
|
||||
foreach (var f in files) {
|
||||
string localPath = dir + "/" + f.Name;
|
||||
var obj = AssetDatabase.LoadAssetAtPath(localPath, typeof(Object));
|
||||
if (obj is SkeletonDataAsset) {
|
||||
var skeletonDataAsset = (SkeletonDataAsset)obj;
|
||||
if (skeletonDataAsset.skeletonJSON == textAsset)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool CheckForValidAtlas(string atlasPath) {
|
||||
|
||||
string dir = Path.GetDirectoryName(atlasPath);
|
||||
TextAsset textAsset = (TextAsset)AssetDatabase.LoadAssetAtPath(atlasPath, typeof(TextAsset));
|
||||
DirectoryInfo dirInfo = new DirectoryInfo(dir);
|
||||
|
||||
FileInfo[] files = dirInfo.GetFiles("*.asset");
|
||||
|
||||
foreach (var f in files) {
|
||||
string localPath = dir + "/" + f.Name;
|
||||
var obj = AssetDatabase.LoadAssetAtPath(localPath, typeof(Object));
|
||||
if (obj is AtlasAsset) {
|
||||
var atlasAsset = (AtlasAsset)obj;
|
||||
if (atlasAsset.atlasFile == textAsset)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static List<AtlasAsset> MultiAtlasDialog(List<string> requiredPaths, string initialDirectory, string header = "") {
|
||||
|
||||
List<AtlasAsset> atlasAssets = new List<AtlasAsset>();
|
||||
|
||||
@ -1,87 +1,138 @@
|
||||
using UnityEngine;
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License
|
||||
* Version 2.1
|
||||
*
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable and
|
||||
* non-transferable license to install, execute and perform the Spine Runtimes
|
||||
* Software (the "Software") solely for internal use. Without the written
|
||||
* permission of Esoteric Software (typically granted by licensing Spine), you
|
||||
* may not (a) modify, translate, adapt or otherwise create derivative works,
|
||||
* improvements of the Software or develop new applications using the Software
|
||||
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
|
||||
* trademark, patent or other intellectual property or proprietary rights
|
||||
* notices on or in the Software, including any copy thereof. Redistributions
|
||||
* in binary or source form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) 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.
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Spine Attributes created by Mitch Thompson
|
||||
* Full irrevocable rights and permissions granted to Esoteric Software
|
||||
*****************************************************************************/
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
|
||||
public class SpineSlot : PropertyAttribute {
|
||||
public string startsWith = "";
|
||||
public string dataSource = "";
|
||||
public string dataField = "";
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// Smart popup menu for Spine Slots
|
||||
/// </summary>
|
||||
/// <param name="startsWith"></param>
|
||||
/// <param name="dataSource">SerializedProperty name containing a reference to either a SkeletonRenderer or a SkeletonDataAsset</param>
|
||||
public SpineSlot(string startsWith = "", string dataSource = "") {
|
||||
/// <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.
|
||||
/// 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 = "") {
|
||||
this.startsWith = startsWith;
|
||||
this.dataSource = dataSource;
|
||||
this.dataField = dataField;
|
||||
}
|
||||
}
|
||||
|
||||
public class SpineSkin : PropertyAttribute {
|
||||
public string startsWith = "";
|
||||
public string dataSource = "";
|
||||
public string dataField = "";
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// Smart popup menu for Spine Skins
|
||||
/// </summary>
|
||||
/// <param name="startsWith"></param>
|
||||
/// <param name="dataSource">SerializedProperty name containing a reference to either a SkeletonRenderer or a SkeletonDataAsset</param>
|
||||
public SpineSkin(string startsWith = "", string dataSource = "") {
|
||||
/// <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.
|
||||
/// 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 = "") {
|
||||
this.startsWith = startsWith;
|
||||
this.dataSource = dataSource;
|
||||
this.dataField = dataField;
|
||||
}
|
||||
}
|
||||
|
||||
public class SpineAtlasRegion : PropertyAttribute {
|
||||
|
||||
}
|
||||
|
||||
public class SpineAnimation : PropertyAttribute {
|
||||
public string startsWith = "";
|
||||
public string dataSource = "";
|
||||
public string dataField = "";
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// Smart popup menu for Spine Animations
|
||||
/// </summary>
|
||||
/// <param name="startsWith"></param>
|
||||
/// <param name="dataSource">SerializedProperty name containing a reference to either a SkeletonRenderer or a SkeletonDataAsset</param>
|
||||
public SpineAnimation(string startsWith = "", string dataSource = "") {
|
||||
/// <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.
|
||||
/// 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 = "") {
|
||||
this.startsWith = startsWith;
|
||||
this.dataSource = dataSource;
|
||||
this.dataField = dataField;
|
||||
}
|
||||
}
|
||||
|
||||
public class SpineAttachment : PropertyAttribute {
|
||||
public bool returnFullPath;
|
||||
public bool currentSkinOnly;
|
||||
public string dataSource = "";
|
||||
public string slotSource = "";
|
||||
public bool returnAttachmentPath = false;
|
||||
public bool currentSkinOnly = false;
|
||||
public bool placeholdersOnly = false;
|
||||
public string dataField = "";
|
||||
public string slotField = "";
|
||||
|
||||
|
||||
public SpineAttachment() {
|
||||
|
||||
}
|
||||
|
||||
public SpineAttachment(bool currentSkinOnly = true, bool returnFullPath = false, string slot = "", string dataSource = "") {
|
||||
/// <summary>
|
||||
/// Smart popup menu for Spine Attachments
|
||||
/// </summary>
|
||||
/// <param name="currentSkinOnly">Filters popup results to only include the current Skin. Only valid when a SkeletonRenderer is the data source.</param>
|
||||
/// <param name="returnAttachmentPath">Returns a fully qualified path for an Attachment in the format "Skin/Slot/AttachmentName"</param>
|
||||
/// <param name="placeholdersOnly">Filters popup results to exclude attachments that are not children of Skin Placeholders</param>
|
||||
/// <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="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 = "") {
|
||||
this.currentSkinOnly = currentSkinOnly;
|
||||
this.returnFullPath = returnFullPath;
|
||||
this.slotSource = slot;
|
||||
this.dataSource = dataSource;
|
||||
this.returnAttachmentPath = returnAttachmentPath;
|
||||
this.placeholdersOnly = placeholdersOnly;
|
||||
this.slotField = slotField;
|
||||
this.dataField = dataField;
|
||||
}
|
||||
|
||||
public static Hierarchy GetHierarchy(string fullPath) {
|
||||
return new Hierarchy(fullPath);
|
||||
}
|
||||
|
||||
public static Spine.Attachment GetAttachment(string fullPath, Spine.SkeletonData skeletonData) {
|
||||
var hierarchy = SpineAttachment.GetHierarchy(fullPath);
|
||||
public static Spine.Attachment GetAttachment(string attachmentPath, Spine.SkeletonData skeletonData) {
|
||||
var hierarchy = SpineAttachment.GetHierarchy(attachmentPath);
|
||||
if (hierarchy.name == "")
|
||||
return null;
|
||||
|
||||
return skeletonData.FindSkin(hierarchy.skin).GetAttachment(skeletonData.FindSlotIndex(hierarchy.slot), hierarchy.name);
|
||||
}
|
||||
|
||||
public static Spine.Attachment GetAttachment(string fullPath, SkeletonDataAsset skeletonDataAsset) {
|
||||
return GetAttachment(fullPath, skeletonDataAsset.GetSkeletonData(true));
|
||||
public static Spine.Attachment GetAttachment(string attachmentPath, SkeletonDataAsset skeletonDataAsset) {
|
||||
return GetAttachment(attachmentPath, skeletonDataAsset.GetSkeletonData(true));
|
||||
}
|
||||
|
||||
public struct Hierarchy {
|
||||
@ -108,4 +159,40 @@ public class SpineAttachment : PropertyAttribute {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class SpineBone : PropertyAttribute {
|
||||
public string startsWith = "";
|
||||
public string dataField = "";
|
||||
|
||||
/// <summary>
|
||||
/// Smart popup menu for Spine Bones
|
||||
/// </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.
|
||||
/// 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 = "") {
|
||||
this.startsWith = startsWith;
|
||||
this.dataField = dataField;
|
||||
}
|
||||
|
||||
public static Spine.Bone GetBone(string boneName, SkeletonRenderer renderer) {
|
||||
if (renderer.skeleton == null)
|
||||
return null;
|
||||
|
||||
return renderer.skeleton.FindBone(boneName);
|
||||
}
|
||||
|
||||
public static Spine.BoneData GetBoneData(string boneName, SkeletonDataAsset skeletonDataAsset) {
|
||||
var data = skeletonDataAsset.GetSkeletonData(true);
|
||||
|
||||
return data.FindBone(boneName);
|
||||
}
|
||||
}
|
||||
|
||||
public class SpineAtlasRegion : PropertyAttribute {
|
||||
//TODO: Standardize with Skeleton attributes
|
||||
//NOTE: For now, relies on locally scoped field named "atlasAsset" for source.
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user