[unity] Unified interfaces for Skeleton instance components. Used by SpineAttributeDrawers.

This commit is contained in:
pharan 2016-07-27 05:40:33 +08:00
parent a7661270c0
commit e23bec8ddb
6 changed files with 41 additions and 31 deletions

View File

@ -38,10 +38,10 @@ namespace Spine.Unity.Editor {
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 if (dataProperty.objectReferenceValue is ISkeletonComponent) {
var skeletonComponent = (ISkeletonComponent)dataProperty.objectReferenceValue;
if (skeletonComponent != null)
skeletonDataAsset = skeletonComponent.SkeletonDataAsset;
} else {
EditorGUI.LabelField(position, "ERROR:", "Invalid reference type");
return;
@ -49,10 +49,9 @@ namespace Spine.Unity.Editor {
} else if (property.serializedObject.targetObject is Component) {
var component = (Component)property.serializedObject.targetObject;
if (component.GetComponentInChildren<SkeletonRenderer>() != null) {
var skeletonRenderer = component.GetComponentInChildren<SkeletonRenderer>();
skeletonDataAsset = skeletonRenderer.skeletonDataAsset;
}
ISkeletonComponent skeletonComponent = component.GetComponentInChildren(typeof(ISkeletonComponent)) as ISkeletonComponent;
if (skeletonComponent != null)
skeletonDataAsset = skeletonComponent.SkeletonDataAsset;
}
if (skeletonDataAsset == null) {

View File

@ -31,7 +31,9 @@
using UnityEngine;
namespace Spine.Unity {
public delegate void UpdateBonesDelegate (ISkeletonAnimation skeletonRenderer);
public delegate void UpdateBonesDelegate (ISkeletonAnimation animatedSkeletonComponent);
/// <summary>A Spine-Unity Component that animates a Skeleton but not necessarily with a Spine.AnimationState.</summary>
public interface ISkeletonAnimation {
event UpdateBonesDelegate UpdateLocal;
event UpdateBonesDelegate UpdateWorld;
@ -39,5 +41,20 @@ namespace Spine.Unity {
void LateUpdate ();
Skeleton Skeleton { get; }
}
}
/// <summary>A Spine-Unity Component that manages a Spine.Skeleton instance, instantiated from a SkeletonDataAsset.</summary>
public interface ISkeletonComponent {
/// <summary>Gets the SkeletonDataAsset of the Spine Component.</summary>
SkeletonDataAsset SkeletonDataAsset { get; }
/// <summary>Gets the Spine.Skeleton instance of the Spine Component. This is equivalent to SkeletonRenderer's .skeleton.</summary>
Skeleton Skeleton { get; }
}
/// <summary>A Spine-Unity Component that uses a Spine.AnimationState to animate its skeleton.</summary>
public interface IAnimationStateComponent {
/// <summary>Gets the Spine.AnimationState of the animated Spine Component. This is equivalent to SkeletonAnimation.state.</summary>
AnimationState AnimationState { get; }
}
}

View File

@ -39,10 +39,11 @@ using Spine;
namespace Spine.Unity {
[ExecuteInEditMode, RequireComponent(typeof(CanvasRenderer), typeof(RectTransform)), DisallowMultipleComponent]
[AddComponentMenu("Spine/SkeletonGraphic (Unity UI Canvas)")]
public class SkeletonGraphic : MaskableGraphic {
public class SkeletonGraphic : MaskableGraphic, ISkeletonComponent, IAnimationStateComponent {
#region Inspector
public SkeletonDataAsset skeletonDataAsset;
public SkeletonDataAsset SkeletonDataAsset { get { return skeletonDataAsset; } }
[SpineSkin(dataField:"skeletonDataAsset")]
public string initialSkinName = "default";

View File

@ -37,12 +37,13 @@ namespace Spine.Unity {
[ExecuteInEditMode]
[AddComponentMenu("Spine/SkeletonAnimation")]
[HelpURL("http://esotericsoftware.com/spine-unity-documentation#Controlling-Animation")]
public class SkeletonAnimation : SkeletonRenderer, ISkeletonAnimation {
public class SkeletonAnimation : SkeletonRenderer, ISkeletonAnimation, Spine.Unity.IAnimationStateComponent {
/// <summary>
/// This is the Spine.AnimationState object of this SkeletonAnimation. You can control animations through it.
/// Note that this object, like .skeleton, is not guaranteed to exist in Awake. Do all accesses and caching to it in Start</summary>
public Spine.AnimationState state;
public Spine.AnimationState AnimationState { get { return this.state; } }
public event UpdateBonesDelegate UpdateLocal {
add { _UpdateLocal += value; }
@ -63,18 +64,9 @@ namespace Spine.Unity {
protected event UpdateBonesDelegate _UpdateWorld;
protected event UpdateBonesDelegate _UpdateComplete;
/// <summary>Gets the skeleton.</summary>
public Skeleton Skeleton {
get {
this.Initialize(false);
return this.skeleton;
}
}
[SerializeField]
[SpineAnimation]
private String _animationName;
public String AnimationName {
get {
if (!valid) {
@ -95,7 +87,7 @@ namespace Spine.Unity {
return;
}
if (value == null || value.Length == 0)
if (string.IsNullOrEmpty(value))
state.ClearTrack(0);
else
state.SetAnimation(0, value, loop);
@ -103,17 +95,13 @@ namespace Spine.Unity {
}
/// <summary>Whether or not an animation should loop. This only applies to the initial animation specified in the inspector, or any subsequent Animations played through .AnimationName. Animations set through state.SetAnimation are unaffected.</summary>
#if UNITY_5
[Tooltip("Whether or not an animation should loop. This only applies to the initial animation specified in the inspector, or any subsequent Animations played through .AnimationName. Animations set through state.SetAnimation are unaffected.")]
#endif
public bool loop;
/// <summary>
/// The rate at which animations progress over time. 1 means 100%. 0.5 means 50%.</summary>
/// <remarks>AnimationState and TrackEntry also have their own timeScale. These are combined multiplicatively.</remarks>
#if UNITY_5
[Tooltip("The rate at which animations progress over time. 1 means 100%. 0.5 means 50%.")]
#endif
public float timeScale = 1;
#region Runtime Instantiation
@ -155,8 +143,8 @@ namespace Spine.Unity {
}
#else
if (!string.IsNullOrEmpty(_animationName)) {
state.SetAnimation(0, _animationName, loop);
Update(0);
state.SetAnimation(0, _animationName, loop);
Update(0);
}
#endif
}

View File

@ -33,8 +33,6 @@ namespace Spine.Unity {
protected event UpdateBonesDelegate _UpdateWorld;
protected event UpdateBonesDelegate _UpdateComplete;
public Skeleton Skeleton { get { return this.skeleton; } }
readonly Dictionary<int, Spine.Animation> animationTable = new Dictionary<int, Spine.Animation>();
readonly Dictionary<AnimationClip, int> clipNameHashCodeTable = new Dictionary<AnimationClip, int>();
Animator animator;

View File

@ -46,12 +46,13 @@ namespace Spine.Unity {
/// <summary>Renders a skeleton.</summary>
[ExecuteInEditMode, RequireComponent(typeof(MeshFilter), typeof(MeshRenderer)), DisallowMultipleComponent]
[HelpURL("http://esotericsoftware.com/spine-unity-documentation#Rendering")]
public class SkeletonRenderer : MonoBehaviour {
public class SkeletonRenderer : MonoBehaviour, ISkeletonComponent {
public delegate void SkeletonRendererDelegate (SkeletonRenderer skeletonRenderer);
public SkeletonRendererDelegate OnRebuild;
public SkeletonDataAsset skeletonDataAsset;
public SkeletonDataAsset SkeletonDataAsset { get { return skeletonDataAsset; } }
public String initialSkinName;
#region Advanced
@ -119,6 +120,12 @@ namespace Spine.Unity {
[System.NonSerialized] public bool valid;
[System.NonSerialized] public Skeleton skeleton;
public Skeleton Skeleton {
get {
Initialize(false);
return skeleton;
}
}
Spine.Unity.DoubleBuffered<SkeletonRenderer.SmartMesh> doubleBufferedMesh;
readonly SmartMesh.Instruction currentInstructions = new SmartMesh.Instruction();