Formatted source, committed formatter policy.

This commit is contained in:
NathanSweet 2014-10-05 20:29:11 +02:00
parent 7b07557e5b
commit 2902fb2ec9
38 changed files with 1207 additions and 1301 deletions

View File

@ -39,21 +39,21 @@ using System.Collections;
[RequireComponent(typeof(CharacterController))] [RequireComponent(typeof(CharacterController))]
public class BasicPlatformerController : MonoBehaviour { public class BasicPlatformerController : MonoBehaviour {
#if !UNITY_4_3 && !UNITY_4_4 #if UNITY_4_5
[Header("Controls")] [Header("Controls")]
#endif #endif
public string XAxis = "Horizontal"; public string XAxis = "Horizontal";
public string YAxis = "Vertical"; public string YAxis = "Vertical";
public string JumpButton = "Jump"; public string JumpButton = "Jump";
#if !UNITY_4_3 && !UNITY_4_4 #if UNITY_4_5
[Header("Moving")] [Header("Moving")]
#endif #endif
public float walkSpeed = 4; public float walkSpeed = 4;
public float runSpeed = 10; public float runSpeed = 10;
public float gravity = 65; public float gravity = 65;
#if !UNITY_4_3 && !UNITY_4_4 #if UNITY_4_5
[Header("Jumping")] [Header("Jumping")]
#endif #endif
public float jumpSpeed = 25; public float jumpSpeed = 25;
@ -62,13 +62,13 @@ public class BasicPlatformerController : MonoBehaviour {
public float forceCrouchVelocity = 25; public float forceCrouchVelocity = 25;
public float forceCrouchDuration = 0.5f; public float forceCrouchDuration = 0.5f;
#if !UNITY_4_3 && !UNITY_4_4 #if UNITY_4_5
[Header("Graphics")] [Header("Graphics")]
#endif #endif
public Transform graphicsRoot; public Transform graphicsRoot;
public SkeletonAnimation skeletonAnimation; public SkeletonAnimation skeletonAnimation;
#if !UNITY_4_3 && !UNITY_4_4 #if UNITY_4_5
[Header("Animation")] [Header("Animation")]
#endif #endif
public string walkName = "Walk"; public string walkName = "Walk";
@ -78,16 +78,13 @@ public class BasicPlatformerController : MonoBehaviour {
public string fallName = "Fall"; public string fallName = "Fall";
public string crouchName = "Crouch"; public string crouchName = "Crouch";
#if !UNITY_4_3 && !UNITY_4_4 #if UNITY_4_5
[Header("Audio")] [Header("Audio")]
#endif #endif
public AudioSource jumpAudioSource; public AudioSource jumpAudioSource;
public AudioSource hardfallAudioSource; public AudioSource hardfallAudioSource;
public AudioSource footstepAudioSource; public AudioSource footstepAudioSource;
public string footstepEventName = "Footstep"; public string footstepEventName = "Footstep";
CharacterController controller; CharacterController controller;
Vector2 velocity = Vector2.zero; Vector2 velocity = Vector2.zero;
Vector2 lastVelocity = Vector2.zero; Vector2 lastVelocity = Vector2.zero;
@ -95,31 +92,26 @@ public class BasicPlatformerController : MonoBehaviour {
float jumpEndTime = 0; float jumpEndTime = 0;
bool jumpInterrupt = false; bool jumpInterrupt = false;
float forceCrouchEndTime; float forceCrouchEndTime;
Quaternion flippedRotation = Quaternion.Euler(0, 180, 0); Quaternion flippedRotation = Quaternion.Euler(0, 180, 0);
void Awake() void Awake () {
{
controller = GetComponent<CharacterController>(); controller = GetComponent<CharacterController>();
} }
void Start(){ void Start () {
//register a callback for Spine Events (in this case, Footstep) //register a callback for Spine Events (in this case, Footstep)
skeletonAnimation.state.Event += HandleEvent; skeletonAnimation.state.Event += HandleEvent;
} }
void HandleEvent (Spine.AnimationState state, int trackIndex, Spine.Event e) void HandleEvent (Spine.AnimationState state, int trackIndex, Spine.Event e) {
{
//play some sound if footstep event fired //play some sound if footstep event fired
if(e.Data.Name == footstepEventName){ if (e.Data.Name == footstepEventName) {
footstepAudioSource.Stop(); footstepAudioSource.Stop();
footstepAudioSource.Play(); footstepAudioSource.Play();
} }
} }
void Update() void Update () {
{
//control inputs //control inputs
float x = Input.GetAxis(XAxis); float x = Input.GetAxis(XAxis);
float y = Input.GetAxis(YAxis); float y = Input.GetAxis(YAxis);
@ -129,36 +121,28 @@ public class BasicPlatformerController : MonoBehaviour {
//Calculate control velocity //Calculate control velocity
if (!crouching) { if (!crouching) {
if (Input.GetButtonDown(JumpButton) && controller.isGrounded) if (Input.GetButtonDown(JumpButton) && controller.isGrounded) {
{
//jump //jump
jumpAudioSource.Stop(); jumpAudioSource.Stop();
jumpAudioSource.Play(); jumpAudioSource.Play();
velocity.y = jumpSpeed; velocity.y = jumpSpeed;
jumpEndTime = Time.time + jumpDuration; jumpEndTime = Time.time + jumpDuration;
} } else if (Time.time < jumpEndTime && Input.GetButtonUp(JumpButton)) {
else if (Time.time < jumpEndTime && Input.GetButtonUp(JumpButton))
{
jumpInterrupt = true; jumpInterrupt = true;
} }
if (x != 0) if (x != 0) {
{
//walk or run //walk or run
velocity.x = Mathf.Abs(x) > 0.6f ? runSpeed : walkSpeed; velocity.x = Mathf.Abs(x) > 0.6f ? runSpeed : walkSpeed;
velocity.x *= Mathf.Sign(x); velocity.x *= Mathf.Sign(x);
} }
if (jumpInterrupt) if (jumpInterrupt) {
{
//interrupt jump and smoothly cut Y velocity //interrupt jump and smoothly cut Y velocity
if (velocity.y > 0) if (velocity.y > 0) {
{
velocity.y = Mathf.MoveTowards(velocity.y, 0, Time.deltaTime * 100); velocity.y = Mathf.MoveTowards(velocity.y, 0, Time.deltaTime * 100);
} } else {
else
{
jumpInterrupt = false; jumpInterrupt = false;
} }
} }
@ -170,8 +154,7 @@ public class BasicPlatformerController : MonoBehaviour {
//move //move
controller.Move(new Vector3(velocity.x, velocity.y, 0) * Time.deltaTime); controller.Move(new Vector3(velocity.x, velocity.y, 0) * Time.deltaTime);
if (controller.isGrounded) if (controller.isGrounded) {
{
//cancel out Y velocity if on ground //cancel out Y velocity if on ground
velocity.y = -gravity * Time.deltaTime; velocity.y = -gravity * Time.deltaTime;
jumpInterrupt = false; jumpInterrupt = false;
@ -180,15 +163,12 @@ public class BasicPlatformerController : MonoBehaviour {
Vector2 deltaVelocity = lastVelocity - velocity; Vector2 deltaVelocity = lastVelocity - velocity;
if (!lastGrounded && controller.isGrounded) if (!lastGrounded && controller.isGrounded) {
{
//detect hard fall //detect hard fall
if ((gravity*Time.deltaTime) - deltaVelocity.y > forceCrouchVelocity) if ((gravity * Time.deltaTime) - deltaVelocity.y > forceCrouchVelocity) {
{
forceCrouchEndTime = Time.time + forceCrouchDuration; forceCrouchEndTime = Time.time + forceCrouchDuration;
hardfallAudioSource.Play(); hardfallAudioSource.Play();
} } else {
else{
//play footstep audio if light fall because why not //play footstep audio if light fall because why not
footstepAudioSource.Play(); footstepAudioSource.Play();
} }
@ -196,28 +176,20 @@ public class BasicPlatformerController : MonoBehaviour {
} }
//graphics updates //graphics updates
if (controller.isGrounded) if (controller.isGrounded) {
{ if (crouching) { //crouch
if (crouching) //crouch
{
skeletonAnimation.AnimationName = crouchName; skeletonAnimation.AnimationName = crouchName;
} } else {
else
{
if (x == 0) //idle if (x == 0) //idle
skeletonAnimation.AnimationName = idleName; skeletonAnimation.AnimationName = idleName;
else //move else //move
skeletonAnimation.AnimationName = Mathf.Abs(x) > 0.6f ? runName : walkName; skeletonAnimation.AnimationName = Mathf.Abs(x) > 0.6f ? runName : walkName;
} }
} } else {
else
{
if (velocity.y > 0) //jump if (velocity.y > 0) //jump
skeletonAnimation.AnimationName = jumpName; skeletonAnimation.AnimationName = jumpName;
else //fall else //fall
skeletonAnimation.AnimationName = fallName; skeletonAnimation.AnimationName = fallName;
} }
//flip left or right //flip left or right

View File

@ -39,10 +39,8 @@ using System.Collections;
public class ConstrainedCamera : MonoBehaviour { public class ConstrainedCamera : MonoBehaviour {
public Transform target; public Transform target;
public Vector3 offset; public Vector3 offset;
public Vector3 min; public Vector3 min;
public Vector3 max; public Vector3 max;
public float smoothing = 5f; public float smoothing = 5f;
// Use this for initialization // Use this for initialization

View File

@ -5,19 +5,15 @@ using System.Collections;
public class SpineboyController : MonoBehaviour { public class SpineboyController : MonoBehaviour {
SkeletonAnimation skeletonAnimation; SkeletonAnimation skeletonAnimation;
public string idleAnimation = "idle"; public string idleAnimation = "idle";
public string walkAnimation = "walk"; public string walkAnimation = "walk";
public string runAnimation = "run"; public string runAnimation = "run";
public string hitAnimation = "hit"; public string hitAnimation = "hit";
public string deathAnimation = "death"; public string deathAnimation = "death";
public float walkVelocity = 1; public float walkVelocity = 1;
public float runVelocity = 3; public float runVelocity = 3;
public int hp = 10; public int hp = 10;
string currentAnimation = ""; string currentAnimation = "";
bool hit = false; bool hit = false;
bool dead = false; bool dead = false;
@ -25,59 +21,53 @@ public class SpineboyController : MonoBehaviour {
skeletonAnimation = GetComponent<SkeletonAnimation>(); skeletonAnimation = GetComponent<SkeletonAnimation>();
} }
void Update () {
void Update(){ if (!dead) {
if(!dead){
float x = Input.GetAxis("Horizontal"); float x = Input.GetAxis("Horizontal");
float absX = Mathf.Abs(x); float absX = Mathf.Abs(x);
if(!hit){ if (!hit) {
if(x > 0) if (x > 0)
skeletonAnimation.skeleton.FlipX = false; skeletonAnimation.skeleton.FlipX = false;
else if(x < 0) else if (x < 0)
skeletonAnimation.skeleton.FlipX = true; skeletonAnimation.skeleton.FlipX = true;
if(absX > 0.7f){ if (absX > 0.7f) {
SetAnimation(runAnimation, true); SetAnimation(runAnimation, true);
rigidbody2D.velocity = new Vector2( runVelocity * Mathf.Sign(x), rigidbody2D.velocity.y); rigidbody2D.velocity = new Vector2(runVelocity * Mathf.Sign(x), rigidbody2D.velocity.y);
} } else if (absX > 0) {
else if(absX > 0){
SetAnimation(walkAnimation, true); SetAnimation(walkAnimation, true);
rigidbody2D.velocity = new Vector2( walkVelocity * Mathf.Sign(x), rigidbody2D.velocity.y); rigidbody2D.velocity = new Vector2(walkVelocity * Mathf.Sign(x), rigidbody2D.velocity.y);
} } else {
else{
SetAnimation(idleAnimation, true); SetAnimation(idleAnimation, true);
rigidbody2D.velocity = new Vector2( 0, rigidbody2D.velocity.y); rigidbody2D.velocity = new Vector2(0, rigidbody2D.velocity.y);
} }
} } else {
else{ if (skeletonAnimation.state.GetCurrent(0).Animation.Name != hitAnimation)
if(skeletonAnimation.state.GetCurrent(0).Animation.Name != hitAnimation)
hit = false; hit = false;
} }
} }
} }
void SetAnimation (string anim, bool loop) {
void SetAnimation(string anim, bool loop){ if (currentAnimation != anim) {
if(currentAnimation != anim){
skeletonAnimation.state.SetAnimation(0, anim, loop); skeletonAnimation.state.SetAnimation(0, anim, loop);
currentAnimation = anim; currentAnimation = anim;
} }
} }
void OnMouseUp(){ void OnMouseUp () {
if(hp > 0){ if (hp > 0) {
hp--; hp--;
if(hp == 0){ if (hp == 0) {
SetAnimation(deathAnimation, false); SetAnimation(deathAnimation, false);
dead = true; dead = true;
} } else {
else{
skeletonAnimation.state.SetAnimation(0, hitAnimation, false); skeletonAnimation.state.SetAnimation(0, hitAnimation, false);
skeletonAnimation.state.AddAnimation(0, currentAnimation, true, 0); skeletonAnimation.state.AddAnimation(0, currentAnimation, true, 0);
rigidbody2D.velocity = new Vector2( 0, rigidbody2D.velocity.y); rigidbody2D.velocity = new Vector2(0, rigidbody2D.velocity.y);
hit = true; hit = true;
} }

View File

@ -1,6 +1,7 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 6bc52290ef03f2846ba38d67e2823598 guid: 6bc52290ef03f2846ba38d67e2823598
TextureImporter: TextureImporter:
fileIDToRecycleName: {}
serializedVersion: 2 serializedVersion: 2
mipmaps: mipmaps:
mipMapMode: 0 mipMapMode: 0
@ -21,7 +22,7 @@ TextureImporter:
generateCubemap: 0 generateCubemap: 0
seamlessCubemap: 0 seamlessCubemap: 0
textureFormat: -3 textureFormat: -3
maxTextureSize: 1024 maxTextureSize: 2048
textureSettings: textureSettings:
filterMode: -1 filterMode: -1
aniso: -1 aniso: -1

View File

@ -1,6 +1,7 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 12c126994123f12468cf4c5a2684078a guid: 12c126994123f12468cf4c5a2684078a
TextureImporter: TextureImporter:
fileIDToRecycleName: {}
serializedVersion: 2 serializedVersion: 2
mipmaps: mipmaps:
mipMapMode: 0 mipMapMode: 0
@ -21,7 +22,7 @@ TextureImporter:
generateCubemap: 0 generateCubemap: 0
seamlessCubemap: 0 seamlessCubemap: 0
textureFormat: -3 textureFormat: -3
maxTextureSize: 1024 maxTextureSize: 2048
textureSettings: textureSettings:
filterMode: -1 filterMode: -1
aniso: -1 aniso: -1

View File

@ -22,7 +22,7 @@ TextureImporter:
generateCubemap: 0 generateCubemap: 0
seamlessCubemap: 0 seamlessCubemap: 0
textureFormat: -3 textureFormat: -3
maxTextureSize: 1024 maxTextureSize: 2048
textureSettings: textureSettings:
filterMode: -1 filterMode: -1
aniso: -1 aniso: -1

View File

@ -1,6 +1,7 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 803c2e614a63081439fde6276d110661 guid: 803c2e614a63081439fde6276d110661
TextureImporter: TextureImporter:
fileIDToRecycleName: {}
serializedVersion: 2 serializedVersion: 2
mipmaps: mipmaps:
mipMapMode: 0 mipMapMode: 0
@ -35,6 +36,7 @@ TextureImporter:
spriteMeshType: 1 spriteMeshType: 1
alignment: 0 alignment: 0
spritePivot: {x: .5, y: .5} spritePivot: {x: .5, y: .5}
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 100 spritePixelsToUnits: 100
alphaIsTransparency: 0 alphaIsTransparency: 0
textureType: -1 textureType: -1

View File

@ -1,6 +1,7 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 4261719a8f729a644b2dab6113d1b0ea guid: 4261719a8f729a644b2dab6113d1b0ea
TextureImporter: TextureImporter:
fileIDToRecycleName: {}
serializedVersion: 2 serializedVersion: 2
mipmaps: mipmaps:
mipMapMode: 0 mipMapMode: 0
@ -21,7 +22,7 @@ TextureImporter:
generateCubemap: 0 generateCubemap: 0
seamlessCubemap: 0 seamlessCubemap: 0
textureFormat: -3 textureFormat: -3
maxTextureSize: 1024 maxTextureSize: 2048
textureSettings: textureSettings:
filterMode: -1 filterMode: -1
aniso: -1 aniso: -1
@ -35,6 +36,7 @@ TextureImporter:
spriteMeshType: 1 spriteMeshType: 1
alignment: 0 alignment: 0
spritePivot: {x: .5, y: .5} spritePivot: {x: .5, y: .5}
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 100 spritePixelsToUnits: 100
alphaIsTransparency: 0 alphaIsTransparency: 0
textureType: -1 textureType: -1

View File

@ -1,6 +1,7 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 49bb65eefe08e424bbf7a38bc98ec638 guid: 49bb65eefe08e424bbf7a38bc98ec638
TextureImporter: TextureImporter:
fileIDToRecycleName: {}
serializedVersion: 2 serializedVersion: 2
mipmaps: mipmaps:
mipMapMode: 0 mipMapMode: 0
@ -21,7 +22,7 @@ TextureImporter:
generateCubemap: 0 generateCubemap: 0
seamlessCubemap: 0 seamlessCubemap: 0
textureFormat: -3 textureFormat: -3
maxTextureSize: 1024 maxTextureSize: 2048
textureSettings: textureSettings:
filterMode: -1 filterMode: -1
aniso: -1 aniso: -1

View File

@ -40,11 +40,10 @@ using Spine;
public class BoneFollower : MonoBehaviour { public class BoneFollower : MonoBehaviour {
[System.NonSerialized] [System.NonSerialized]
public bool valid; public bool
valid;
public SkeletonRenderer skeletonRenderer; public SkeletonRenderer skeletonRenderer;
public Bone bone; public Bone bone;
public bool followZPosition = true; public bool followZPosition = true;
public bool followBoneRotation = true; public bool followBoneRotation = true;
@ -52,20 +51,18 @@ public class BoneFollower : MonoBehaviour {
get { return skeletonRenderer; } get { return skeletonRenderer; }
set { set {
skeletonRenderer = value; skeletonRenderer = value;
Reset (); Reset();
} }
} }
/// <summary>If a bone isn't set, boneName is used to find the bone.</summary> /// <summary>If a bone isn't set, boneName is used to find the bone.</summary>
public String boneName; public String boneName;
public bool resetOnAwake = true; public bool resetOnAwake = true;
protected Transform cachedTransform; protected Transform cachedTransform;
protected Transform skeletonTransform; protected Transform skeletonTransform;
public void HandleResetRenderer(SkeletonRenderer skeletonRenderer){ public void HandleResetRenderer (SkeletonRenderer skeletonRenderer) {
Reset(); Reset();
} }
@ -73,32 +70,32 @@ public class BoneFollower : MonoBehaviour {
bone = null; bone = null;
cachedTransform = transform; cachedTransform = transform;
valid = skeletonRenderer != null && skeletonRenderer.valid; valid = skeletonRenderer != null && skeletonRenderer.valid;
if (!valid) return; if (!valid)
return;
skeletonTransform = skeletonRenderer.transform; skeletonTransform = skeletonRenderer.transform;
skeletonRenderer.OnReset -= HandleResetRenderer; skeletonRenderer.OnReset -= HandleResetRenderer;
skeletonRenderer.OnReset += HandleResetRenderer; skeletonRenderer.OnReset += HandleResetRenderer;
if(Application.isEditor) if (Application.isEditor)
DoUpdate(); DoUpdate();
} }
void OnDestroy(){ void OnDestroy () {
//cleanup //cleanup
if(skeletonRenderer != null) if (skeletonRenderer != null)
skeletonRenderer.OnReset -= HandleResetRenderer; skeletonRenderer.OnReset -= HandleResetRenderer;
} }
public void Awake () { public void Awake () {
if(resetOnAwake) if (resetOnAwake)
Reset(); Reset();
} }
void LateUpdate(){ void LateUpdate () {
DoUpdate(); DoUpdate();
} }
public void DoUpdate () { public void DoUpdate () {
if (!valid) { if (!valid) {
Reset(); Reset();
@ -106,13 +103,13 @@ public class BoneFollower : MonoBehaviour {
} }
if (bone == null) { if (bone == null) {
if (boneName == null || boneName.Length == 0) return; if (boneName == null || boneName.Length == 0)
return;
bone = skeletonRenderer.skeleton.FindBone(boneName); bone = skeletonRenderer.skeleton.FindBone(boneName);
if (bone == null) { if (bone == null) {
Debug.LogError("Bone not found: " + boneName, this); Debug.LogError("Bone not found: " + boneName, this);
return; return;
} } else {
else{
} }
} }
@ -123,21 +120,22 @@ public class BoneFollower : MonoBehaviour {
if (cachedTransform.parent == skeletonTransform) { if (cachedTransform.parent == skeletonTransform) {
cachedTransform.localPosition = new Vector3(bone.worldX, bone.worldY, followZPosition ? 0f : cachedTransform.localPosition.z); cachedTransform.localPosition = new Vector3(bone.worldX, bone.worldY, followZPosition ? 0f : cachedTransform.localPosition.z);
if(followBoneRotation) { if (followBoneRotation) {
Vector3 rotation = cachedTransform.localRotation.eulerAngles; Vector3 rotation = cachedTransform.localRotation.eulerAngles;
cachedTransform.localRotation = Quaternion.Euler(rotation.x, rotation.y, bone.worldRotation * flipRotation); cachedTransform.localRotation = Quaternion.Euler(rotation.x, rotation.y, bone.worldRotation * flipRotation);
} }
} else { } else {
Vector3 targetWorldPosition = skeletonTransform.TransformPoint(new Vector3(bone.worldX, bone.worldY, 0f)); Vector3 targetWorldPosition = skeletonTransform.TransformPoint(new Vector3(bone.worldX, bone.worldY, 0f));
if(!followZPosition) targetWorldPosition.z = cachedTransform.position.z; if (!followZPosition)
targetWorldPosition.z = cachedTransform.position.z;
cachedTransform.position = targetWorldPosition; cachedTransform.position = targetWorldPosition;
if(followBoneRotation) { if (followBoneRotation) {
Vector3 rotation = skeletonTransform.rotation.eulerAngles; Vector3 rotation = skeletonTransform.rotation.eulerAngles;
cachedTransform.rotation = Quaternion.Euler(rotation.x, rotation.y, skeletonTransform.rotation.eulerAngles.z + (bone.worldRotation * flipRotation) ); cachedTransform.rotation = Quaternion.Euler(rotation.x, rotation.y, skeletonTransform.rotation.eulerAngles.z + (bone.worldRotation * flipRotation));
} }
} }

View File

@ -27,7 +27,6 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/ *****************************************************************************/
using System; using System;
using UnityEditor; using UnityEditor;
using UnityEngine; using UnityEngine;

View File

@ -27,7 +27,6 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/ *****************************************************************************/
using System; using System;
using UnityEditor; using UnityEditor;
using UnityEngine; using UnityEngine;
@ -36,6 +35,7 @@ using UnityEngine;
public class BoneFollowerInspector : Editor { public class BoneFollowerInspector : Editor {
private SerializedProperty boneName, skeletonRenderer, followZPosition, followBoneRotation; private SerializedProperty boneName, skeletonRenderer, followZPosition, followBoneRotation;
BoneFollower component; BoneFollower component;
void OnEnable () { void OnEnable () {
skeletonRenderer = serializedObject.FindProperty("skeletonRenderer"); skeletonRenderer = serializedObject.FindProperty("skeletonRenderer");
boneName = serializedObject.FindProperty("boneName"); boneName = serializedObject.FindProperty("boneName");
@ -45,20 +45,20 @@ public class BoneFollowerInspector : Editor {
ForceReload(); ForceReload();
} }
void FindRenderer(){ void FindRenderer () {
if(skeletonRenderer.objectReferenceValue == null){ if (skeletonRenderer.objectReferenceValue == null) {
SkeletonRenderer parentRenderer = SkeletonUtility.GetInParent<SkeletonRenderer>( component.transform ); SkeletonRenderer parentRenderer = SkeletonUtility.GetInParent<SkeletonRenderer>(component.transform);
if(parentRenderer != null){ if (parentRenderer != null) {
skeletonRenderer.objectReferenceValue = (UnityEngine.Object)parentRenderer; skeletonRenderer.objectReferenceValue = (UnityEngine.Object)parentRenderer;
} }
} }
} }
void ForceReload(){ void ForceReload () {
if(component.skeletonRenderer != null){ if (component.skeletonRenderer != null) {
if(component.skeletonRenderer.valid == false) if (component.skeletonRenderer.valid == false)
component.skeletonRenderer.Reset(); component.skeletonRenderer.Reset();
} }
} }
@ -72,10 +72,9 @@ public class BoneFollowerInspector : Editor {
if (component.valid) { if (component.valid) {
String[] bones = new String[1]; String[] bones = new String[1];
try{ try {
bones = new String[component.skeletonRenderer.skeleton.Data.Bones.Count + 1]; bones = new String[component.skeletonRenderer.skeleton.Data.Bones.Count + 1];
} } catch {
catch{
} }
@ -94,8 +93,7 @@ public class BoneFollowerInspector : Editor {
boneName.stringValue = boneIndex == 0 ? null : bones[boneIndex]; boneName.stringValue = boneIndex == 0 ? null : bones[boneIndex];
EditorGUILayout.PropertyField(followBoneRotation); EditorGUILayout.PropertyField(followBoneRotation);
EditorGUILayout.PropertyField(followZPosition); EditorGUILayout.PropertyField(followZPosition);
} } else {
else{
GUILayout.Label("INVALID"); GUILayout.Label("INVALID");
} }

View File

@ -27,7 +27,6 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/ *****************************************************************************/
using System; using System;
using System.IO; using System.IO;
using UnityEditor; using UnityEditor;
@ -50,7 +49,8 @@ public class Menus {
var selected = Selection.activeObject; var selected = Selection.activeObject;
if (selected != null) { if (selected != null) {
var assetDir = AssetDatabase.GetAssetPath(selected.GetInstanceID()); var assetDir = AssetDatabase.GetAssetPath(selected.GetInstanceID());
if (assetDir.Length > 0 && Directory.Exists(assetDir)) dir = assetDir + "/"; if (assetDir.Length > 0 && Directory.Exists(assetDir))
dir = assetDir + "/";
} }
ScriptableObject asset = ScriptableObject.CreateInstance<T>(); ScriptableObject asset = ScriptableObject.CreateInstance<T>();
AssetDatabase.CreateAsset(asset, dir + name + ".asset"); AssetDatabase.CreateAsset(asset, dir + name + ".asset");

View File

@ -27,7 +27,6 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/ *****************************************************************************/
using System; using System;
using UnityEditor; using UnityEditor;
using UnityEngine; using UnityEngine;
@ -44,7 +43,7 @@ public class SkeletonAnimationInspector : SkeletonRendererInspector {
loop = serializedObject.FindProperty("loop"); loop = serializedObject.FindProperty("loop");
timeScale = serializedObject.FindProperty("timeScale"); timeScale = serializedObject.FindProperty("timeScale");
if(PrefabUtility.GetPrefabType(this.target) == PrefabType.Prefab) if (PrefabUtility.GetPrefabType(this.target) == PrefabType.Prefab)
isPrefab = true; isPrefab = true;
@ -54,13 +53,14 @@ public class SkeletonAnimationInspector : SkeletonRendererInspector {
base.gui(); base.gui();
SkeletonAnimation component = (SkeletonAnimation)target; SkeletonAnimation component = (SkeletonAnimation)target;
if (!component.valid) return; if (!component.valid)
return;
//catch case where SetAnimation was used to set track 0 without using AnimationName //catch case where SetAnimation was used to set track 0 without using AnimationName
if(Application.isPlaying){ if (Application.isPlaying) {
TrackEntry currentState = component.state.GetCurrent(0); TrackEntry currentState = component.state.GetCurrent(0);
if(currentState != null){ if (currentState != null) {
if(component.AnimationName != animationName.stringValue){ if (component.AnimationName != animationName.stringValue) {
animationName.stringValue = currentState.Animation.Name; animationName.stringValue = currentState.Animation.Name;
} }
} }
@ -86,7 +86,7 @@ public class SkeletonAnimationInspector : SkeletonRendererInspector {
EditorGUILayout.EndHorizontal(); EditorGUILayout.EndHorizontal();
String selectedAnimationName = animationIndex == 0 ? null : animations[animationIndex]; String selectedAnimationName = animationIndex == 0 ? null : animations[animationIndex];
if(component.AnimationName != selectedAnimationName){ if (component.AnimationName != selectedAnimationName) {
component.AnimationName = selectedAnimationName; component.AnimationName = selectedAnimationName;
animationName.stringValue = selectedAnimationName; animationName.stringValue = selectedAnimationName;
} }
@ -100,9 +100,9 @@ public class SkeletonAnimationInspector : SkeletonRendererInspector {
EditorGUILayout.Space(); EditorGUILayout.Space();
if(!isPrefab){ if (!isPrefab) {
if(component.GetComponent<SkeletonUtility>() == null){ if (component.GetComponent<SkeletonUtility>() == null) {
if(GUILayout.Button(new GUIContent("Add Skeleton Utility", SpineEditorUtilities.Icons.skeletonUtility), GUILayout.Height(30))){ if (GUILayout.Button(new GUIContent("Add Skeleton Utility", SpineEditorUtilities.Icons.skeletonUtility), GUILayout.Height(30))) {
component.gameObject.AddComponent<SkeletonUtility>(); component.gameObject.AddComponent<SkeletonUtility>();
} }
} }

View File

@ -32,10 +32,10 @@
* Automatic import and advanced preview added by Mitch Thompson * Automatic import and advanced preview added by Mitch Thompson
* Full irrevocable rights and permissions granted to Esoteric Software * Full irrevocable rights and permissions granted to Esoteric Software
*****************************************************************************/ *****************************************************************************/
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEditor; using UnityEditor;
#if !UNITY_4_3 #if !UNITY_4_3
using UnityEditor.AnimatedValues; using UnityEditor.AnimatedValues;
#endif #endif
@ -58,7 +58,7 @@ public class SkeletonDataAssetInspector : Editor {
private string m_skeletonDataAssetGUID; private string m_skeletonDataAssetGUID;
void OnEnable () { void OnEnable () {
try{ try {
atlasAsset = serializedObject.FindProperty("atlasAsset"); atlasAsset = serializedObject.FindProperty("atlasAsset");
skeletonJSON = serializedObject.FindProperty("skeletonJSON"); skeletonJSON = serializedObject.FindProperty("skeletonJSON");
@ -69,23 +69,21 @@ public class SkeletonDataAssetInspector : Editor {
defaultMix = serializedObject.FindProperty("defaultMix"); defaultMix = serializedObject.FindProperty("defaultMix");
m_skeletonDataAsset = (SkeletonDataAsset)target; m_skeletonDataAsset = (SkeletonDataAsset)target;
m_skeletonDataAssetGUID = AssetDatabase.AssetPathToGUID( AssetDatabase.GetAssetPath(m_skeletonDataAsset) ); m_skeletonDataAssetGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(m_skeletonDataAsset));
EditorApplication.update += Update; EditorApplication.update += Update;
} } catch {
catch{
} }
} }
void OnDestroy(){ void OnDestroy () {
m_initialized = false; m_initialized = false;
EditorApplication.update -= Update; EditorApplication.update -= Update;
this.DestroyPreviewInstances(); this.DestroyPreviewInstances();
if (this.m_previewUtility != null) if (this.m_previewUtility != null) {
{
this.m_previewUtility.Cleanup(); this.m_previewUtility.Cleanup();
this.m_previewUtility = null; this.m_previewUtility = null;
} }
@ -99,8 +97,8 @@ public class SkeletonDataAssetInspector : Editor {
EditorGUILayout.PropertyField(atlasAsset); EditorGUILayout.PropertyField(atlasAsset);
EditorGUILayout.PropertyField(skeletonJSON); EditorGUILayout.PropertyField(skeletonJSON);
EditorGUILayout.PropertyField(scale); EditorGUILayout.PropertyField(scale);
if(EditorGUI.EndChangeCheck()){ if (EditorGUI.EndChangeCheck()) {
if(m_previewUtility != null){ if (m_previewUtility != null) {
m_previewUtility.Cleanup(); m_previewUtility.Cleanup();
m_previewUtility = null; m_previewUtility = null;
} }
@ -143,7 +141,7 @@ public class SkeletonDataAssetInspector : Editor {
EditorGUILayout.EndHorizontal(); EditorGUILayout.EndHorizontal();
} }
if(GUILayout.Button(new GUIContent("Setup Pose", SpineEditorUtilities.Icons.skeleton), GUILayout.Width(105), GUILayout.Height(18))){ if (GUILayout.Button(new GUIContent("Setup Pose", SpineEditorUtilities.Icons.skeleton), GUILayout.Width(105), GUILayout.Height(18))) {
StopAnimation(); StopAnimation();
m_skeletonAnimation.skeleton.SetToSetupPose(); m_skeletonAnimation.skeleton.SetToSetupPose();
m_requireRefresh = true; m_requireRefresh = true;
@ -154,31 +152,29 @@ public class SkeletonDataAssetInspector : Editor {
if(m_showAnimationList){ if(m_showAnimationList){
#else #else
m_showAnimationList.target = EditorGUILayout.Foldout(m_showAnimationList.target, new GUIContent("Animations", SpineEditorUtilities.Icons.animationRoot)); m_showAnimationList.target = EditorGUILayout.Foldout(m_showAnimationList.target, new GUIContent("Animations", SpineEditorUtilities.Icons.animationRoot));
if(EditorGUILayout.BeginFadeGroup(m_showAnimationList.faded)){ if (EditorGUILayout.BeginFadeGroup(m_showAnimationList.faded)) {
#endif #endif
EditorGUILayout.LabelField("Name", "Duration"); EditorGUILayout.LabelField("Name", "Duration");
foreach(Spine.Animation a in skeletonData.Animations){ foreach (Spine.Animation a in skeletonData.Animations) {
GUILayout.BeginHorizontal(); GUILayout.BeginHorizontal();
if(m_skeletonAnimation != null && m_skeletonAnimation.state != null){ if (m_skeletonAnimation != null && m_skeletonAnimation.state != null) {
if(m_skeletonAnimation.state.GetCurrent(0) != null && m_skeletonAnimation.state.GetCurrent(0).Animation == a){ if (m_skeletonAnimation.state.GetCurrent(0) != null && m_skeletonAnimation.state.GetCurrent(0).Animation == a) {
GUI.contentColor = Color.black; GUI.contentColor = Color.black;
if(GUILayout.Button("\u25BA", GUILayout.Width(24))){ if (GUILayout.Button("\u25BA", GUILayout.Width(24))) {
StopAnimation(); StopAnimation();
} }
GUI.contentColor = Color.white; GUI.contentColor = Color.white;
} } else {
else{ if (GUILayout.Button("\u25BA", GUILayout.Width(24))) {
if(GUILayout.Button("\u25BA", GUILayout.Width(24))){
PlayAnimation(a.Name, true); PlayAnimation(a.Name, true);
} }
} }
} } else {
else{
GUILayout.Label("?", GUILayout.Width(24)); GUILayout.Label("?", GUILayout.Width(24));
} }
EditorGUILayout.LabelField(new GUIContent(a.Name, SpineEditorUtilities.Icons.animation), new GUIContent(a.Duration.ToString("f3") + "s" + ("(" + (Mathf.RoundToInt(a.Duration * 30)) + ")").PadLeft(12, ' '))); EditorGUILayout.LabelField(new GUIContent(a.Name, SpineEditorUtilities.Icons.animation), new GUIContent(a.Duration.ToString("f3") + "s" + ("(" + (Mathf.RoundToInt(a.Duration * 30)) + ")").PadLeft(12, ' ')));
@ -205,34 +201,32 @@ public class SkeletonDataAssetInspector : Editor {
private Vector2 previewDir; private Vector2 previewDir;
private SkeletonAnimation m_skeletonAnimation; private SkeletonAnimation m_skeletonAnimation;
private SkeletonData m_skeletonData; private SkeletonData m_skeletonData;
private static int sliderHash = "Slider".GetHashCode(); private static int sliderHash = "Slider".GetHashCode();
private float m_lastTime; private float m_lastTime;
private bool m_playing; private bool m_playing;
private bool m_requireRefresh; private bool m_requireRefresh;
private Color m_originColor = new Color(0.3f, 0.3f, 0.3f, 1);
private Color m_originColor = new Color(0.3f,0.3f,0.3f, 1); private void StopAnimation () {
private void StopAnimation(){
m_skeletonAnimation.state.ClearTrack(0); m_skeletonAnimation.state.ClearTrack(0);
m_playing = false; m_playing = false;
} }
List<Spine.Event> m_animEvents = new List<Spine.Event>(); List<Spine.Event> m_animEvents = new List<Spine.Event>();
List<float> m_animEventFrames = new List<float>(); List<float> m_animEventFrames = new List<float>();
private void PlayAnimation(string animName, bool loop){
private void PlayAnimation (string animName, bool loop) {
m_animEvents.Clear(); m_animEvents.Clear();
m_animEventFrames.Clear(); m_animEventFrames.Clear();
m_skeletonAnimation.state.SetAnimation(0, animName, loop); m_skeletonAnimation.state.SetAnimation(0, animName, loop);
Spine.Animation a = m_skeletonAnimation.state.GetCurrent(0).Animation; Spine.Animation a = m_skeletonAnimation.state.GetCurrent(0).Animation;
foreach(Timeline t in a.Timelines){ foreach (Timeline t in a.Timelines) {
if(t.GetType() == typeof(EventTimeline)){ if (t.GetType() == typeof(EventTimeline)) {
EventTimeline et = (EventTimeline)t; EventTimeline et = (EventTimeline)t;
for(int i = 0; i < et.Events.Length; i++){ for (int i = 0; i < et.Events.Length; i++) {
m_animEvents.Add(et.Events[i]); m_animEvents.Add(et.Events[i]);
m_animEventFrames.Add(et.Frames[i]); m_animEventFrames.Add(et.Frames[i]);
} }
@ -243,10 +237,8 @@ public class SkeletonDataAssetInspector : Editor {
m_playing = true; m_playing = true;
} }
private void InitPreview() private void InitPreview () {
{ if (this.m_previewUtility == null) {
if (this.m_previewUtility == null)
{
this.m_lastTime = Time.realtimeSinceStartup; this.m_lastTime = Time.realtimeSinceStartup;
this.m_previewUtility = new PreviewRenderUtility(true); this.m_previewUtility = new PreviewRenderUtility(true);
this.m_previewUtility.m_Camera.isOrthoGraphic = true; this.m_previewUtility.m_Camera.isOrthoGraphic = true;
@ -256,14 +248,12 @@ public class SkeletonDataAssetInspector : Editor {
} }
} }
private void CreatePreviewInstances() private void CreatePreviewInstances () {
{
this.DestroyPreviewInstances(); this.DestroyPreviewInstances();
if (this.m_previewInstance == null) if (this.m_previewInstance == null) {
{
string skinName = EditorPrefs.GetString(m_skeletonDataAssetGUID + "_lastSkin", ""); string skinName = EditorPrefs.GetString(m_skeletonDataAssetGUID + "_lastSkin", "");
m_previewInstance = SpineEditorUtilities.SpawnAnimatedSkeleton( (SkeletonDataAsset)target, skinName ).gameObject; m_previewInstance = SpineEditorUtilities.SpawnAnimatedSkeleton((SkeletonDataAsset)target, skinName).gameObject;
m_previewInstance.hideFlags = HideFlags.HideAndDontSave; m_previewInstance.hideFlags = HideFlags.HideAndDontSave;
m_previewInstance.layer = 0x1f; m_previewInstance.layer = 0x1f;
@ -281,36 +271,32 @@ public class SkeletonDataAssetInspector : Editor {
} }
} }
private void DestroyPreviewInstances() private void DestroyPreviewInstances () {
{ if (this.m_previewInstance != null) {
if (this.m_previewInstance != null)
{
DestroyImmediate(this.m_previewInstance); DestroyImmediate(this.m_previewInstance);
m_previewInstance = null; m_previewInstance = null;
} }
m_initialized = false; m_initialized = false;
} }
public override bool HasPreviewGUI () public override bool HasPreviewGUI () {
{
//TODO: validate json data //TODO: validate json data
return skeletonJSON.objectReferenceValue != null; return skeletonJSON.objectReferenceValue != null;
} }
Texture m_previewTex = new Texture(); Texture m_previewTex = new Texture();
public override void OnInteractivePreviewGUI(Rect r, GUIStyle background)
{ public override void OnInteractivePreviewGUI (Rect r, GUIStyle background) {
this.InitPreview(); this.InitPreview();
if (UnityEngine.Event.current.type == EventType.Repaint) if (UnityEngine.Event.current.type == EventType.Repaint) {
{ if (m_requireRefresh) {
if(m_requireRefresh){
this.m_previewUtility.BeginPreview(r, background); this.m_previewUtility.BeginPreview(r, background);
this.DoRenderPreview(true); this.DoRenderPreview(true);
this.m_previewTex = this.m_previewUtility.EndPreview(); this.m_previewTex = this.m_previewUtility.EndPreview();
m_requireRefresh = false; m_requireRefresh = false;
} }
if(this.m_previewTex != null) if (this.m_previewTex != null)
GUI.DrawTexture(r, m_previewTex, ScaleMode.StretchToFill, false); GUI.DrawTexture(r, m_previewTex, ScaleMode.StretchToFill, false);
} }
@ -322,11 +308,12 @@ public class SkeletonDataAssetInspector : Editor {
} }
float m_orthoGoal = 1; float m_orthoGoal = 1;
Vector3 m_posGoal = new Vector3(0,0,-10); Vector3 m_posGoal = new Vector3(0, 0, -10);
double m_adjustFrameEndTime = 0; double m_adjustFrameEndTime = 0;
private void AdjustCameraGoals(bool calculateMixTime){
if(calculateMixTime){ private void AdjustCameraGoals (bool calculateMixTime) {
if(m_skeletonAnimation.state.GetCurrent(0) != null){ if (calculateMixTime) {
if (m_skeletonAnimation.state.GetCurrent(0) != null) {
m_adjustFrameEndTime = EditorApplication.timeSinceStartup + m_skeletonAnimation.state.GetCurrent(0).Mix; m_adjustFrameEndTime = EditorApplication.timeSinceStartup + m_skeletonAnimation.state.GetCurrent(0).Mix;
} }
} }
@ -336,19 +323,19 @@ public class SkeletonDataAssetInspector : Editor {
Bounds bounds = go.renderer.bounds; Bounds bounds = go.renderer.bounds;
m_orthoGoal = bounds.size.y; m_orthoGoal = bounds.size.y;
m_posGoal = bounds.center + new Vector3(0,0,-10); m_posGoal = bounds.center + new Vector3(0, 0, -10);
} }
private void AdjustCameraGoals(){ private void AdjustCameraGoals () {
AdjustCameraGoals(false); AdjustCameraGoals(false);
} }
private void AdjustCamera(){ private void AdjustCamera () {
if(m_previewUtility == null) if (m_previewUtility == null)
return; return;
if(EditorApplication.timeSinceStartup < m_adjustFrameEndTime){ if (EditorApplication.timeSinceStartup < m_adjustFrameEndTime) {
AdjustCameraGoals(); AdjustCameraGoals();
} }
@ -357,7 +344,7 @@ public class SkeletonDataAssetInspector : Editor {
this.m_previewUtility.m_Camera.orthographicSize = orthoSet; this.m_previewUtility.m_Camera.orthographicSize = orthoSet;
float dist = Vector3.Distance(m_previewUtility.m_Camera.transform.position, m_posGoal); float dist = Vector3.Distance(m_previewUtility.m_Camera.transform.position, m_posGoal);
if(dist > 60f * ((SkeletonDataAsset)target).scale){ if (dist > 60f * ((SkeletonDataAsset)target).scale) {
Vector3 pos = Vector3.Lerp(this.m_previewUtility.m_Camera.transform.position, m_posGoal, 0.1f); Vector3 pos = Vector3.Lerp(this.m_previewUtility.m_Camera.transform.position, m_posGoal, 0.1f);
pos.x = 0; pos.x = 0;
this.m_previewUtility.m_Camera.transform.position = pos; this.m_previewUtility.m_Camera.transform.position = pos;
@ -366,31 +353,29 @@ public class SkeletonDataAssetInspector : Editor {
} }
} }
private void DoRenderPreview(bool drawHandles) private void DoRenderPreview (bool drawHandles) {
{
GameObject go = this.m_previewInstance; GameObject go = this.m_previewInstance;
if(m_requireRefresh){ if (m_requireRefresh) {
go.renderer.enabled = true; go.renderer.enabled = true;
if(EditorApplication.isPlaying){ if (EditorApplication.isPlaying) {
//do nothing //do nothing
} } else {
else{
m_skeletonAnimation.Update((Time.realtimeSinceStartup - m_lastTime)); m_skeletonAnimation.Update((Time.realtimeSinceStartup - m_lastTime));
} }
m_lastTime = Time.realtimeSinceStartup; m_lastTime = Time.realtimeSinceStartup;
if(!EditorApplication.isPlaying) if (!EditorApplication.isPlaying)
m_skeletonAnimation.LateUpdate(); m_skeletonAnimation.LateUpdate();
if(drawHandles){ if (drawHandles) {
Handles.SetCamera(m_previewUtility.m_Camera); Handles.SetCamera(m_previewUtility.m_Camera);
Handles.color = m_originColor; Handles.color = m_originColor;
Handles.DrawLine(new Vector3(-1000 * m_skeletonDataAsset.scale,0,0), new Vector3(1000 * m_skeletonDataAsset.scale,0,0)); Handles.DrawLine(new Vector3(-1000 * m_skeletonDataAsset.scale, 0, 0), new Vector3(1000 * m_skeletonDataAsset.scale, 0, 0));
Handles.DrawLine(new Vector3(0,1000 * m_skeletonDataAsset.scale,0), new Vector3(0,-1000 * m_skeletonDataAsset.scale,0)); Handles.DrawLine(new Vector3(0, 1000 * m_skeletonDataAsset.scale, 0), new Vector3(0, -1000 * m_skeletonDataAsset.scale, 0));
} }
this.m_previewUtility.m_Camera.Render(); this.m_previewUtility.m_Camera.Render();
@ -400,29 +385,27 @@ public class SkeletonDataAssetInspector : Editor {
} }
void Update(){ void Update () {
AdjustCamera(); AdjustCamera();
if (m_playing) { if (m_playing) {
m_requireRefresh = true; m_requireRefresh = true;
Repaint(); Repaint();
} } else if (m_requireRefresh) {
else if (m_requireRefresh) { Repaint();
Repaint (); } else {
}
else{
#if !UNITY_4_3 #if !UNITY_4_3
if(m_showAnimationList.isAnimating) if (m_showAnimationList.isAnimating)
Repaint(); Repaint();
#endif #endif
} }
} }
void DrawSkinToolbar(Rect r){ void DrawSkinToolbar (Rect r) {
if(m_skeletonAnimation == null) if (m_skeletonAnimation == null)
return; return;
if(m_skeletonAnimation.skeleton != null){ if (m_skeletonAnimation.skeleton != null) {
string label = (m_skeletonAnimation.skeleton != null && m_skeletonAnimation.skeleton.Skin != null) ? m_skeletonAnimation.skeleton.Skin.Name : "default"; string label = (m_skeletonAnimation.skeleton != null && m_skeletonAnimation.skeleton.Skin != null) ? m_skeletonAnimation.skeleton.Skin.Name : "default";
Rect popRect = new Rect(r); Rect popRect = new Rect(r);
@ -436,23 +419,23 @@ public class SkeletonDataAssetInspector : Editor {
popRect.width = 150; popRect.width = 150;
popRect.x += 44; popRect.x += 44;
if(GUI.Button( popRect, label, EditorStyles.popup)){ if (GUI.Button(popRect, label, EditorStyles.popup)) {
SelectSkinContext(); SelectSkinContext();
} }
} }
} }
void SelectSkinContext(){ void SelectSkinContext () {
GenericMenu menu = new GenericMenu(); GenericMenu menu = new GenericMenu();
foreach(Skin s in m_skeletonData.Skins){ foreach (Skin s in m_skeletonData.Skins) {
menu.AddItem( new GUIContent(s.Name), this.m_skeletonAnimation.skeleton.Skin == s, SetSkin, (object)s); menu.AddItem(new GUIContent(s.Name), this.m_skeletonAnimation.skeleton.Skin == s, SetSkin, (object)s);
} }
menu.ShowAsContext(); menu.ShowAsContext();
} }
void SetSkin(object o){ void SetSkin (object o) {
Skin skin = (Skin)o; Skin skin = (Skin)o;
m_skeletonAnimation.initialSkinName = skin.Name; m_skeletonAnimation.initialSkinName = skin.Name;
@ -462,11 +445,11 @@ public class SkeletonDataAssetInspector : Editor {
EditorPrefs.SetString(m_skeletonDataAssetGUID + "_lastSkin", skin.Name); EditorPrefs.SetString(m_skeletonDataAssetGUID + "_lastSkin", skin.Name);
} }
void NormalizedTimeBar(Rect r){ void NormalizedTimeBar (Rect r) {
Rect barRect = new Rect(r); Rect barRect = new Rect(r);
barRect.height = 32; barRect.height = 32;
barRect.x += 4; barRect.x += 4;
barRect.width -=4; barRect.width -= 4;
GUI.Box(barRect, ""); GUI.Box(barRect, "");
@ -474,7 +457,7 @@ public class SkeletonDataAssetInspector : Editor {
float width = lineRect.width; float width = lineRect.width;
TrackEntry t = m_skeletonAnimation.state.GetCurrent(0); TrackEntry t = m_skeletonAnimation.state.GetCurrent(0);
if(t != null){ if (t != null) {
int loopCount = (int)(t.Time / t.EndTime); int loopCount = (int)(t.Time / t.EndTime);
float currentTime = t.Time - (t.EndTime * loopCount); float currentTime = t.Time - (t.EndTime * loopCount);
@ -487,14 +470,14 @@ public class SkeletonDataAssetInspector : Editor {
GUI.DrawTexture(lineRect, EditorGUIUtility.whiteTexture); GUI.DrawTexture(lineRect, EditorGUIUtility.whiteTexture);
GUI.color = Color.white; GUI.color = Color.white;
for(int i = 0; i < m_animEvents.Count; i++){ for (int i = 0; i < m_animEvents.Count; i++) {
//TODO: Tooltip //TODO: Tooltip
//Spine.Event spev = animEvents[i]; //Spine.Event spev = animEvents[i];
float fr = m_animEventFrames[i]; float fr = m_animEventFrames[i];
Rect evRect = new Rect(barRect); Rect evRect = new Rect(barRect);
evRect.x = Mathf.Clamp(((fr / t.Animation.Duration) * width) - (SpineEditorUtilities.Icons._event.width/2), barRect.x, float.MaxValue); evRect.x = Mathf.Clamp(((fr / t.Animation.Duration) * width) - (SpineEditorUtilities.Icons._event.width / 2), barRect.x, float.MaxValue);
evRect.width = SpineEditorUtilities.Icons._event.width; evRect.width = SpineEditorUtilities.Icons._event.width;
evRect.height = SpineEditorUtilities.Icons._event.height; evRect.height = SpineEditorUtilities.Icons._event.height;
evRect.y += SpineEditorUtilities.Icons._event.height; evRect.y += SpineEditorUtilities.Icons._event.height;
@ -518,13 +501,13 @@ public class SkeletonDataAssetInspector : Editor {
} }
} }
void MouseScroll(Rect position){ void MouseScroll (Rect position) {
UnityEngine.Event current = UnityEngine.Event.current; UnityEngine.Event current = UnityEngine.Event.current;
int controlID = GUIUtility.GetControlID(sliderHash, FocusType.Passive); int controlID = GUIUtility.GetControlID(sliderHash, FocusType.Passive);
switch(current.GetTypeForControl(controlID)){ switch (current.GetTypeForControl(controlID)) {
case EventType.ScrollWheel: case EventType.ScrollWheel:
if(position.Contains(current.mousePosition)){ if (position.Contains(current.mousePosition)) {
m_orthoGoal += current.delta.y * ((SkeletonDataAsset)target).scale * 10; m_orthoGoal += current.delta.y * ((SkeletonDataAsset)target).scale * 10;
GUIUtility.hotControl = controlID; GUIUtility.hotControl = controlID;
@ -577,18 +560,15 @@ public class SkeletonDataAssetInspector : Editor {
} }
*/ */
public override GUIContent GetPreviewTitle () public override GUIContent GetPreviewTitle () {
{ return new GUIContent("Preview");
return new GUIContent ("Preview");
} }
public override void OnPreviewSettings () public override void OnPreviewSettings () {
{ if (!m_initialized) {
if(!m_initialized){ GUILayout.HorizontalSlider(0, 0, 2, GUILayout.MaxWidth(64));
GUILayout.HorizontalSlider(0,0,2, GUILayout.MaxWidth(64)); } else {
} float speed = GUILayout.HorizontalSlider(m_skeletonAnimation.timeScale, 0, 2, GUILayout.MaxWidth(64));
else{
float speed = GUILayout.HorizontalSlider( m_skeletonAnimation.timeScale, 0, 2, GUILayout.MaxWidth(64));
//snap to nearest 0.25 //snap to nearest 0.25
float y = speed / 0.25f; float y = speed / 0.25f;
@ -601,22 +581,21 @@ public class SkeletonDataAssetInspector : Editor {
//TODO: Fix first-import error //TODO: Fix first-import error
//TODO: Update preview without thumbnail //TODO: Update preview without thumbnail
public override Texture2D RenderStaticPreview (string assetPath, UnityEngine.Object[] subAssets, int width, int height) public override Texture2D RenderStaticPreview (string assetPath, UnityEngine.Object[] subAssets, int width, int height) {
{
Texture2D tex = new Texture2D(width, height, TextureFormat.ARGB32, false); Texture2D tex = new Texture2D(width, height, TextureFormat.ARGB32, false);
this.InitPreview(); this.InitPreview();
if(this.m_previewUtility.m_Camera == null) if (this.m_previewUtility.m_Camera == null)
return null; return null;
m_requireRefresh = true; m_requireRefresh = true;
this.DoRenderPreview(false); this.DoRenderPreview(false);
AdjustCameraGoals(false); AdjustCameraGoals(false);
this.m_previewUtility.m_Camera.orthographicSize = m_orthoGoal/2; this.m_previewUtility.m_Camera.orthographicSize = m_orthoGoal / 2;
this.m_previewUtility.m_Camera.transform.position = m_posGoal; this.m_previewUtility.m_Camera.transform.position = m_posGoal;
this.m_previewUtility.BeginStaticPreview(new Rect(0,0,width,height)); this.m_previewUtility.BeginStaticPreview(new Rect(0, 0, width, height));
this.DoRenderPreview(false); this.DoRenderPreview(false);
//TODO: Figure out why this is throwing errors on first attempt //TODO: Figure out why this is throwing errors on first attempt
@ -629,4 +608,4 @@ public class SkeletonDataAssetInspector : Editor {
tex = this.m_previewUtility.EndStaticPreview(); tex = this.m_previewUtility.EndStaticPreview();
return tex; return tex;
} }
} }

View File

@ -27,7 +27,6 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/ *****************************************************************************/
using System; using System;
using UnityEditor; using UnityEditor;
using UnityEngine; using UnityEngine;
@ -64,7 +63,8 @@ public class SkeletonRendererInspector : Editor {
if (!component.valid) { if (!component.valid) {
component.Reset(); component.Reset();
component.LateUpdate(); component.LateUpdate();
if (!component.valid) return; if (!component.valid)
return;
} }
// Initial skin name. // Initial skin name.
@ -100,7 +100,8 @@ public class SkeletonRendererInspector : Editor {
if (serializedObject.ApplyModifiedProperties() || if (serializedObject.ApplyModifiedProperties() ||
(Event.current.type == EventType.ValidateCommand && Event.current.commandName == "UndoRedoPerformed") (Event.current.type == EventType.ValidateCommand && Event.current.commandName == "UndoRedoPerformed")
) { ) {
if (!Application.isPlaying) ((SkeletonRenderer)target).Reset(); if (!Application.isPlaying)
((SkeletonRenderer)target).Reset();
} }
} }
} }

View File

@ -33,7 +33,6 @@
* Spine Editor Utilities created by Mitch Thompson * Spine Editor Utilities created by Mitch Thompson
* Full irrevocable rights and permissions granted to Esoteric Software * Full irrevocable rights and permissions granted to Esoteric Software
*****************************************************************************/ *****************************************************************************/
using UnityEngine; using UnityEngine;
using UnityEditor; using UnityEditor;
using System.Collections; using System.Collections;
@ -45,7 +44,7 @@ using Spine;
[InitializeOnLoad] [InitializeOnLoad]
public class SpineEditorUtilities : AssetPostprocessor { public class SpineEditorUtilities : AssetPostprocessor {
public static class Icons{ public static class Icons {
public static Texture2D skeleton; public static Texture2D skeleton;
public static Texture2D nullBone; public static Texture2D nullBone;
public static Texture2D bone; public static Texture2D bone;
@ -68,11 +67,16 @@ public class SpineEditorUtilities : AssetPostprocessor {
public static Texture2D hingeChain; public static Texture2D hingeChain;
public static Texture2D subMeshRenderer; public static Texture2D subMeshRenderer;
public static Mesh boneMesh{ public static Mesh boneMesh {
get{ get {
if(_boneMesh == null){ if (_boneMesh == null) {
_boneMesh = new Mesh(); _boneMesh = new Mesh();
_boneMesh.vertices = new Vector3[4]{Vector3.zero, new Vector3(-0.1f,0.1f,0), Vector3.up, new Vector3(0.1f,0.1f,0)}; _boneMesh.vertices = new Vector3[4] {
Vector3.zero,
new Vector3(-0.1f, 0.1f, 0),
Vector3.up,
new Vector3(0.1f, 0.1f, 0)
};
_boneMesh.uv = new Vector2[4]; _boneMesh.uv = new Vector2[4];
_boneMesh.triangles = new int[6]{0,1,2,2,3,0}; _boneMesh.triangles = new int[6]{0,1,2,2,3,0};
_boneMesh.RecalculateBounds(); _boneMesh.RecalculateBounds();
@ -82,12 +86,12 @@ public class SpineEditorUtilities : AssetPostprocessor {
return _boneMesh; return _boneMesh;
} }
} }
internal static Mesh _boneMesh; internal static Mesh _boneMesh;
public static Material boneMaterial {
public static Material boneMaterial{ get {
get{ if (_boneMaterial == null) {
if(_boneMaterial == null){
#if UNITY_4_3 #if UNITY_4_3
_boneMaterial = new Material(Shader.Find("Particles/Alpha Blended")); _boneMaterial = new Material(Shader.Find("Particles/Alpha Blended"));
_boneMaterial.SetColor("_TintColor", new Color(0.4f, 0.4f, 0.4f, 0.25f)); _boneMaterial.SetColor("_TintColor", new Color(0.4f, 0.4f, 0.4f, 0.25f));
@ -101,48 +105,43 @@ public class SpineEditorUtilities : AssetPostprocessor {
return _boneMaterial; return _boneMaterial;
} }
} }
internal static Material _boneMaterial; internal static Material _boneMaterial;
public static void Initialize(){ public static void Initialize () {
skeleton = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-skeleton.png"); skeleton = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-skeleton.png");
nullBone = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-null.png"); nullBone = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-null.png");
bone = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-bone.png"); bone = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-bone.png");
poseBones = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-poseBones.png"); poseBones = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-poseBones.png");
boneNib = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-boneNib.png"); boneNib = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-boneNib.png");
slot = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-slot.png"); slot = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-slot.png");
skinPlaceholder = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-skinPlaceholder.png"); skinPlaceholder = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-skinPlaceholder.png");
image = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-image.png"); image = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-image.png");
boundingBox = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-boundingBox.png"); boundingBox = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-boundingBox.png");
mesh = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-mesh.png"); mesh = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-mesh.png");
skin = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-skinPlaceholder.png"); skin = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-skinPlaceholder.png");
skinsRoot = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-skinsRoot.png"); skinsRoot = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-skinsRoot.png");
animation = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-animation.png"); animation = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-animation.png");
animationRoot = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-animationRoot.png"); animationRoot = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-animationRoot.png");
spine = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-spine.png"); spine = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-spine.png");
_event = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-event.png"); _event = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-event.png");
constraintNib = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-constraintNib.png"); constraintNib = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-constraintNib.png");
warning = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-warning.png"); warning = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-warning.png");
skeletonUtility = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-skeletonUtility.png"); skeletonUtility = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-skeletonUtility.png");
hingeChain = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-hingeChain.png"); hingeChain = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-hingeChain.png");
subMeshRenderer = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-subMeshRenderer.png"); subMeshRenderer = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-subMeshRenderer.png");
} }
} }
public static string editorPath = ""; public static string editorPath = "";
public static string editorGUIPath = ""; public static string editorGUIPath = "";
static Dictionary<int, GameObject> skeletonRendererTable; static Dictionary<int, GameObject> skeletonRendererTable;
static Dictionary<int, SkeletonUtilityBone> skeletonUtilityBoneTable; static Dictionary<int, SkeletonUtilityBone> skeletonUtilityBoneTable;
public static float defaultScale = 0.01f; public static float defaultScale = 0.01f;
public static float defaultMix = 0.2f; public static float defaultMix = 0.2f;
public static string defaultShader = "Spine/Skeleton"; public static string defaultShader = "Spine/Skeleton";
static SpineEditorUtilities(){ static SpineEditorUtilities () {
DirectoryInfo rootDir = new DirectoryInfo(Application.dataPath); DirectoryInfo rootDir = new DirectoryInfo(Application.dataPath);
FileInfo[] files = rootDir.GetFiles("SpineEditorUtilities.cs", SearchOption.AllDirectories); FileInfo[] files = rootDir.GetFiles("SpineEditorUtilities.cs", SearchOption.AllDirectories);
editorPath = Path.GetDirectoryName(files[0].FullName.Replace("\\", "/").Replace(Application.dataPath, "Assets")); editorPath = Path.GetDirectoryName(files[0].FullName.Replace("\\", "/").Replace(Application.dataPath, "Assets"));
@ -159,34 +158,33 @@ public class SpineEditorUtilities : AssetPostprocessor {
HierarchyWindowChanged(); HierarchyWindowChanged();
} }
static void HierarchyWindowChanged(){ static void HierarchyWindowChanged () {
skeletonRendererTable.Clear(); skeletonRendererTable.Clear();
skeletonUtilityBoneTable.Clear(); skeletonUtilityBoneTable.Clear();
SkeletonRenderer[] arr = Object.FindObjectsOfType<SkeletonRenderer>(); SkeletonRenderer[] arr = Object.FindObjectsOfType<SkeletonRenderer>();
foreach(SkeletonRenderer r in arr) foreach (SkeletonRenderer r in arr)
skeletonRendererTable.Add( r.gameObject.GetInstanceID(), r.gameObject ); skeletonRendererTable.Add(r.gameObject.GetInstanceID(), r.gameObject);
SkeletonUtilityBone[] boneArr = Object.FindObjectsOfType<SkeletonUtilityBone>(); SkeletonUtilityBone[] boneArr = Object.FindObjectsOfType<SkeletonUtilityBone>();
foreach(SkeletonUtilityBone b in boneArr) foreach (SkeletonUtilityBone b in boneArr)
skeletonUtilityBoneTable.Add(b.gameObject.GetInstanceID(), b); skeletonUtilityBoneTable.Add(b.gameObject.GetInstanceID(), b);
} }
static void HierarchyWindowItemOnGUI(int instanceId, Rect selectionRect){ static void HierarchyWindowItemOnGUI (int instanceId, Rect selectionRect) {
if(skeletonRendererTable.ContainsKey(instanceId)){ if (skeletonRendererTable.ContainsKey(instanceId)) {
Rect r = new Rect (selectionRect); Rect r = new Rect(selectionRect);
r.x = r.width - 15; r.x = r.width - 15;
r.width = 15; r.width = 15;
GUI.Label(r, Icons.spine); GUI.Label(r, Icons.spine);
} } else if (skeletonUtilityBoneTable.ContainsKey(instanceId)) {
else if(skeletonUtilityBoneTable.ContainsKey(instanceId)){ Rect r = new Rect(selectionRect);
Rect r = new Rect (selectionRect);
r.x -= 26; r.x -= 26;
if(skeletonUtilityBoneTable[instanceId] != null){ if (skeletonUtilityBoneTable[instanceId] != null) {
if( skeletonUtilityBoneTable[instanceId].transform.childCount == 0 ) if (skeletonUtilityBoneTable[instanceId].transform.childCount == 0)
r.x += 13; r.x += 13;
r.y += 2; r.y += 2;
@ -194,10 +192,9 @@ public class SpineEditorUtilities : AssetPostprocessor {
r.width = 13; r.width = 13;
r.height = 13; r.height = 13;
if( skeletonUtilityBoneTable[instanceId].mode == SkeletonUtilityBone.Mode.Follow ){ if (skeletonUtilityBoneTable[instanceId].mode == SkeletonUtilityBone.Mode.Follow) {
GUI.DrawTexture(r, Icons.bone); GUI.DrawTexture(r, Icons.bone);
} } else {
else{
GUI.DrawTexture(r, Icons.poseBones); GUI.DrawTexture(r, Icons.poseBones);
} }
} }
@ -207,33 +204,33 @@ public class SpineEditorUtilities : AssetPostprocessor {
} }
[MenuItem("Assets/Spine/Ingest")] [MenuItem("Assets/Spine/Ingest")]
static void IngestSpineProjectFromSelection(){ static void IngestSpineProjectFromSelection () {
TextAsset spineJson = null; TextAsset spineJson = null;
TextAsset atlasText = null; TextAsset atlasText = null;
List<TextAsset> spineJsonList = new List<TextAsset>(); List<TextAsset> spineJsonList = new List<TextAsset>();
foreach(UnityEngine.Object o in Selection.objects){ foreach (UnityEngine.Object o in Selection.objects) {
if(o.GetType() != typeof(TextAsset)) if (o.GetType() != typeof(TextAsset))
continue; continue;
string fileName = Path.GetFileName(AssetDatabase.GetAssetPath(o)); string fileName = Path.GetFileName(AssetDatabase.GetAssetPath(o));
if(fileName.EndsWith(".json")) if (fileName.EndsWith(".json"))
spineJson = (TextAsset)o; spineJson = (TextAsset)o;
else if(fileName.EndsWith(".atlas.txt")) else if (fileName.EndsWith(".atlas.txt"))
atlasText = (TextAsset)o; atlasText = (TextAsset)o;
} }
if(spineJson == null){ if (spineJson == null) {
EditorUtility.DisplayDialog("Error!", "Spine JSON file not found in selection!", "OK"); EditorUtility.DisplayDialog("Error!", "Spine JSON file not found in selection!", "OK");
return; return;
} }
string primaryName = Path.GetFileNameWithoutExtension(spineJson.name); string primaryName = Path.GetFileNameWithoutExtension(spineJson.name);
string assetPath = Path.GetDirectoryName( AssetDatabase.GetAssetPath(spineJson)); string assetPath = Path.GetDirectoryName(AssetDatabase.GetAssetPath(spineJson));
if(atlasText == null){ if (atlasText == null) {
string atlasPath = assetPath + "/" + primaryName + ".atlas.txt"; string atlasPath = assetPath + "/" + primaryName + ".atlas.txt";
atlasText = (TextAsset)AssetDatabase.LoadAssetAtPath(atlasPath, typeof(TextAsset)); atlasText = (TextAsset)AssetDatabase.LoadAssetAtPath(atlasPath, typeof(TextAsset));
} }
@ -243,7 +240,7 @@ public class SpineEditorUtilities : AssetPostprocessor {
IngestSpineProject(spineJson, atlasAsset); IngestSpineProject(spineJson, atlasAsset);
} }
static void OnPostprocessAllAssets(string[] imported, string[] deleted, string[] moved, string[] movedFromAssetPaths){ static void OnPostprocessAllAssets (string[] imported, string[] deleted, string[] moved, string[] movedFromAssetPaths) {
//debug //debug
// return; // return;
@ -251,20 +248,20 @@ public class SpineEditorUtilities : AssetPostprocessor {
System.Array.Sort<string>(imported); System.Array.Sort<string>(imported);
foreach(string str in imported){ foreach (string str in imported) {
if(Path.GetExtension(str).ToLower() == ".json"){ if (Path.GetExtension(str).ToLower() == ".json") {
TextAsset spineJson = (TextAsset)AssetDatabase.LoadAssetAtPath(str, typeof(TextAsset)); TextAsset spineJson = (TextAsset)AssetDatabase.LoadAssetAtPath(str, typeof(TextAsset));
if(IsSpineJSON(spineJson)){ if (IsSpineJSON(spineJson)) {
if(sharedAtlas != null){ if (sharedAtlas != null) {
string spinePath = Path.GetDirectoryName(AssetDatabase.GetAssetPath(spineJson)); string spinePath = Path.GetDirectoryName(AssetDatabase.GetAssetPath(spineJson));
string atlasPath = Path.GetDirectoryName(AssetDatabase.GetAssetPath(sharedAtlas)); string atlasPath = Path.GetDirectoryName(AssetDatabase.GetAssetPath(sharedAtlas));
if(spinePath != atlasPath) if (spinePath != atlasPath)
sharedAtlas = null; sharedAtlas = null;
} }
SkeletonDataAsset data = AutoIngestSpineProject(spineJson, sharedAtlas); SkeletonDataAsset data = AutoIngestSpineProject(spineJson, sharedAtlas);
if(data == null) if (data == null)
continue; continue;
sharedAtlas = data.atlasAsset; sharedAtlas = data.atlasAsset;
@ -273,15 +270,14 @@ public class SpineEditorUtilities : AssetPostprocessor {
string dir = Path.GetDirectoryName(Path.GetDirectoryName(AssetDatabase.GetAssetPath(data))); string dir = Path.GetDirectoryName(Path.GetDirectoryName(AssetDatabase.GetAssetPath(data)));
string prefabPath = Path.Combine(dir, data.skeletonJSON.name + ".prefab").Replace("\\", "/"); string prefabPath = Path.Combine(dir, data.skeletonJSON.name + ".prefab").Replace("\\", "/");
if(File.Exists(prefabPath) == false){ if (File.Exists(prefabPath) == false) {
SkeletonAnimation anim = SpawnAnimatedSkeleton(data); SkeletonAnimation anim = SpawnAnimatedSkeleton(data);
PrefabUtility.CreatePrefab(prefabPath, anim.gameObject, ReplacePrefabOptions.ReplaceNameBased); PrefabUtility.CreatePrefab(prefabPath, anim.gameObject, ReplacePrefabOptions.ReplaceNameBased);
if(EditorApplication.isPlaying) if (EditorApplication.isPlaying)
GameObject.Destroy(anim.gameObject); GameObject.Destroy(anim.gameObject);
else else
GameObject.DestroyImmediate(anim.gameObject); GameObject.DestroyImmediate(anim.gameObject);
} } else {
else{
} }
@ -291,58 +287,54 @@ public class SpineEditorUtilities : AssetPostprocessor {
} }
} }
static bool IsSpineJSON(TextAsset asset){ static bool IsSpineJSON (TextAsset asset) {
object obj = Json.Deserialize( new StringReader(asset.text)); object obj = Json.Deserialize(new StringReader(asset.text));
if(obj == null){ if (obj == null) {
Debug.LogError("Is not valid JSON"); Debug.LogError("Is not valid JSON");
return false; return false;
} }
Dictionary<string, object> root = (Dictionary<string, object>)obj; Dictionary<string, object> root = (Dictionary<string, object>)obj;
if(!root.ContainsKey("skeleton")) if (!root.ContainsKey("skeleton"))
return false; return false;
Dictionary<string, object> skeletonInfo = (Dictionary<string, object>)root["skeleton"]; Dictionary<string, object> skeletonInfo = (Dictionary<string, object>)root["skeleton"];
string spineVersion = (string)skeletonInfo["spine"]; string spineVersion = (string)skeletonInfo["spine"];
//TODO: reject old versions //TODO: reject old versions
return true; return true;
} }
static SkeletonDataAsset AutoIngestSpineProject(TextAsset spineJson, Object atlasSource = null){ static SkeletonDataAsset AutoIngestSpineProject (TextAsset spineJson, Object atlasSource = null) {
TextAsset atlasText = null; TextAsset atlasText = null;
AtlasAsset atlasAsset = null; AtlasAsset atlasAsset = null;
if(atlasSource != null){ if (atlasSource != null) {
if(atlasSource.GetType() == typeof(TextAsset)){ if (atlasSource.GetType() == typeof(TextAsset)) {
atlasText = (TextAsset)atlasSource; atlasText = (TextAsset)atlasSource;
} } else if (atlasSource.GetType() == typeof(AtlasAsset)) {
else if(atlasSource.GetType() == typeof(AtlasAsset)){
atlasAsset = (AtlasAsset)atlasSource; atlasAsset = (AtlasAsset)atlasSource;
} }
} }
if(atlasText == null && atlasAsset == null){ if (atlasText == null && atlasAsset == null) {
string primaryName = Path.GetFileNameWithoutExtension(spineJson.name); string primaryName = Path.GetFileNameWithoutExtension(spineJson.name);
string assetPath = Path.GetDirectoryName( AssetDatabase.GetAssetPath(spineJson)); string assetPath = Path.GetDirectoryName(AssetDatabase.GetAssetPath(spineJson));
if(atlasText == null){ if (atlasText == null) {
string atlasPath = assetPath + "/" + primaryName + ".atlas.txt"; string atlasPath = assetPath + "/" + primaryName + ".atlas.txt";
atlasText = (TextAsset)AssetDatabase.LoadAssetAtPath(atlasPath, typeof(TextAsset)); atlasText = (TextAsset)AssetDatabase.LoadAssetAtPath(atlasPath, typeof(TextAsset));
if(atlasText == null){ if (atlasText == null) {
//can't find atlas, likely because using a shared atlas //can't find atlas, likely because using a shared atlas
bool abort = !EditorUtility.DisplayDialog("Atlas not Found", "Expecting " + spineJson.name + ".atlas\n" + "Press OK to select Atlas", "OK", "Abort"); bool abort = !EditorUtility.DisplayDialog("Atlas not Found", "Expecting " + spineJson.name + ".atlas\n" + "Press OK to select Atlas", "OK", "Abort");
if(abort){ if (abort) {
//do nothing, let it error later //do nothing, let it error later
} } else {
else{ string path = EditorUtility.OpenFilePanel("Find Atlas source...", Path.GetDirectoryName(Application.dataPath) + "/" + assetPath, "txt");
string path = EditorUtility.OpenFilePanel( "Find Atlas source...", Path.GetDirectoryName(Application.dataPath) + "/" + assetPath, "txt"); if (path != "") {
if(path != ""){
path = path.Replace("\\", "/"); path = path.Replace("\\", "/");
path = path.Replace(Application.dataPath.Replace("\\", "/"), "Assets"); path = path.Replace(Application.dataPath.Replace("\\", "/"), "Assets");
atlasText = (TextAsset)AssetDatabase.LoadAssetAtPath(path, typeof(TextAsset)); atlasText = (TextAsset)AssetDatabase.LoadAssetAtPath(path, typeof(TextAsset));
@ -353,27 +345,27 @@ public class SpineEditorUtilities : AssetPostprocessor {
} }
} }
if(atlasAsset == null) if (atlasAsset == null)
atlasAsset = IngestSpineAtlas(atlasText); atlasAsset = IngestSpineAtlas(atlasText);
return IngestSpineProject(spineJson, atlasAsset); return IngestSpineProject(spineJson, atlasAsset);
} }
static AtlasAsset IngestSpineAtlas(TextAsset atlasText){ static AtlasAsset IngestSpineAtlas (TextAsset atlasText) {
if(atlasText == null){ if (atlasText == null) {
Debug.LogWarning("Atlas source cannot be null!"); Debug.LogWarning("Atlas source cannot be null!");
return null; return null;
} }
string primaryName = Path.GetFileNameWithoutExtension(atlasText.name).Replace(".atlas", ""); string primaryName = Path.GetFileNameWithoutExtension(atlasText.name).Replace(".atlas", "");
string assetPath = Path.GetDirectoryName( AssetDatabase.GetAssetPath(atlasText)); string assetPath = Path.GetDirectoryName(AssetDatabase.GetAssetPath(atlasText));
string atlasPath = assetPath + "/" + primaryName + "_Atlas.asset"; string atlasPath = assetPath + "/" + primaryName + "_Atlas.asset";
AtlasAsset atlasAsset = (AtlasAsset)AssetDatabase.LoadAssetAtPath(atlasPath, typeof(AtlasAsset)); AtlasAsset atlasAsset = (AtlasAsset)AssetDatabase.LoadAssetAtPath(atlasPath, typeof(AtlasAsset));
if(atlasAsset == null) if (atlasAsset == null)
atlasAsset = AtlasAsset.CreateInstance<AtlasAsset>(); atlasAsset = AtlasAsset.CreateInstance<AtlasAsset>();
atlasAsset.atlasFile = atlasText; atlasAsset.atlasFile = atlasText;
@ -384,14 +376,14 @@ public class SpineEditorUtilities : AssetPostprocessor {
string[] atlasLines = atlasStr.Split('\n'); string[] atlasLines = atlasStr.Split('\n');
List<string> pageFiles = new List<string>(); List<string> pageFiles = new List<string>();
for(int i = 0; i < atlasLines.Length-1; i++){ for (int i = 0; i < atlasLines.Length-1; i++) {
if(atlasLines[i].Length == 0) if (atlasLines[i].Length == 0)
pageFiles.Add(atlasLines[i+1]); pageFiles.Add(atlasLines[i + 1]);
} }
atlasAsset.materials = new Material[pageFiles.Count]; atlasAsset.materials = new Material[pageFiles.Count];
for(int i = 0; i < pageFiles.Count; i++){ for (int i = 0; i < pageFiles.Count; i++) {
string texturePath = assetPath + "/" + pageFiles[i]; string texturePath = assetPath + "/" + pageFiles[i];
Texture2D texture = (Texture2D)AssetDatabase.LoadAssetAtPath(texturePath, typeof(Texture2D)); Texture2D texture = (Texture2D)AssetDatabase.LoadAssetAtPath(texturePath, typeof(Texture2D));
@ -407,13 +399,13 @@ public class SpineEditorUtilities : AssetPostprocessor {
string pageName = Path.GetFileNameWithoutExtension(pageFiles[i]); string pageName = Path.GetFileNameWithoutExtension(pageFiles[i]);
//because this looks silly //because this looks silly
if(pageName == primaryName && pageFiles.Count == 1) if (pageName == primaryName && pageFiles.Count == 1)
pageName = "Material"; pageName = "Material";
string materialPath = assetPath + "/" + primaryName + "_" + pageName + ".mat"; string materialPath = assetPath + "/" + primaryName + "_" + pageName + ".mat";
Material mat = (Material)AssetDatabase.LoadAssetAtPath(materialPath, typeof(Material)); Material mat = (Material)AssetDatabase.LoadAssetAtPath(materialPath, typeof(Material));
if(mat == null){ if (mat == null) {
mat = new Material(Shader.Find(defaultShader)); mat = new Material(Shader.Find(defaultShader));
AssetDatabase.CreateAsset(mat, materialPath); AssetDatabase.CreateAsset(mat, materialPath);
} }
@ -426,7 +418,7 @@ public class SpineEditorUtilities : AssetPostprocessor {
atlasAsset.materials[i] = mat; atlasAsset.materials[i] = mat;
} }
if(AssetDatabase.GetAssetPath( atlasAsset ) == "") if (AssetDatabase.GetAssetPath(atlasAsset) == "")
AssetDatabase.CreateAsset(atlasAsset, atlasPath); AssetDatabase.CreateAsset(atlasAsset, atlasPath);
else else
atlasAsset.Reset(); atlasAsset.Reset();
@ -436,17 +428,15 @@ public class SpineEditorUtilities : AssetPostprocessor {
return (AtlasAsset)AssetDatabase.LoadAssetAtPath(atlasPath, typeof(AtlasAsset)); return (AtlasAsset)AssetDatabase.LoadAssetAtPath(atlasPath, typeof(AtlasAsset));
} }
static SkeletonDataAsset IngestSpineProject (TextAsset spineJson, AtlasAsset atlasAsset = null) {
static SkeletonDataAsset IngestSpineProject(TextAsset spineJson, AtlasAsset atlasAsset = null){
string primaryName = Path.GetFileNameWithoutExtension(spineJson.name); string primaryName = Path.GetFileNameWithoutExtension(spineJson.name);
string assetPath = Path.GetDirectoryName( AssetDatabase.GetAssetPath(spineJson)); string assetPath = Path.GetDirectoryName(AssetDatabase.GetAssetPath(spineJson));
string filePath = assetPath + "/" + primaryName + "_SkeletonData.asset"; string filePath = assetPath + "/" + primaryName + "_SkeletonData.asset";
if(spineJson != null && atlasAsset != null){ if (spineJson != null && atlasAsset != null) {
SkeletonDataAsset skelDataAsset = (SkeletonDataAsset)AssetDatabase.LoadAssetAtPath(filePath, typeof(SkeletonDataAsset)); SkeletonDataAsset skelDataAsset = (SkeletonDataAsset)AssetDatabase.LoadAssetAtPath(filePath, typeof(SkeletonDataAsset));
if(skelDataAsset == null){ if (skelDataAsset == null) {
skelDataAsset = SkeletonDataAsset.CreateInstance<SkeletonDataAsset>(); skelDataAsset = SkeletonDataAsset.CreateInstance<SkeletonDataAsset>();
skelDataAsset.atlasAsset = atlasAsset; skelDataAsset.atlasAsset = atlasAsset;
skelDataAsset.skeletonJSON = spineJson; skelDataAsset.skeletonJSON = spineJson;
@ -458,27 +448,23 @@ public class SpineEditorUtilities : AssetPostprocessor {
AssetDatabase.CreateAsset(skelDataAsset, filePath); AssetDatabase.CreateAsset(skelDataAsset, filePath);
AssetDatabase.SaveAssets(); AssetDatabase.SaveAssets();
} } else {
else{
skelDataAsset.Reset(); skelDataAsset.Reset();
skelDataAsset.GetSkeletonData(true); skelDataAsset.GetSkeletonData(true);
} }
return skelDataAsset; return skelDataAsset;
} } else {
else{
EditorUtility.DisplayDialog("Error!", "Must specify both Spine JSON and Atlas TextAsset", "OK"); EditorUtility.DisplayDialog("Error!", "Must specify both Spine JSON and Atlas TextAsset", "OK");
return null; return null;
} }
} }
[MenuItem("Assets/Spine/Spawn")] [MenuItem("Assets/Spine/Spawn")]
static void SpawnAnimatedSkeleton(){ static void SpawnAnimatedSkeleton () {
Object[] arr = Selection.objects; Object[] arr = Selection.objects;
foreach (Object o in arr) {
foreach(Object o in arr){ string guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(o));
string guid = AssetDatabase.AssetPathToGUID( AssetDatabase.GetAssetPath( o ) );
string skinName = EditorPrefs.GetString(guid + "_lastSkin", ""); string skinName = EditorPrefs.GetString(guid + "_lastSkin", "");
SpawnAnimatedSkeleton((SkeletonDataAsset)o, skinName); SpawnAnimatedSkeleton((SkeletonDataAsset)o, skinName);
@ -487,34 +473,33 @@ public class SpineEditorUtilities : AssetPostprocessor {
} }
[MenuItem("Assets/Spine/Spawn", true)] [MenuItem("Assets/Spine/Spawn", true)]
static bool ValidateSpawnAnimatedSkeleton(){ static bool ValidateSpawnAnimatedSkeleton () {
Object[] arr = Selection.objects; Object[] arr = Selection.objects;
if(arr.Length == 0) if (arr.Length == 0)
return false; return false;
foreach(Object o in arr){ foreach (Object o in arr) {
if(o.GetType() != typeof(SkeletonDataAsset)) if (o.GetType() != typeof(SkeletonDataAsset))
return false; return false;
} }
return true; return true;
} }
public static SkeletonAnimation SpawnAnimatedSkeleton(SkeletonDataAsset skeletonDataAsset, string skinName){ public static SkeletonAnimation SpawnAnimatedSkeleton (SkeletonDataAsset skeletonDataAsset, string skinName) {
return SpawnAnimatedSkeleton(skeletonDataAsset, skeletonDataAsset.GetSkeletonData(true).FindSkin(skinName)); return SpawnAnimatedSkeleton(skeletonDataAsset, skeletonDataAsset.GetSkeletonData(true).FindSkin(skinName));
} }
public static SkeletonAnimation SpawnAnimatedSkeleton(SkeletonDataAsset skeletonDataAsset, Skin skin = null){ public static SkeletonAnimation SpawnAnimatedSkeleton (SkeletonDataAsset skeletonDataAsset, Skin skin = null) {
GameObject go = new GameObject(skeletonDataAsset.name.Replace("_SkeletonData", ""), typeof(MeshFilter), typeof(MeshRenderer), typeof(SkeletonAnimation)); GameObject go = new GameObject(skeletonDataAsset.name.Replace("_SkeletonData", ""), typeof(MeshFilter), typeof(MeshRenderer), typeof(SkeletonAnimation));
SkeletonAnimation anim = go.GetComponent<SkeletonAnimation>(); SkeletonAnimation anim = go.GetComponent<SkeletonAnimation>();
anim.skeletonDataAsset = skeletonDataAsset; anim.skeletonDataAsset = skeletonDataAsset;
bool requiresNormals = false; bool requiresNormals = false;
foreach(Material m in anim.skeletonDataAsset.atlasAsset.materials){ foreach (Material m in anim.skeletonDataAsset.atlasAsset.materials) {
if(m.shader.name.Contains("Lit")){ if (m.shader.name.Contains("Lit")) {
requiresNormals = true; requiresNormals = true;
break; break;
} }
@ -524,16 +509,16 @@ public class SpineEditorUtilities : AssetPostprocessor {
SkeletonData data = skeletonDataAsset.GetSkeletonData(true); SkeletonData data = skeletonDataAsset.GetSkeletonData(true);
if(data == null){ if (data == null) {
string reloadAtlasPath = AssetDatabase.GetAssetPath( skeletonDataAsset.atlasAsset ); string reloadAtlasPath = AssetDatabase.GetAssetPath(skeletonDataAsset.atlasAsset);
skeletonDataAsset.atlasAsset = (AtlasAsset)AssetDatabase.LoadAssetAtPath( reloadAtlasPath, typeof(AtlasAsset)); skeletonDataAsset.atlasAsset = (AtlasAsset)AssetDatabase.LoadAssetAtPath(reloadAtlasPath, typeof(AtlasAsset));
data = skeletonDataAsset.GetSkeletonData(true); data = skeletonDataAsset.GetSkeletonData(true);
} }
if(skin == null) if (skin == null)
skin = data.DefaultSkin; skin = data.DefaultSkin;
if(skin == null) if (skin == null)
skin = data.Skins[0]; skin = data.Skins[0];
anim.Reset(); anim.Reset();
@ -548,8 +533,4 @@ public class SpineEditorUtilities : AssetPostprocessor {
return anim; return anim;
} }
} }

View File

@ -41,20 +41,23 @@ public class SkeletonAnimation : SkeletonRenderer {
public bool loop; public bool loop;
public Spine.AnimationState state; public Spine.AnimationState state;
public delegate void UpdateBonesDelegate(SkeletonAnimation skeleton); public delegate void UpdateBonesDelegate (SkeletonAnimation skeleton);
public UpdateBonesDelegate UpdateLocal; public UpdateBonesDelegate UpdateLocal;
public UpdateBonesDelegate UpdateWorld; public UpdateBonesDelegate UpdateWorld;
public UpdateBonesDelegate UpdateComplete; public UpdateBonesDelegate UpdateComplete;
[SerializeField] [SerializeField]
private String _animationName; private String
_animationName;
public String AnimationName { public String AnimationName {
get { get {
TrackEntry entry = state.GetCurrent(0); TrackEntry entry = state.GetCurrent(0);
return entry == null ? null : entry.Animation.Name; return entry == null ? null : entry.Animation.Name;
} }
set { set {
if (_animationName == value) return; if (_animationName == value)
return;
_animationName = value; _animationName = value;
if (value == null || value.Length == 0) if (value == null || value.Length == 0)
state.ClearTrack(0); state.ClearTrack(0);
@ -65,7 +68,8 @@ public class SkeletonAnimation : SkeletonRenderer {
public override void Reset () { public override void Reset () {
base.Reset(); base.Reset();
if (!valid) return; if (!valid)
return;
state = new Spine.AnimationState(skeletonDataAsset.GetAnimationStateData()); state = new Spine.AnimationState(skeletonDataAsset.GetAnimationStateData());
if (_animationName != null && _animationName.Length > 0) { if (_animationName != null && _animationName.Length > 0) {
@ -79,7 +83,8 @@ public class SkeletonAnimation : SkeletonRenderer {
} }
public virtual void Update (float deltaTime) { public virtual void Update (float deltaTime) {
if (!valid) return; if (!valid)
return;
deltaTime *= timeScale; deltaTime *= timeScale;
skeleton.Update(deltaTime); skeleton.Update(deltaTime);
@ -91,12 +96,12 @@ public class SkeletonAnimation : SkeletonRenderer {
skeleton.UpdateWorldTransform(); skeleton.UpdateWorldTransform();
if (UpdateWorld != null){ if (UpdateWorld != null) {
UpdateWorld(this); UpdateWorld(this);
skeleton.UpdateWorldTransform(); skeleton.UpdateWorldTransform();
} }
if (UpdateComplete != null){ if (UpdateComplete != null) {
UpdateComplete(this); UpdateComplete(this);
} }
} }

View File

@ -87,7 +87,8 @@ public class SkeletonDataAsset : ScriptableObject {
stateData = new AnimationStateData(skeletonData); stateData = new AnimationStateData(skeletonData);
stateData.DefaultMix = defaultMix; stateData.DefaultMix = defaultMix;
for (int i = 0, n = fromAnimation.Length; i < n; i++) { for (int i = 0, n = fromAnimation.Length; i < n; i++) {
if (fromAnimation[i].Length == 0 || toAnimation[i].Length == 0) continue; if (fromAnimation[i].Length == 0 || toAnimation[i].Length == 0)
continue;
stateData.SetMix(fromAnimation[i], toAnimation[i], duration[i]); stateData.SetMix(fromAnimation[i], toAnimation[i], duration[i]);
} }

View File

@ -39,68 +39,68 @@ using Spine;
public static class SkeletonExtensions { public static class SkeletonExtensions {
public static void SetColor(this Slot slot, Color color){ public static void SetColor (this Slot slot, Color color) {
slot.A = color.a; slot.A = color.a;
slot.R = color.r; slot.R = color.r;
slot.G = color.g; slot.G = color.g;
slot.B = color.b; slot.B = color.b;
} }
public static void SetColor(this Slot slot, Color32 color){ public static void SetColor (this Slot slot, Color32 color) {
slot.A = color.a / 255f; slot.A = color.a / 255f;
slot.R = color.r / 255f; slot.R = color.r / 255f;
slot.G = color.g / 255f; slot.G = color.g / 255f;
slot.B = color.b / 255f; slot.B = color.b / 255f;
} }
public static void SetColor(this RegionAttachment attachment, Color color){ public static void SetColor (this RegionAttachment attachment, Color color) {
attachment.A = color.a; attachment.A = color.a;
attachment.R = color.r; attachment.R = color.r;
attachment.G = color.g; attachment.G = color.g;
attachment.B = color.b; attachment.B = color.b;
} }
public static void SetColor(this RegionAttachment attachment, Color32 color){ public static void SetColor (this RegionAttachment attachment, Color32 color) {
attachment.A = color.a / 255f; attachment.A = color.a / 255f;
attachment.R = color.r / 255f; attachment.R = color.r / 255f;
attachment.G = color.g / 255f; attachment.G = color.g / 255f;
attachment.B = color.b / 255f; attachment.B = color.b / 255f;
} }
public static void SetColor(this MeshAttachment attachment, Color color){ public static void SetColor (this MeshAttachment attachment, Color color) {
attachment.A = color.a; attachment.A = color.a;
attachment.R = color.r; attachment.R = color.r;
attachment.G = color.g; attachment.G = color.g;
attachment.B = color.b; attachment.B = color.b;
} }
public static void SetColor(this MeshAttachment attachment, Color32 color){ public static void SetColor (this MeshAttachment attachment, Color32 color) {
attachment.A = color.a / 255f; attachment.A = color.a / 255f;
attachment.R = color.r / 255f; attachment.R = color.r / 255f;
attachment.G = color.g / 255f; attachment.G = color.g / 255f;
attachment.B = color.b / 255f; attachment.B = color.b / 255f;
} }
public static void SetColor(this SkinnedMeshAttachment attachment, Color color){ public static void SetColor (this SkinnedMeshAttachment attachment, Color color) {
attachment.A = color.a; attachment.A = color.a;
attachment.R = color.r; attachment.R = color.r;
attachment.G = color.g; attachment.G = color.g;
attachment.B = color.b; attachment.B = color.b;
} }
public static void SetColor(this SkinnedMeshAttachment attachment, Color32 color){ public static void SetColor (this SkinnedMeshAttachment attachment, Color32 color) {
attachment.A = color.a / 255f; attachment.A = color.a / 255f;
attachment.R = color.r / 255f; attachment.R = color.r / 255f;
attachment.G = color.g / 255f; attachment.G = color.g / 255f;
attachment.B = color.b / 255f; attachment.B = color.b / 255f;
} }
public static void SetPosition(this Bone bone, Vector2 position){ public static void SetPosition (this Bone bone, Vector2 position) {
bone.X = position.x; bone.X = position.x;
bone.Y = position.y; bone.Y = position.y;
} }
public static void SetPosition(this Bone bone, Vector3 position){ public static void SetPosition (this Bone bone, Vector3 position) {
bone.X = position.x; bone.X = position.x;
bone.Y = position.y; bone.Y = position.y;
} }

View File

@ -38,21 +38,19 @@ using Spine;
[ExecuteInEditMode, RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))] [ExecuteInEditMode, RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class SkeletonRenderer : MonoBehaviour { public class SkeletonRenderer : MonoBehaviour {
public delegate void SkeletonRendererDelegate(SkeletonRenderer skeletonRenderer); public delegate void SkeletonRendererDelegate (SkeletonRenderer skeletonRenderer);
public SkeletonRendererDelegate OnReset;
public SkeletonRendererDelegate OnReset;
[System.NonSerialized] [System.NonSerialized]
public bool valid; public bool valid;
[System.NonSerialized] [System.NonSerialized]
public Skeleton skeleton; public Skeleton skeleton;
public SkeletonDataAsset skeletonDataAsset; public SkeletonDataAsset skeletonDataAsset;
public String initialSkinName; public String initialSkinName;
public bool calculateNormals, calculateTangents; public bool calculateNormals, calculateTangents;
public float zSpacing; public float zSpacing;
public bool renderMeshes = true, immutableTriangles; public bool renderMeshes = true, immutableTriangles;
public bool logErrors = false; public bool logErrors = false;
private MeshFilter meshFilter; private MeshFilter meshFilter;
private Mesh mesh, mesh1, mesh2; private Mesh mesh, mesh1, mesh2;
private bool useMesh1; private bool useMesh1;
@ -66,9 +64,12 @@ public class SkeletonRenderer : MonoBehaviour {
private readonly List<Submesh> submeshes = new List<Submesh>(); private readonly List<Submesh> submeshes = new List<Submesh>();
public virtual void Reset () { public virtual void Reset () {
if (meshFilter != null) meshFilter.sharedMesh = null; if (meshFilter != null)
if (mesh != null) DestroyImmediate(mesh); meshFilter.sharedMesh = null;
if (renderer != null) renderer.sharedMaterial = null; if (mesh != null)
DestroyImmediate(mesh);
if (renderer != null)
renderer.sharedMaterial = null;
mesh = null; mesh = null;
mesh1 = null; mesh1 = null;
mesh2 = null; mesh2 = null;
@ -83,13 +84,14 @@ public class SkeletonRenderer : MonoBehaviour {
valid = false; valid = false;
if (!skeletonDataAsset) { if (!skeletonDataAsset) {
if(logErrors) if (logErrors)
Debug.LogError("Missing SkeletonData asset.", this); Debug.LogError("Missing SkeletonData asset.", this);
return; return;
} }
SkeletonData skeletonData = skeletonDataAsset.GetSkeletonData(false); SkeletonData skeletonData = skeletonDataAsset.GetSkeletonData(false);
if (skeletonData == null) return; if (skeletonData == null)
return;
valid = true; valid = true;
meshFilter = GetComponent<MeshFilter>(); meshFilter = GetComponent<MeshFilter>();
@ -100,7 +102,8 @@ public class SkeletonRenderer : MonoBehaviour {
skeleton = new Skeleton(skeletonData); skeleton = new Skeleton(skeletonData);
if (initialSkinName != null && initialSkinName.Length > 0 && initialSkinName != "default") if (initialSkinName != null && initialSkinName.Length > 0 && initialSkinName != "default")
skeleton.SetSkin(initialSkinName); skeleton.SetSkin(initialSkinName);
if(OnReset != null) OnReset(this); if (OnReset != null)
OnReset(this);
} }
public void Awake () { public void Awake () {
@ -116,7 +119,8 @@ public class SkeletonRenderer : MonoBehaviour {
} }
public virtual void LateUpdate () { public virtual void LateUpdate () {
if (!valid) return; if (!valid)
return;
// Count vertices and submesh triangles. // Count vertices and submesh triangles.
int vertexCount = 0; int vertexCount = 0;
int submeshTriangleCount = 0, submeshFirstVertex = 0, submeshStartSlotIndex = 0; int submeshTriangleCount = 0, submeshFirstVertex = 0, submeshStartSlotIndex = 0;
@ -137,7 +141,8 @@ public class SkeletonRenderer : MonoBehaviour {
attachmentVertexCount = 4; attachmentVertexCount = 4;
attachmentTriangleCount = 6; attachmentTriangleCount = 6;
} else { } else {
if (!renderMeshes) continue; if (!renderMeshes)
continue;
if (attachment is MeshAttachment) { if (attachment is MeshAttachment) {
MeshAttachment meshAttachment = (MeshAttachment)attachment; MeshAttachment meshAttachment = (MeshAttachment)attachment;
rendererObject = meshAttachment.RendererObject; rendererObject = meshAttachment.RendererObject;
@ -217,7 +222,8 @@ public class SkeletonRenderer : MonoBehaviour {
color.r = (byte)(r * slot.r * regionAttachment.r * color.a); color.r = (byte)(r * slot.r * regionAttachment.r * color.a);
color.g = (byte)(g * slot.g * regionAttachment.g * color.a); color.g = (byte)(g * slot.g * regionAttachment.g * color.a);
color.b = (byte)(b * slot.b * regionAttachment.b * color.a); color.b = (byte)(b * slot.b * regionAttachment.b * color.a);
if (slot.data.additiveBlending) color.a = 0; if (slot.data.additiveBlending)
color.a = 0;
colors[vertexIndex] = color; colors[vertexIndex] = color;
colors[vertexIndex + 1] = color; colors[vertexIndex + 1] = color;
colors[vertexIndex + 2] = color; colors[vertexIndex + 2] = color;
@ -231,18 +237,21 @@ public class SkeletonRenderer : MonoBehaviour {
vertexIndex += 4; vertexIndex += 4;
} else { } else {
if (!renderMeshes) continue; if (!renderMeshes)
continue;
if (attachment is MeshAttachment) { if (attachment is MeshAttachment) {
MeshAttachment meshAttachment = (MeshAttachment)attachment; MeshAttachment meshAttachment = (MeshAttachment)attachment;
int meshVertexCount = meshAttachment.vertices.Length; int meshVertexCount = meshAttachment.vertices.Length;
if (tempVertices.Length < meshVertexCount) tempVertices = new float[meshVertexCount]; if (tempVertices.Length < meshVertexCount)
tempVertices = new float[meshVertexCount];
meshAttachment.ComputeWorldVertices(slot, tempVertices); meshAttachment.ComputeWorldVertices(slot, tempVertices);
color.a = (byte)(a * slot.a * meshAttachment.a); color.a = (byte)(a * slot.a * meshAttachment.a);
color.r = (byte)(r * slot.r * meshAttachment.r * color.a); color.r = (byte)(r * slot.r * meshAttachment.r * color.a);
color.g = (byte)(g * slot.g * meshAttachment.g * color.a); color.g = (byte)(g * slot.g * meshAttachment.g * color.a);
color.b = (byte)(b * slot.b * meshAttachment.b * color.a); color.b = (byte)(b * slot.b * meshAttachment.b * color.a);
if (slot.data.additiveBlending) color.a = 0; if (slot.data.additiveBlending)
color.a = 0;
float[] meshUVs = meshAttachment.uvs; float[] meshUVs = meshAttachment.uvs;
float z = i * zSpacing; float z = i * zSpacing;
@ -254,14 +263,16 @@ public class SkeletonRenderer : MonoBehaviour {
} else if (attachment is SkinnedMeshAttachment) { } else if (attachment is SkinnedMeshAttachment) {
SkinnedMeshAttachment meshAttachment = (SkinnedMeshAttachment)attachment; SkinnedMeshAttachment meshAttachment = (SkinnedMeshAttachment)attachment;
int meshVertexCount = meshAttachment.uvs.Length; int meshVertexCount = meshAttachment.uvs.Length;
if (tempVertices.Length < meshVertexCount) tempVertices = new float[meshVertexCount]; if (tempVertices.Length < meshVertexCount)
tempVertices = new float[meshVertexCount];
meshAttachment.ComputeWorldVertices(slot, tempVertices); meshAttachment.ComputeWorldVertices(slot, tempVertices);
color.a = (byte)(a * slot.a * meshAttachment.a); color.a = (byte)(a * slot.a * meshAttachment.a);
color.r = (byte)(r * slot.r * meshAttachment.r * color.a); color.r = (byte)(r * slot.r * meshAttachment.r * color.a);
color.g = (byte)(g * slot.g * meshAttachment.g * color.a); color.g = (byte)(g * slot.g * meshAttachment.g * color.a);
color.b = (byte)(b * slot.b * meshAttachment.b * color.a); color.b = (byte)(b * slot.b * meshAttachment.b * color.a);
if (slot.data.additiveBlending) color.a = 0; if (slot.data.additiveBlending)
color.a = 0;
float[] meshUVs = meshAttachment.uvs; float[] meshUVs = meshAttachment.uvs;
float z = i * zSpacing; float z = i * zSpacing;
@ -385,7 +396,7 @@ public class SkeletonRenderer : MonoBehaviour {
} }
} }
#if UNITY_EDITOR #if UNITY_EDITOR
void OnDrawGizmos() { void OnDrawGizmos() {
// Make selection easier by drawing a clear gizmo over the skeleton. // Make selection easier by drawing a clear gizmo over the skeleton.
if (vertices == null) return; if (vertices == null) return;
@ -405,7 +416,7 @@ public class SkeletonRenderer : MonoBehaviour {
Gizmos.matrix = transform.localToWorldMatrix; Gizmos.matrix = transform.localToWorldMatrix;
Gizmos.DrawCube(gizmosCenter, gizmosSize); Gizmos.DrawCube(gizmosCenter, gizmosSize);
} }
#endif #endif
} }
class Submesh { class Submesh {

View File

@ -32,7 +32,6 @@
* Skeleton Utility created by Mitch Thompson * Skeleton Utility created by Mitch Thompson
* Full irrevocable rights and permissions granted to Esoteric Software * Full irrevocable rights and permissions granted to Esoteric Software
*****************************************************************************/ *****************************************************************************/
using UnityEngine; using UnityEngine;
using UnityEditor; using UnityEditor;
using System.Collections; using System.Collections;
@ -51,7 +50,7 @@ public class SkeletonUtilityBoneInspector : Editor {
SkeletonUtility skeletonUtility; SkeletonUtility skeletonUtility;
bool canCreateHingeChain = false; bool canCreateHingeChain = false;
void OnEnable(){ void OnEnable () {
mode = this.serializedObject.FindProperty("mode"); mode = this.serializedObject.FindProperty("mode");
boneName = this.serializedObject.FindProperty("boneName"); boneName = this.serializedObject.FindProperty("boneName");
zPosition = this.serializedObject.FindProperty("zPosition"); zPosition = this.serializedObject.FindProperty("zPosition");
@ -65,67 +64,64 @@ public class SkeletonUtilityBoneInspector : Editor {
EvaluateFlags(); EvaluateFlags();
if(utilityBone.valid == false && skeletonUtility != null && skeletonUtility.skeletonRenderer != null){ if (utilityBone.valid == false && skeletonUtility != null && skeletonUtility.skeletonRenderer != null) {
skeletonUtility.skeletonRenderer.Reset(); skeletonUtility.skeletonRenderer.Reset();
} }
canCreateHingeChain = CanCreateHingeChain(); canCreateHingeChain = CanCreateHingeChain();
} }
/// <summary> void EvaluateFlags () {
/// Evaluates the flags.
/// </summary>
void EvaluateFlags(){
utilityBone = (SkeletonUtilityBone)target; utilityBone = (SkeletonUtilityBone)target;
skeletonUtility = utilityBone.skeletonUtility; skeletonUtility = utilityBone.skeletonUtility;
if(Selection.objects.Length == 1){ if (Selection.objects.Length == 1) {
containsFollows = utilityBone.mode == SkeletonUtilityBone.Mode.Follow; containsFollows = utilityBone.mode == SkeletonUtilityBone.Mode.Follow;
containsOverrides = utilityBone.mode == SkeletonUtilityBone.Mode.Override; containsOverrides = utilityBone.mode == SkeletonUtilityBone.Mode.Override;
} } else {
else{
int boneCount = 0; int boneCount = 0;
foreach(Object o in Selection.objects){ foreach (Object o in Selection.objects) {
if(o is GameObject){ if (o is GameObject) {
GameObject go = (GameObject)o; GameObject go = (GameObject)o;
SkeletonUtilityBone sub = go.GetComponent<SkeletonUtilityBone>(); SkeletonUtilityBone sub = go.GetComponent<SkeletonUtilityBone>();
if(sub != null){ if (sub != null) {
boneCount++; boneCount++;
if(sub.mode == SkeletonUtilityBone.Mode.Follow) if (sub.mode == SkeletonUtilityBone.Mode.Follow)
containsFollows = true; containsFollows = true;
if(sub.mode == SkeletonUtilityBone.Mode.Override) if (sub.mode == SkeletonUtilityBone.Mode.Override)
containsOverrides = true; containsOverrides = true;
} }
} }
} }
if(boneCount > 1) if (boneCount > 1)
multiObject = true; multiObject = true;
} }
} }
public override void OnInspectorGUI () public override void OnInspectorGUI () {
{
serializedObject.Update(); serializedObject.Update();
EditorGUI.BeginChangeCheck(); EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(mode); EditorGUILayout.PropertyField(mode);
if(EditorGUI.EndChangeCheck()){ if (EditorGUI.EndChangeCheck()) {
containsOverrides = mode.enumValueIndex == 1; containsOverrides = mode.enumValueIndex == 1;
containsFollows = mode.enumValueIndex == 0; containsFollows = mode.enumValueIndex == 0;
} }
EditorGUI.BeginDisabledGroup( multiObject ); EditorGUI.BeginDisabledGroup(multiObject);
{ {
string str = boneName.stringValue; string str = boneName.stringValue;
if(str == "") str = "<None>"; if (str == "")
if(multiObject) str = "<Multiple>"; str = "<None>";
if (multiObject)
str = "<Multiple>";
GUILayout.BeginHorizontal(); GUILayout.BeginHorizontal();
EditorGUILayout.PrefixLabel("Bone"); EditorGUILayout.PrefixLabel("Bone");
if(GUILayout.Button( str, EditorStyles.popup )){ if (GUILayout.Button(str, EditorStyles.popup)) {
BoneSelectorContextMenu( str, ((SkeletonUtilityBone)target).skeletonUtility.skeletonRenderer.skeleton.Bones, "<None>", TargetBoneSelected ); BoneSelectorContextMenu(str, ((SkeletonUtilityBone)target).skeletonUtility.skeletonRenderer.skeleton.Bones, "<None>", TargetBoneSelected);
} }
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
@ -138,7 +134,7 @@ public class SkeletonUtilityBoneInspector : Editor {
EditorGUILayout.PropertyField(scale); EditorGUILayout.PropertyField(scale);
EditorGUILayout.PropertyField(flip); EditorGUILayout.PropertyField(flip);
EditorGUI.BeginDisabledGroup( containsFollows ); EditorGUI.BeginDisabledGroup(containsFollows);
{ {
EditorGUILayout.PropertyField(overrideAlpha); EditorGUILayout.PropertyField(overrideAlpha);
EditorGUILayout.PropertyField(parentReference); EditorGUILayout.PropertyField(parentReference);
@ -147,8 +143,7 @@ public class SkeletonUtilityBoneInspector : Editor {
{ {
EditorGUI.BeginChangeCheck(); EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(flipX); EditorGUILayout.PropertyField(flipX);
if (EditorGUI.EndChangeCheck()) if (EditorGUI.EndChangeCheck()) {
{
FlipX(flipX.boolValue); FlipX(flipX.boolValue);
} }
} }
@ -161,23 +156,23 @@ public class SkeletonUtilityBoneInspector : Editor {
GUILayout.BeginHorizontal(); GUILayout.BeginHorizontal();
{ {
EditorGUI.BeginDisabledGroup( multiObject || !utilityBone.valid || utilityBone.bone == null || utilityBone.bone.Children.Count == 0); EditorGUI.BeginDisabledGroup(multiObject || !utilityBone.valid || utilityBone.bone == null || utilityBone.bone.Children.Count == 0);
{ {
if(GUILayout.Button(new GUIContent("Add Child", SpineEditorUtilities.Icons.bone), GUILayout.Width(150), GUILayout.Height(24))) if (GUILayout.Button(new GUIContent("Add Child", SpineEditorUtilities.Icons.bone), GUILayout.Width(150), GUILayout.Height(24)))
BoneSelectorContextMenu( "", utilityBone.bone.Children, "<Recursively>", SpawnChildBoneSelected); BoneSelectorContextMenu("", utilityBone.bone.Children, "<Recursively>", SpawnChildBoneSelected);
} }
EditorGUI.EndDisabledGroup(); EditorGUI.EndDisabledGroup();
EditorGUI.BeginDisabledGroup( multiObject || !utilityBone.valid || utilityBone.bone == null || containsOverrides); EditorGUI.BeginDisabledGroup(multiObject || !utilityBone.valid || utilityBone.bone == null || containsOverrides);
{ {
if(GUILayout.Button(new GUIContent("Add Override", SpineEditorUtilities.Icons.poseBones), GUILayout.Width(150), GUILayout.Height(24))) if (GUILayout.Button(new GUIContent("Add Override", SpineEditorUtilities.Icons.poseBones), GUILayout.Width(150), GUILayout.Height(24)))
SpawnOverride(); SpawnOverride();
} }
EditorGUI.EndDisabledGroup(); EditorGUI.EndDisabledGroup();
EditorGUI.BeginDisabledGroup( multiObject || !utilityBone.valid || !canCreateHingeChain ); EditorGUI.BeginDisabledGroup(multiObject || !utilityBone.valid || !canCreateHingeChain);
{ {
if(GUILayout.Button(new GUIContent("Create Hinge Chain", SpineEditorUtilities.Icons.hingeChain), GUILayout.Width(150), GUILayout.Height(24))) if (GUILayout.Button(new GUIContent("Create Hinge Chain", SpineEditorUtilities.Icons.hingeChain), GUILayout.Width(150), GUILayout.Height(24)))
CreateHingeChain(); CreateHingeChain();
} }
EditorGUI.EndDisabledGroup(); EditorGUI.EndDisabledGroup();
@ -188,36 +183,32 @@ public class SkeletonUtilityBoneInspector : Editor {
serializedObject.ApplyModifiedProperties(); serializedObject.ApplyModifiedProperties();
} }
void FlipX(bool state) void FlipX (bool state) {
{
utilityBone.FlipX(state); utilityBone.FlipX(state);
if (Application.isPlaying == false) if (Application.isPlaying == false) {
{
skeletonUtility.skeletonAnimation.LateUpdate(); skeletonUtility.skeletonAnimation.LateUpdate();
} }
} }
void BoneSelectorContextMenu(string current, List<Bone> bones, string topValue, GenericMenu.MenuFunction2 callback){ void BoneSelectorContextMenu (string current, List<Bone> bones, string topValue, GenericMenu.MenuFunction2 callback) {
GenericMenu menu = new GenericMenu(); GenericMenu menu = new GenericMenu();
if(topValue != "") if (topValue != "")
menu.AddItem( new GUIContent(topValue), current == topValue, callback, null ); menu.AddItem(new GUIContent(topValue), current == topValue, callback, null);
for(int i = 0; i < bones.Count; i++){ for (int i = 0; i < bones.Count; i++) {
menu.AddItem( new GUIContent(bones[i].Data.Name), bones[i].Data.Name == current, callback, bones[i] ); menu.AddItem(new GUIContent(bones[i].Data.Name), bones[i].Data.Name == current, callback, bones[i]);
} }
menu.ShowAsContext(); menu.ShowAsContext();
} }
void TargetBoneSelected (object obj) {
void TargetBoneSelected(object obj){ if (obj == null) {
if(obj == null){
boneName.stringValue = ""; boneName.stringValue = "";
serializedObject.ApplyModifiedProperties(); serializedObject.ApplyModifiedProperties();
} } else {
else{
Bone bone = (Bone)obj; Bone bone = (Bone)obj;
boneName.stringValue = bone.Data.Name; boneName.stringValue = bone.Data.Name;
serializedObject.ApplyModifiedProperties(); serializedObject.ApplyModifiedProperties();
@ -226,56 +217,59 @@ public class SkeletonUtilityBoneInspector : Editor {
} }
} }
void SpawnChildBoneSelected(object obj){ void SpawnChildBoneSelected (object obj) {
if(obj == null){ if (obj == null) {
//add recursively //add recursively
foreach(var bone in utilityBone.bone.Children){ foreach (var bone in utilityBone.bone.Children) {
GameObject go = skeletonUtility.SpawnBoneRecursively( bone, utilityBone.transform, utilityBone.mode, utilityBone.position, utilityBone.rotation, utilityBone.scale ); GameObject go = skeletonUtility.SpawnBoneRecursively(bone, utilityBone.transform, utilityBone.mode, utilityBone.position, utilityBone.rotation, utilityBone.scale);
SkeletonUtilityBone[] newUtilityBones = go.GetComponentsInChildren<SkeletonUtilityBone>(); SkeletonUtilityBone[] newUtilityBones = go.GetComponentsInChildren<SkeletonUtilityBone>();
foreach(SkeletonUtilityBone utilBone in newUtilityBones) foreach (SkeletonUtilityBone utilBone in newUtilityBones)
SkeletonUtilityInspector.AttachIcon(utilBone); SkeletonUtilityInspector.AttachIcon(utilBone);
} }
} } else {
else{
Bone bone = (Bone)obj; Bone bone = (Bone)obj;
GameObject go = skeletonUtility.SpawnBone( bone, utilityBone.transform, utilityBone.mode, utilityBone.position, utilityBone.rotation, utilityBone.scale ); GameObject go = skeletonUtility.SpawnBone(bone, utilityBone.transform, utilityBone.mode, utilityBone.position, utilityBone.rotation, utilityBone.scale);
SkeletonUtilityInspector.AttachIcon(go.GetComponent<SkeletonUtilityBone>()); SkeletonUtilityInspector.AttachIcon(go.GetComponent<SkeletonUtilityBone>());
Selection.activeGameObject = go; Selection.activeGameObject = go;
EditorGUIUtility.PingObject(go); EditorGUIUtility.PingObject(go);
} }
} }
void SpawnOverride(){ void SpawnOverride () {
GameObject go = skeletonUtility.SpawnBone( utilityBone.bone, utilityBone.transform.parent, SkeletonUtilityBone.Mode.Override, utilityBone.position, utilityBone.rotation, utilityBone.scale); GameObject go = skeletonUtility.SpawnBone(utilityBone.bone, utilityBone.transform.parent, SkeletonUtilityBone.Mode.Override, utilityBone.position, utilityBone.rotation, utilityBone.scale);
go.name = go.name + " [Override]"; go.name = go.name + " [Override]";
SkeletonUtilityInspector.AttachIcon(go.GetComponent<SkeletonUtilityBone>()); SkeletonUtilityInspector.AttachIcon(go.GetComponent<SkeletonUtilityBone>());
Selection.activeGameObject = go; Selection.activeGameObject = go;
EditorGUIUtility.PingObject(go); EditorGUIUtility.PingObject(go);
} }
bool CanCreateHingeChain(){ bool CanCreateHingeChain () {
if(utilityBone == null) return false; if (utilityBone == null)
if(utilityBone.rigidbody != null) return false; return false;
if(utilityBone.bone != null && utilityBone.bone.Children.Count == 0) return false; if (utilityBone.rigidbody != null)
return false;
if (utilityBone.bone != null && utilityBone.bone.Children.Count == 0)
return false;
Rigidbody[] rigidbodies = utilityBone.GetComponentsInChildren<Rigidbody>(); Rigidbody[] rigidbodies = utilityBone.GetComponentsInChildren<Rigidbody>();
if(rigidbodies.Length > 0) return false; if (rigidbodies.Length > 0)
return false;
return true; return true;
} }
void CreateHingeChain(){ void CreateHingeChain () {
var utilBoneArr = utilityBone.GetComponentsInChildren<SkeletonUtilityBone>(); var utilBoneArr = utilityBone.GetComponentsInChildren<SkeletonUtilityBone>();
foreach(var utilBone in utilBoneArr){ foreach (var utilBone in utilBoneArr) {
AttachRigidbody(utilBone); AttachRigidbody(utilBone);
} }
utilityBone.rigidbody.isKinematic = true; utilityBone.rigidbody.isKinematic = true;
foreach(var utilBone in utilBoneArr){ foreach (var utilBone in utilBoneArr) {
if(utilBone == utilityBone) if (utilBone == utilityBone)
continue; continue;
utilBone.mode = SkeletonUtilityBone.Mode.Override; utilBone.mode = SkeletonUtilityBone.Mode.Override;
@ -292,16 +286,15 @@ public class SkeletonUtilityBoneInspector : Editor {
} }
} }
void AttachRigidbody(SkeletonUtilityBone utilBone){ void AttachRigidbody (SkeletonUtilityBone utilBone) {
if(utilBone.GetComponent<Collider>() == null){ if (utilBone.GetComponent<Collider>() == null) {
if(utilBone.bone.Data.Length == 0){ if (utilBone.bone.Data.Length == 0) {
SphereCollider sphere = utilBone.gameObject.AddComponent<SphereCollider>(); SphereCollider sphere = utilBone.gameObject.AddComponent<SphereCollider>();
sphere.radius = 0.1f; sphere.radius = 0.1f;
} } else {
else{
float length = utilBone.bone.Data.Length; float length = utilBone.bone.Data.Length;
BoxCollider box = utilBone.gameObject.AddComponent<BoxCollider>(); BoxCollider box = utilBone.gameObject.AddComponent<BoxCollider>();
box.size = new Vector3( length, length / 3, 0.2f); box.size = new Vector3(length, length / 3, 0.2f);
box.center = new Vector3(length / 2, 0, 0); box.center = new Vector3(length / 2, 0, 0);
} }
} }

View File

@ -32,9 +32,9 @@
* Skeleton Utility created by Mitch Thompson * Skeleton Utility created by Mitch Thompson
* Full irrevocable rights and permissions granted to Esoteric Software * Full irrevocable rights and permissions granted to Esoteric Software
*****************************************************************************/ *****************************************************************************/
using UnityEngine; using UnityEngine;
using UnityEditor; using UnityEditor;
#if UNITY_4_3 #if UNITY_4_3
//nothing //nothing
#else #else
@ -49,16 +49,16 @@ using System.Reflection;
[CustomEditor(typeof(SkeletonUtility))] [CustomEditor(typeof(SkeletonUtility))]
public class SkeletonUtilityInspector : Editor { public class SkeletonUtilityInspector : Editor {
public static void AttachIcon(SkeletonUtilityBone utilityBone){ public static void AttachIcon (SkeletonUtilityBone utilityBone) {
Skeleton skeleton = utilityBone.skeletonUtility.skeletonRenderer.skeleton; Skeleton skeleton = utilityBone.skeletonUtility.skeletonRenderer.skeleton;
Texture2D icon; Texture2D icon;
if(utilityBone.bone.Data.Length == 0) if (utilityBone.bone.Data.Length == 0)
icon = SpineEditorUtilities.Icons.nullBone; icon = SpineEditorUtilities.Icons.nullBone;
else else
icon = SpineEditorUtilities.Icons.boneNib; icon = SpineEditorUtilities.Icons.boneNib;
foreach(IkConstraint c in skeleton.IkConstraints){ foreach (IkConstraint c in skeleton.IkConstraints) {
if(c.Target == utilityBone.bone){ if (c.Target == utilityBone.bone) {
icon = SpineEditorUtilities.Icons.constraintNib; icon = SpineEditorUtilities.Icons.constraintNib;
break; break;
} }
@ -66,21 +66,22 @@ public class SkeletonUtilityInspector : Editor {
typeof(EditorGUIUtility).InvokeMember("SetIconForObject", BindingFlags.InvokeMethod | BindingFlags.Static | BindingFlags.NonPublic, null, null, new object[2]{ utilityBone.gameObject, icon}); typeof(EditorGUIUtility).InvokeMember("SetIconForObject", BindingFlags.InvokeMethod | BindingFlags.Static | BindingFlags.NonPublic, null, null, new object[2] {
utilityBone.gameObject,
icon
});
} }
static void AttachIconsToChildren(Transform root){ static void AttachIconsToChildren (Transform root) {
if(root != null){ if (root != null) {
var utilityBones = root.GetComponentsInChildren<SkeletonUtilityBone>(); var utilityBones = root.GetComponentsInChildren<SkeletonUtilityBone>();
foreach(var utilBone in utilityBones){ foreach (var utilBone in utilityBones) {
AttachIcon(utilBone); AttachIcon(utilBone);
} }
} }
} }
static SkeletonUtilityInspector () {
static SkeletonUtilityInspector(){
#if UNITY_4_3 #if UNITY_4_3
showSlots = false; showSlots = false;
#else #else
@ -89,13 +90,10 @@ public class SkeletonUtilityInspector : Editor {
} }
SkeletonUtility skeletonUtility; SkeletonUtility skeletonUtility;
Skeleton skeleton; Skeleton skeleton;
SkeletonRenderer skeletonRenderer; SkeletonRenderer skeletonRenderer;
Transform transform; Transform transform;
bool isPrefab; bool isPrefab;
Dictionary<Slot, List<Attachment>> attachmentTable = new Dictionary<Slot, List<Attachment>>(); Dictionary<Slot, List<Attachment>> attachmentTable = new Dictionary<Slot, List<Attachment>>();
@ -106,13 +104,13 @@ public class SkeletonUtilityInspector : Editor {
static AnimBool showSlots; static AnimBool showSlots;
#endif #endif
void OnEnable(){ void OnEnable () {
skeletonUtility = (SkeletonUtility)target; skeletonUtility = (SkeletonUtility)target;
skeletonRenderer = skeletonUtility.GetComponent<SkeletonRenderer>(); skeletonRenderer = skeletonUtility.GetComponent<SkeletonRenderer>();
skeleton = skeletonRenderer.skeleton; skeleton = skeletonRenderer.skeleton;
transform = skeletonRenderer.transform; transform = skeletonRenderer.transform;
if(skeleton == null){ if (skeleton == null) {
skeletonRenderer.Reset(); skeletonRenderer.Reset();
skeletonRenderer.LateUpdate(); skeletonRenderer.LateUpdate();
@ -121,44 +119,44 @@ public class SkeletonUtilityInspector : Editor {
UpdateAttachments(); UpdateAttachments();
if(PrefabUtility.GetPrefabType(this.target) == PrefabType.Prefab) if (PrefabUtility.GetPrefabType(this.target) == PrefabType.Prefab)
isPrefab = true; isPrefab = true;
} }
void OnDestroy(){ void OnDestroy () {
} }
void OnSceneGUI(){ void OnSceneGUI () {
if(skeleton == null){ if (skeleton == null) {
OnEnable(); OnEnable();
return; return;
} }
float flipRotation = skeleton.FlipX ? -1 : 1; float flipRotation = skeleton.FlipX ? -1 : 1;
foreach(Bone b in skeleton.Bones){ foreach (Bone b in skeleton.Bones) {
Vector3 vec = transform.TransformPoint(new Vector3(b.WorldX, b.WorldY, 0)); Vector3 vec = transform.TransformPoint(new Vector3(b.WorldX, b.WorldY, 0));
Quaternion rot = Quaternion.Euler(0,0,b.WorldRotation * flipRotation); Quaternion rot = Quaternion.Euler(0, 0, b.WorldRotation * flipRotation);
Vector3 forward = transform.TransformDirection( rot * Vector3.right); Vector3 forward = transform.TransformDirection(rot * Vector3.right);
forward *= flipRotation; forward *= flipRotation;
SpineEditorUtilities.Icons.boneMaterial.SetPass(0); SpineEditorUtilities.Icons.boneMaterial.SetPass(0);
Graphics.DrawMeshNow( SpineEditorUtilities.Icons.boneMesh, Matrix4x4.TRS ( vec, Quaternion.LookRotation(transform.forward, forward), Vector3.one * b.Data.Length * b.WorldScaleX)); Graphics.DrawMeshNow(SpineEditorUtilities.Icons.boneMesh, Matrix4x4.TRS(vec, Quaternion.LookRotation(transform.forward, forward), Vector3.one * b.Data.Length * b.WorldScaleX));
} }
} }
void UpdateAttachments(){ void UpdateAttachments () {
attachmentTable = new Dictionary<Slot, List<Attachment>>(); attachmentTable = new Dictionary<Slot, List<Attachment>>();
Skin skin = skeleton.Skin; Skin skin = skeleton.Skin;
if(skin == null){ if (skin == null) {
skin = skeletonRenderer.skeletonDataAsset.GetSkeletonData(true).DefaultSkin; skin = skeletonRenderer.skeletonDataAsset.GetSkeletonData(true).DefaultSkin;
} }
for(int i = skeleton.Slots.Count-1; i >= 0; i--){ for (int i = skeleton.Slots.Count-1; i >= 0; i--) {
List<Attachment> attachments = new List<Attachment>(); List<Attachment> attachments = new List<Attachment>();
skin.FindAttachmentsForSlot(i, attachments); skin.FindAttachmentsForSlot(i, attachments);
@ -166,49 +164,48 @@ public class SkeletonUtilityInspector : Editor {
} }
} }
void SpawnHierarchyButton(string label, string tooltip, SkeletonUtilityBone.Mode mode, bool pos, bool rot, bool sca, params GUILayoutOption[] options){ void SpawnHierarchyButton (string label, string tooltip, SkeletonUtilityBone.Mode mode, bool pos, bool rot, bool sca, params GUILayoutOption[] options) {
GUIContent content = new GUIContent(label, tooltip); GUIContent content = new GUIContent(label, tooltip);
if(GUILayout.Button(content, options)){ if (GUILayout.Button(content, options)) {
if(skeletonUtility.skeletonRenderer == null) if (skeletonUtility.skeletonRenderer == null)
skeletonUtility.skeletonRenderer = skeletonUtility.GetComponent<SkeletonRenderer>(); skeletonUtility.skeletonRenderer = skeletonUtility.GetComponent<SkeletonRenderer>();
if(skeletonUtility.boneRoot != null){ if (skeletonUtility.boneRoot != null) {
return; return;
} }
skeletonUtility.SpawnHierarchy(mode, pos, rot, sca); skeletonUtility.SpawnHierarchy(mode, pos, rot, sca);
SkeletonUtilityBone[] boneComps = skeletonUtility.GetComponentsInChildren<SkeletonUtilityBone>(); SkeletonUtilityBone[] boneComps = skeletonUtility.GetComponentsInChildren<SkeletonUtilityBone>();
foreach(SkeletonUtilityBone b in boneComps) foreach (SkeletonUtilityBone b in boneComps)
AttachIcon(b); AttachIcon(b);
} }
} }
public override void OnInspectorGUI () public override void OnInspectorGUI () {
{ if (isPrefab) {
if(isPrefab){
GUILayout.Label(new GUIContent("Cannot edit Prefabs", SpineEditorUtilities.Icons.warning)); GUILayout.Label(new GUIContent("Cannot edit Prefabs", SpineEditorUtilities.Icons.warning));
return; return;
} }
skeletonUtility.boneRoot = (Transform)EditorGUILayout.ObjectField( "Bone Root", skeletonUtility.boneRoot, typeof(Transform), true); skeletonUtility.boneRoot = (Transform)EditorGUILayout.ObjectField("Bone Root", skeletonUtility.boneRoot, typeof(Transform), true);
GUILayout.BeginHorizontal(); GUILayout.BeginHorizontal();
EditorGUI.BeginDisabledGroup(skeletonUtility.boneRoot != null); EditorGUI.BeginDisabledGroup(skeletonUtility.boneRoot != null);
{ {
if(GUILayout.Button(new GUIContent("Spawn Hierarchy", SpineEditorUtilities.Icons.skeleton), GUILayout.Width(150), GUILayout.Height(24))) if (GUILayout.Button(new GUIContent("Spawn Hierarchy", SpineEditorUtilities.Icons.skeleton), GUILayout.Width(150), GUILayout.Height(24)))
SpawnHierarchyContextMenu(); SpawnHierarchyContextMenu();
} }
EditorGUI.EndDisabledGroup(); EditorGUI.EndDisabledGroup();
if(GUILayout.Button(new GUIContent("Spawn Submeshes", SpineEditorUtilities.Icons.subMeshRenderer), GUILayout.Width(150), GUILayout.Height(24))) if (GUILayout.Button(new GUIContent("Spawn Submeshes", SpineEditorUtilities.Icons.subMeshRenderer), GUILayout.Width(150), GUILayout.Height(24)))
skeletonUtility.SpawnSubRenderers(true); skeletonUtility.SpawnSubRenderers(true);
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
EditorGUI.BeginChangeCheck(); EditorGUI.BeginChangeCheck();
skeleton.FlipX = EditorGUILayout.ToggleLeft("Flip X", skeleton.FlipX); skeleton.FlipX = EditorGUILayout.ToggleLeft("Flip X", skeleton.FlipX);
skeleton.FlipY = EditorGUILayout.ToggleLeft("Flip Y", skeleton.FlipY); skeleton.FlipY = EditorGUILayout.ToggleLeft("Flip Y", skeleton.FlipY);
if(EditorGUI.EndChangeCheck()){ if (EditorGUI.EndChangeCheck()) {
skeletonRenderer.LateUpdate(); skeletonRenderer.LateUpdate();
SceneView.RepaintAll(); SceneView.RepaintAll();
} }
@ -217,9 +214,9 @@ public class SkeletonUtilityInspector : Editor {
showSlots = EditorGUILayout.Foldout(showSlots, "Slots"); showSlots = EditorGUILayout.Foldout(showSlots, "Slots");
#else #else
showSlots.target = EditorGUILayout.Foldout(showSlots.target, "Slots"); showSlots.target = EditorGUILayout.Foldout(showSlots.target, "Slots");
if(EditorGUILayout.BeginFadeGroup(showSlots.faded)){ if (EditorGUILayout.BeginFadeGroup(showSlots.faded)) {
#endif #endif
foreach(KeyValuePair<Slot, List<Attachment>> pair in attachmentTable){ foreach (KeyValuePair<Slot, List<Attachment>> pair in attachmentTable) {
Slot slot = pair.Key; Slot slot = pair.Key;
@ -230,8 +227,8 @@ public class SkeletonUtilityInspector : Editor {
EditorGUI.BeginChangeCheck(); EditorGUI.BeginChangeCheck();
Color c = EditorGUILayout.ColorField(new Color(slot.R, slot.G, slot.B, slot.A), GUILayout.Width(60)); Color c = EditorGUILayout.ColorField(new Color(slot.R, slot.G, slot.B, slot.A), GUILayout.Width(60));
if(EditorGUI.EndChangeCheck()){ if (EditorGUI.EndChangeCheck()) {
slot.SetColor( c ); slot.SetColor(c);
skeletonRenderer.LateUpdate(); skeletonRenderer.LateUpdate();
} }
@ -239,12 +236,11 @@ public class SkeletonUtilityInspector : Editor {
foreach(Attachment attachment in pair.Value){ foreach (Attachment attachment in pair.Value) {
if(slot.Attachment == attachment){ if (slot.Attachment == attachment) {
GUI.contentColor = Color.white; GUI.contentColor = Color.white;
} } else {
else{
GUI.contentColor = Color.grey; GUI.contentColor = Color.grey;
} }
@ -253,18 +249,17 @@ public class SkeletonUtilityInspector : Editor {
Texture2D icon = null; Texture2D icon = null;
if(attachment is MeshAttachment || attachment is SkinnedMeshAttachment) if (attachment is MeshAttachment || attachment is SkinnedMeshAttachment)
icon = SpineEditorUtilities.Icons.mesh; icon = SpineEditorUtilities.Icons.mesh;
else else
icon = SpineEditorUtilities.Icons.image; icon = SpineEditorUtilities.Icons.image;
bool swap = EditorGUILayout.ToggleLeft( new GUIContent( attachment.Name, icon ), attachment == slot.Attachment ); bool swap = EditorGUILayout.ToggleLeft(new GUIContent(attachment.Name, icon), attachment == slot.Attachment);
if(!isAttached && swap){ if (!isAttached && swap) {
slot.Attachment = attachment; slot.Attachment = attachment;
skeletonRenderer.LateUpdate(); skeletonRenderer.LateUpdate();
} } else if (isAttached && !swap) {
else if(isAttached && !swap){
slot.Attachment = null; slot.Attachment = null;
skeletonRenderer.LateUpdate(); skeletonRenderer.LateUpdate();
} }
@ -277,12 +272,12 @@ public class SkeletonUtilityInspector : Editor {
#else #else
} }
EditorGUILayout.EndFadeGroup(); EditorGUILayout.EndFadeGroup();
if(showSlots.isAnimating) if (showSlots.isAnimating)
Repaint(); Repaint();
#endif #endif
} }
void SpawnHierarchyContextMenu(){ void SpawnHierarchyContextMenu () {
GenericMenu menu = new GenericMenu(); GenericMenu menu = new GenericMenu();
menu.AddItem(new GUIContent("Follow"), false, SpawnFollowHierarchy); menu.AddItem(new GUIContent("Follow"), false, SpawnFollowHierarchy);
@ -294,23 +289,23 @@ public class SkeletonUtilityInspector : Editor {
menu.ShowAsContext(); menu.ShowAsContext();
} }
void SpawnFollowHierarchy(){ void SpawnFollowHierarchy () {
Selection.activeGameObject = skeletonUtility.SpawnHierarchy( SkeletonUtilityBone.Mode.Follow, true, true, true ); Selection.activeGameObject = skeletonUtility.SpawnHierarchy(SkeletonUtilityBone.Mode.Follow, true, true, true);
AttachIconsToChildren( skeletonUtility.boneRoot ); AttachIconsToChildren(skeletonUtility.boneRoot);
} }
void SpawnFollowHierarchyRootOnly(){ void SpawnFollowHierarchyRootOnly () {
Selection.activeGameObject = skeletonUtility.SpawnRoot( SkeletonUtilityBone.Mode.Follow, true, true, true ); Selection.activeGameObject = skeletonUtility.SpawnRoot(SkeletonUtilityBone.Mode.Follow, true, true, true);
AttachIconsToChildren( skeletonUtility.boneRoot ); AttachIconsToChildren(skeletonUtility.boneRoot);
} }
void SpawnOverrideHierarchy(){ void SpawnOverrideHierarchy () {
Selection.activeGameObject = skeletonUtility.SpawnHierarchy( SkeletonUtilityBone.Mode.Override, true, true, true ); Selection.activeGameObject = skeletonUtility.SpawnHierarchy(SkeletonUtilityBone.Mode.Override, true, true, true);
AttachIconsToChildren( skeletonUtility.boneRoot ); AttachIconsToChildren(skeletonUtility.boneRoot);
} }
void SpawnOverrideHierarchyRootOnly(){ void SpawnOverrideHierarchyRootOnly () {
Selection.activeGameObject = skeletonUtility.SpawnRoot( SkeletonUtilityBone.Mode.Override, true, true, true ); Selection.activeGameObject = skeletonUtility.SpawnRoot(SkeletonUtilityBone.Mode.Override, true, true, true);
AttachIconsToChildren( skeletonUtility.boneRoot ); AttachIconsToChildren(skeletonUtility.boneRoot);
} }
} }

View File

@ -42,7 +42,7 @@ using Spine;
[ExecuteInEditMode] [ExecuteInEditMode]
public class SkeletonUtility : MonoBehaviour { public class SkeletonUtility : MonoBehaviour {
public static T GetInParent<T>(Transform origin) where T : Component{ public static T GetInParent<T> (Transform origin) where T : Component {
#if UNITY_4_3 #if UNITY_4_3
Transform parent = origin.parent; Transform parent = origin.parent;
while(parent.GetComponent<T>() == null){ while(parent.GetComponent<T>() == null){
@ -58,18 +58,19 @@ public class SkeletonUtility : MonoBehaviour {
} }
public delegate void SkeletonUtilityDelegate(); public delegate void SkeletonUtilityDelegate ();
public event SkeletonUtilityDelegate OnReset; public event SkeletonUtilityDelegate OnReset;
public Transform boneRoot; public Transform boneRoot;
void Update(){ void Update () {
if(boneRoot != null && skeletonRenderer.skeleton != null){ if (boneRoot != null && skeletonRenderer.skeleton != null) {
Vector3 flipScale = Vector3.one; Vector3 flipScale = Vector3.one;
if(skeletonRenderer.skeleton.FlipX) if (skeletonRenderer.skeleton.FlipX)
flipScale.x = -1; flipScale.x = -1;
if(skeletonRenderer.skeleton.FlipY) if (skeletonRenderer.skeleton.FlipY)
flipScale.y = -1; flipScale.y = -1;
boneRoot.localScale = flipScale; boneRoot.localScale = flipScale;
@ -78,35 +79,31 @@ public class SkeletonUtility : MonoBehaviour {
[HideInInspector] [HideInInspector]
public SkeletonRenderer skeletonRenderer; public SkeletonRenderer skeletonRenderer;
[HideInInspector] [HideInInspector]
public SkeletonAnimation skeletonAnimation; public SkeletonAnimation skeletonAnimation;
[System.NonSerialized] [System.NonSerialized]
public List<SkeletonUtilityBone> utilityBones = new List<SkeletonUtilityBone>(); public List<SkeletonUtilityBone> utilityBones = new List<SkeletonUtilityBone>();
[System.NonSerialized] [System.NonSerialized]
public List<SkeletonUtilityConstraint> utilityConstraints = new List<SkeletonUtilityConstraint>(); public List<SkeletonUtilityConstraint> utilityConstraints = new List<SkeletonUtilityConstraint>();
// Dictionary<Bone, SkeletonUtilityBone> utilityBoneTable; // Dictionary<Bone, SkeletonUtilityBone> utilityBoneTable;
protected bool hasTransformBones; protected bool hasTransformBones;
protected bool hasUtilityConstraints; protected bool hasUtilityConstraints;
protected bool needToReprocessBones; protected bool needToReprocessBones;
void OnEnable(){ void OnEnable () {
if(skeletonRenderer == null){ if (skeletonRenderer == null) {
skeletonRenderer = GetComponent<SkeletonRenderer>(); skeletonRenderer = GetComponent<SkeletonRenderer>();
} }
if(skeletonAnimation == null){ if (skeletonAnimation == null) {
skeletonAnimation = GetComponent<SkeletonAnimation>(); skeletonAnimation = GetComponent<SkeletonAnimation>();
} }
skeletonRenderer.OnReset -= HandleRendererReset; skeletonRenderer.OnReset -= HandleRendererReset;
skeletonRenderer.OnReset += HandleRendererReset; skeletonRenderer.OnReset += HandleRendererReset;
if(skeletonAnimation != null){ if (skeletonAnimation != null) {
skeletonAnimation.UpdateLocal -= UpdateLocal; skeletonAnimation.UpdateLocal -= UpdateLocal;
skeletonAnimation.UpdateLocal += UpdateLocal; skeletonAnimation.UpdateLocal += UpdateLocal;
} }
@ -115,147 +112,144 @@ public class SkeletonUtility : MonoBehaviour {
CollectBones(); CollectBones();
} }
void Start(){ void Start () {
//recollect because order of operations failure when switching between game mode and edit mode... //recollect because order of operations failure when switching between game mode and edit mode...
// CollectBones(); // CollectBones();
} }
void OnDisable () {
void OnDisable(){
skeletonRenderer.OnReset -= HandleRendererReset; skeletonRenderer.OnReset -= HandleRendererReset;
if(skeletonAnimation != null){ if (skeletonAnimation != null) {
skeletonAnimation.UpdateLocal -= UpdateLocal; skeletonAnimation.UpdateLocal -= UpdateLocal;
skeletonAnimation.UpdateWorld -= UpdateWorld; skeletonAnimation.UpdateWorld -= UpdateWorld;
skeletonAnimation.UpdateComplete -= UpdateComplete; skeletonAnimation.UpdateComplete -= UpdateComplete;
} }
} }
void HandleRendererReset(SkeletonRenderer r){ void HandleRendererReset (SkeletonRenderer r) {
if(OnReset != null) if (OnReset != null)
OnReset(); OnReset();
CollectBones(); CollectBones();
} }
public void RegisterBone(SkeletonUtilityBone bone){ public void RegisterBone (SkeletonUtilityBone bone) {
if(utilityBones.Contains(bone)) if (utilityBones.Contains(bone))
return; return;
else{ else {
utilityBones.Add(bone); utilityBones.Add(bone);
needToReprocessBones = true; needToReprocessBones = true;
} }
} }
public void UnregisterBone(SkeletonUtilityBone bone){ public void UnregisterBone (SkeletonUtilityBone bone) {
utilityBones.Remove(bone); utilityBones.Remove(bone);
} }
public void RegisterConstraint(SkeletonUtilityConstraint constraint){ public void RegisterConstraint (SkeletonUtilityConstraint constraint) {
if(utilityConstraints.Contains(constraint)) if (utilityConstraints.Contains(constraint))
return; return;
else{ else {
utilityConstraints.Add(constraint); utilityConstraints.Add(constraint);
needToReprocessBones = true; needToReprocessBones = true;
} }
} }
public void UnregisterConstraint(SkeletonUtilityConstraint constraint){ public void UnregisterConstraint (SkeletonUtilityConstraint constraint) {
utilityConstraints.Remove(constraint); utilityConstraints.Remove(constraint);
} }
public void CollectBones(){ public void CollectBones () {
if(skeletonRenderer.skeleton == null) if (skeletonRenderer.skeleton == null)
return; return;
if(boneRoot != null){ if (boneRoot != null) {
List<string> constraintTargetNames = new List<string>(); List<string> constraintTargetNames = new List<string>();
foreach(IkConstraint c in skeletonRenderer.skeleton.IkConstraints){ foreach (IkConstraint c in skeletonRenderer.skeleton.IkConstraints) {
constraintTargetNames.Add(c.Target.Data.Name); constraintTargetNames.Add(c.Target.Data.Name);
} }
foreach(var b in utilityBones){ foreach (var b in utilityBones) {
if(b.bone == null){ if (b.bone == null) {
return; return;
} }
if(b.mode == SkeletonUtilityBone.Mode.Override){ if (b.mode == SkeletonUtilityBone.Mode.Override) {
hasTransformBones = true; hasTransformBones = true;
} }
if(constraintTargetNames.Contains( b.bone.Data.Name )){ if (constraintTargetNames.Contains(b.bone.Data.Name)) {
hasUtilityConstraints = true; hasUtilityConstraints = true;
} }
} }
if(utilityConstraints.Count > 0) if (utilityConstraints.Count > 0)
hasUtilityConstraints = true; hasUtilityConstraints = true;
if(skeletonAnimation != null){ if (skeletonAnimation != null) {
skeletonAnimation.UpdateWorld -= UpdateWorld; skeletonAnimation.UpdateWorld -= UpdateWorld;
skeletonAnimation.UpdateComplete -= UpdateComplete; skeletonAnimation.UpdateComplete -= UpdateComplete;
if(hasTransformBones || hasUtilityConstraints){ if (hasTransformBones || hasUtilityConstraints) {
skeletonAnimation.UpdateWorld += UpdateWorld; skeletonAnimation.UpdateWorld += UpdateWorld;
} }
if(hasUtilityConstraints){ if (hasUtilityConstraints) {
skeletonAnimation.UpdateComplete += UpdateComplete; skeletonAnimation.UpdateComplete += UpdateComplete;
} }
} }
needToReprocessBones = false; needToReprocessBones = false;
} } else {
else{
utilityBones.Clear(); utilityBones.Clear();
utilityConstraints.Clear(); utilityConstraints.Clear();
} }
} }
void UpdateLocal(SkeletonAnimation anim){ void UpdateLocal (SkeletonAnimation anim) {
if(needToReprocessBones) if (needToReprocessBones)
CollectBones(); CollectBones();
if(utilityBones == null) if (utilityBones == null)
return; return;
foreach(SkeletonUtilityBone b in utilityBones){ foreach (SkeletonUtilityBone b in utilityBones) {
b.transformLerpComplete = false; b.transformLerpComplete = false;
} }
UpdateAllBones(); UpdateAllBones();
} }
void UpdateWorld(SkeletonAnimation anim){ void UpdateWorld (SkeletonAnimation anim) {
UpdateAllBones(); UpdateAllBones();
foreach(SkeletonUtilityConstraint c in utilityConstraints) foreach (SkeletonUtilityConstraint c in utilityConstraints)
c.DoUpdate(); c.DoUpdate();
} }
void UpdateComplete(SkeletonAnimation anim){ void UpdateComplete (SkeletonAnimation anim) {
UpdateAllBones(); UpdateAllBones();
} }
void UpdateAllBones(){ void UpdateAllBones () {
if(boneRoot == null){ if (boneRoot == null) {
CollectBones(); CollectBones();
} }
if(utilityBones == null) if (utilityBones == null)
return; return;
foreach(SkeletonUtilityBone b in utilityBones){ foreach (SkeletonUtilityBone b in utilityBones) {
b.DoUpdate(); b.DoUpdate();
} }
} }
public Transform GetBoneRoot(){ public Transform GetBoneRoot () {
if(boneRoot != null) if (boneRoot != null)
return boneRoot; return boneRoot;
boneRoot = new GameObject("SkeletonUtility-Root").transform; boneRoot = new GameObject("SkeletonUtility-Root").transform;
@ -267,18 +261,18 @@ public class SkeletonUtility : MonoBehaviour {
return boneRoot; return boneRoot;
} }
public GameObject SpawnRoot(SkeletonUtilityBone.Mode mode, bool pos, bool rot, bool sca){ public GameObject SpawnRoot (SkeletonUtilityBone.Mode mode, bool pos, bool rot, bool sca) {
GetBoneRoot(); GetBoneRoot();
Skeleton skeleton = this.skeletonRenderer.skeleton; Skeleton skeleton = this.skeletonRenderer.skeleton;
GameObject go = SpawnBone( skeleton.RootBone, boneRoot, mode, pos, rot, sca ); GameObject go = SpawnBone(skeleton.RootBone, boneRoot, mode, pos, rot, sca);
CollectBones(); CollectBones();
return go; return go;
} }
public GameObject SpawnHierarchy(SkeletonUtilityBone.Mode mode, bool pos, bool rot, bool sca){ public GameObject SpawnHierarchy (SkeletonUtilityBone.Mode mode, bool pos, bool rot, bool sca) {
GetBoneRoot(); GetBoneRoot();
Skeleton skeleton = this.skeletonRenderer.skeleton; Skeleton skeleton = this.skeletonRenderer.skeleton;
@ -290,17 +284,17 @@ public class SkeletonUtility : MonoBehaviour {
return go; return go;
} }
public GameObject SpawnBoneRecursively(Bone bone, Transform parent, SkeletonUtilityBone.Mode mode, bool pos, bool rot, bool sca){ public GameObject SpawnBoneRecursively (Bone bone, Transform parent, SkeletonUtilityBone.Mode mode, bool pos, bool rot, bool sca) {
GameObject go = SpawnBone(bone, parent, mode, pos, rot, sca); GameObject go = SpawnBone(bone, parent, mode, pos, rot, sca);
foreach(Bone child in bone.Children){ foreach (Bone child in bone.Children) {
SpawnBoneRecursively(child, go.transform, mode, pos, rot, sca); SpawnBoneRecursively(child, go.transform, mode, pos, rot, sca);
} }
return go; return go;
} }
public GameObject SpawnBone(Bone bone, Transform parent, SkeletonUtilityBone.Mode mode, bool pos, bool rot, bool sca){ public GameObject SpawnBone (Bone bone, Transform parent, SkeletonUtilityBone.Mode mode, bool pos, bool rot, bool sca) {
GameObject go = new GameObject(bone.Data.Name); GameObject go = new GameObject(bone.Data.Name);
go.transform.parent = parent; go.transform.parent = parent;
@ -316,11 +310,11 @@ public class SkeletonUtility : MonoBehaviour {
b.boneName = bone.Data.Name; b.boneName = bone.Data.Name;
b.valid = true; b.valid = true;
if(mode == SkeletonUtilityBone.Mode.Override){ if (mode == SkeletonUtilityBone.Mode.Override) {
if(rot) if (rot)
go.transform.localRotation = Quaternion.Euler(0, 0, b.bone.RotationIK); go.transform.localRotation = Quaternion.Euler(0, 0, b.bone.RotationIK);
if(pos) if (pos)
go.transform.localPosition = new Vector3(b.bone.X, b.bone.Y, 0); go.transform.localPosition = new Vector3(b.bone.X, b.bone.Y, 0);
go.transform.localScale = new Vector3(b.bone.scaleX, b.bone.scaleY, 0); go.transform.localScale = new Vector3(b.bone.scaleX, b.bone.scaleY, 0);
@ -329,10 +323,10 @@ public class SkeletonUtility : MonoBehaviour {
return go; return go;
} }
public void SpawnSubRenderers(bool disablePrimaryRenderer){ public void SpawnSubRenderers (bool disablePrimaryRenderer) {
int submeshCount = GetComponent<MeshFilter>().sharedMesh.subMeshCount; int submeshCount = GetComponent<MeshFilter>().sharedMesh.subMeshCount;
for(int i = 0; i < submeshCount; i++){ for (int i = 0; i < submeshCount; i++) {
GameObject go = new GameObject("Submesh " + i, typeof(MeshFilter), typeof(MeshRenderer)); GameObject go = new GameObject("Submesh " + i, typeof(MeshFilter), typeof(MeshRenderer));
go.transform.parent = transform; go.transform.parent = transform;
go.transform.localPosition = Vector3.zero; go.transform.localPosition = Vector3.zero;
@ -342,11 +336,11 @@ public class SkeletonUtility : MonoBehaviour {
SkeletonUtilitySubmeshRenderer s = go.AddComponent<SkeletonUtilitySubmeshRenderer>(); SkeletonUtilitySubmeshRenderer s = go.AddComponent<SkeletonUtilitySubmeshRenderer>();
s.sortingOrder = i * 10; s.sortingOrder = i * 10;
s.submeshIndex = i; s.submeshIndex = i;
s.Initialize( renderer ); s.Initialize(renderer);
s.Update(); s.Update();
} }
if(disablePrimaryRenderer) if (disablePrimaryRenderer)
renderer.enabled = false; renderer.enabled = false;
} }
} }

View File

@ -44,52 +44,49 @@ using Spine;
[AddComponentMenu("Spine/SkeletonUtilityBone")] [AddComponentMenu("Spine/SkeletonUtilityBone")]
public class SkeletonUtilityBone : MonoBehaviour { public class SkeletonUtilityBone : MonoBehaviour {
public enum Mode { Follow, Override } public enum Mode {
Follow,
Override
}
[System.NonSerialized] [System.NonSerialized]
public bool valid; public bool valid;
[System.NonSerialized] [System.NonSerialized]
public SkeletonUtility skeletonUtility; public SkeletonUtility skeletonUtility;
[System.NonSerialized] [System.NonSerialized]
public Bone bone; public Bone bone;
public Mode mode; public Mode mode;
public bool zPosition = true; public bool zPosition = true;
public bool position; public bool position;
public bool rotation; public bool rotation;
public bool scale; public bool scale;
public bool flip; public bool flip;
public bool flipX; public bool flipX;
[Range(0f,1f)] [Range(0f,1f)]
public float overrideAlpha = 1; public float overrideAlpha = 1;
/// <summary>If a bone isn't set, boneName is used to find the bone.</summary> /// <summary>If a bone isn't set, boneName is used to find the bone.</summary>
public String boneName; public String boneName;
public Transform parentReference; public Transform parentReference;
[HideInInspector] [HideInInspector]
public bool transformLerpComplete; public bool transformLerpComplete;
protected Transform cachedTransform; protected Transform cachedTransform;
protected Transform skeletonTransform; protected Transform skeletonTransform;
public bool NonUniformScaleWarning{ public bool NonUniformScaleWarning {
get{ get {
return nonUniformScaleWarning; return nonUniformScaleWarning;
} }
} }
private bool nonUniformScaleWarning; private bool nonUniformScaleWarning;
public void Reset () { public void Reset () {
bone = null; bone = null;
cachedTransform = transform; cachedTransform = transform;
valid = skeletonUtility != null && skeletonUtility.skeletonRenderer != null && skeletonUtility.skeletonRenderer.valid; valid = skeletonUtility != null && skeletonUtility.skeletonRenderer != null && skeletonUtility.skeletonRenderer.valid;
if (!valid) return; if (!valid)
return;
skeletonTransform = skeletonUtility.transform; skeletonTransform = skeletonUtility.transform;
skeletonUtility.OnReset -= HandleOnReset; skeletonUtility.OnReset -= HandleOnReset;
@ -98,10 +95,10 @@ public class SkeletonUtilityBone : MonoBehaviour {
DoUpdate(); DoUpdate();
} }
void OnEnable(){ void OnEnable () {
skeletonUtility = SkeletonUtility.GetInParent<SkeletonUtility>(transform); skeletonUtility = SkeletonUtility.GetInParent<SkeletonUtility>(transform);
if(skeletonUtility == null) if (skeletonUtility == null)
return; return;
skeletonUtility.RegisterBone(this); skeletonUtility.RegisterBone(this);
@ -109,13 +106,12 @@ public class SkeletonUtilityBone : MonoBehaviour {
skeletonUtility.OnReset += HandleOnReset; skeletonUtility.OnReset += HandleOnReset;
} }
void HandleOnReset () void HandleOnReset () {
{ Reset();
Reset ();
} }
void OnDisable(){ void OnDisable () {
if(skeletonUtility != null){ if (skeletonUtility != null) {
skeletonUtility.OnReset -= HandleOnReset; skeletonUtility.OnReset -= HandleOnReset;
skeletonUtility.UnregisterBone(this); skeletonUtility.UnregisterBone(this);
@ -132,7 +128,8 @@ public class SkeletonUtilityBone : MonoBehaviour {
Spine.Skeleton skeleton = skeletonUtility.skeletonRenderer.skeleton; Spine.Skeleton skeleton = skeletonUtility.skeletonRenderer.skeleton;
if (bone == null) { if (bone == null) {
if (boneName == null || boneName.Length == 0) return; if (boneName == null || boneName.Length == 0)
return;
bone = skeleton.FindBone(boneName); bone = skeleton.FindBone(boneName);
if (bone == null) { if (bone == null) {
Debug.LogError("Bone not found: " + boneName, this); Debug.LogError("Bone not found: " + boneName, this);
@ -145,66 +142,59 @@ public class SkeletonUtilityBone : MonoBehaviour {
float skeletonFlipRotation = (skeleton.flipX ^ skeleton.flipY) ? -1f : 1f; float skeletonFlipRotation = (skeleton.flipX ^ skeleton.flipY) ? -1f : 1f;
float flipCompensation = 0; float flipCompensation = 0;
if (flip && (flipX || ( flipX != bone.flipX)) && bone.parent != null) if (flip && (flipX || (flipX != bone.flipX)) && bone.parent != null) {
{
flipCompensation = bone.parent.WorldRotation * -2; flipCompensation = bone.parent.WorldRotation * -2;
} }
if(mode == Mode.Follow){ if (mode == Mode.Follow) {
if (flip) if (flip) {
{
flipX = bone.flipX; flipX = bone.flipX;
} }
if(position){ if (position) {
cachedTransform.localPosition = new Vector3(bone.x, bone.y, 0); cachedTransform.localPosition = new Vector3(bone.x, bone.y, 0);
} }
if(rotation){ if (rotation) {
if(bone.Data.InheritRotation){ if (bone.Data.InheritRotation) {
if (bone.FlipX) if (bone.FlipX) {
{
cachedTransform.localRotation = Quaternion.Euler(0, 180, bone.rotationIK - flipCompensation); cachedTransform.localRotation = Quaternion.Euler(0, 180, bone.rotationIK - flipCompensation);
} else {
cachedTransform.localRotation = Quaternion.Euler(0, 0, bone.rotationIK);
} }
else { } else {
cachedTransform.localRotation = Quaternion.Euler(0,0,bone.rotationIK);
}
}
else{
Vector3 euler = skeletonTransform.rotation.eulerAngles; Vector3 euler = skeletonTransform.rotation.eulerAngles;
cachedTransform.rotation = Quaternion.Euler(euler.x, euler.y, skeletonTransform.rotation.eulerAngles.z + (bone.worldRotation * skeletonFlipRotation) ); cachedTransform.rotation = Quaternion.Euler(euler.x, euler.y, skeletonTransform.rotation.eulerAngles.z + (bone.worldRotation * skeletonFlipRotation));
} }
} }
if(scale){ if (scale) {
cachedTransform.localScale = new Vector3(bone.scaleX, bone.scaleY, 1); cachedTransform.localScale = new Vector3(bone.scaleX, bone.scaleY, 1);
nonUniformScaleWarning = (bone.scaleX != bone.scaleY); nonUniformScaleWarning = (bone.scaleX != bone.scaleY);
} }
} } else if (mode == Mode.Override) {
else if(mode == Mode.Override){
if(transformLerpComplete) if (transformLerpComplete)
return; return;
if(parentReference == null){ if (parentReference == null) {
if(position){ if (position) {
bone.x = Mathf.Lerp(bone.x, cachedTransform.localPosition.x, overrideAlpha); bone.x = Mathf.Lerp(bone.x, cachedTransform.localPosition.x, overrideAlpha);
bone.y = Mathf.Lerp(bone.y, cachedTransform.localPosition.y, overrideAlpha); bone.y = Mathf.Lerp(bone.y, cachedTransform.localPosition.y, overrideAlpha);
} }
if(rotation){ if (rotation) {
float angle = Mathf.LerpAngle(bone.Rotation, cachedTransform.localRotation.eulerAngles.z, overrideAlpha) + flipCompensation; float angle = Mathf.LerpAngle(bone.Rotation, cachedTransform.localRotation.eulerAngles.z, overrideAlpha) + flipCompensation;
if (flip) { if (flip) {
if ((!flipX && bone.flipX)) if ((!flipX && bone.flipX)) {
{
angle -= flipCompensation; angle -= flipCompensation;
} }
@ -218,36 +208,32 @@ public class SkeletonUtilityBone : MonoBehaviour {
bone.Rotation = angle; bone.Rotation = angle;
} }
if(scale){ if (scale) {
bone.scaleX = Mathf.Lerp(bone.scaleX, cachedTransform.localScale.x, overrideAlpha); bone.scaleX = Mathf.Lerp(bone.scaleX, cachedTransform.localScale.x, overrideAlpha);
bone.scaleY = Mathf.Lerp(bone.scaleY, cachedTransform.localScale.y, overrideAlpha); bone.scaleY = Mathf.Lerp(bone.scaleY, cachedTransform.localScale.y, overrideAlpha);
nonUniformScaleWarning = (bone.scaleX != bone.scaleY); nonUniformScaleWarning = (bone.scaleX != bone.scaleY);
} }
if (flip) if (flip) {
{
bone.flipX = flipX; bone.flipX = flipX;
} }
} } else {
else{
if (transformLerpComplete) if (transformLerpComplete)
return; return;
if(position){ if (position) {
Vector3 pos = parentReference.InverseTransformPoint(cachedTransform.position); Vector3 pos = parentReference.InverseTransformPoint(cachedTransform.position);
bone.x = Mathf.Lerp(bone.x, pos.x, overrideAlpha); bone.x = Mathf.Lerp(bone.x, pos.x, overrideAlpha);
bone.y = Mathf.Lerp(bone.y, pos.y, overrideAlpha); bone.y = Mathf.Lerp(bone.y, pos.y, overrideAlpha);
} }
if(rotation){ if (rotation) {
float angle = Mathf.LerpAngle(bone.Rotation, Quaternion.LookRotation(flipX ? Vector3.forward * -1 : Vector3.forward, parentReference.InverseTransformDirection(cachedTransform.up)).eulerAngles.z, overrideAlpha) + flipCompensation; float angle = Mathf.LerpAngle(bone.Rotation, Quaternion.LookRotation(flipX ? Vector3.forward * -1 : Vector3.forward, parentReference.InverseTransformDirection(cachedTransform.up)).eulerAngles.z, overrideAlpha) + flipCompensation;
if (flip) if (flip) {
{ if ((!flipX && bone.flipX)) {
if ((!flipX && bone.flipX))
{
angle -= flipCompensation; angle -= flipCompensation;
} }
@ -262,15 +248,14 @@ public class SkeletonUtilityBone : MonoBehaviour {
} }
//TODO: Something about this //TODO: Something about this
if(scale){ if (scale) {
bone.scaleX = Mathf.Lerp(bone.scaleX, cachedTransform.localScale.x, overrideAlpha); bone.scaleX = Mathf.Lerp(bone.scaleX, cachedTransform.localScale.x, overrideAlpha);
bone.scaleY = Mathf.Lerp(bone.scaleY, cachedTransform.localScale.y, overrideAlpha); bone.scaleY = Mathf.Lerp(bone.scaleY, cachedTransform.localScale.y, overrideAlpha);
nonUniformScaleWarning = (bone.scaleX != bone.scaleY); nonUniformScaleWarning = (bone.scaleX != bone.scaleY);
} }
if (flip) if (flip) {
{
bone.flipX = flipX; bone.flipX = flipX;
} }
@ -280,18 +265,13 @@ public class SkeletonUtilityBone : MonoBehaviour {
} }
} }
public void FlipX(bool state) public void FlipX (bool state) {
{ if (state != flipX) {
if (state != flipX)
{
flipX = state; flipX = state;
if (flipX && Mathf.Abs(transform.localRotation.eulerAngles.y) > 90) if (flipX && Mathf.Abs(transform.localRotation.eulerAngles.y) > 90) {
{
skeletonUtility.skeletonAnimation.LateUpdate(); skeletonUtility.skeletonAnimation.LateUpdate();
return; return;
} } else if (!flipX && Mathf.Abs(transform.localRotation.eulerAngles.y) < 90) {
else if (!flipX && Mathf.Abs(transform.localRotation.eulerAngles.y) < 90)
{
skeletonUtility.skeletonAnimation.LateUpdate(); skeletonUtility.skeletonAnimation.LateUpdate();
return; return;
} }
@ -305,9 +285,9 @@ public class SkeletonUtilityBone : MonoBehaviour {
transform.localRotation = Quaternion.Euler(euler); transform.localRotation = Quaternion.Euler(euler);
} }
void OnDrawGizmos(){ void OnDrawGizmos () {
if(NonUniformScaleWarning){ if (NonUniformScaleWarning) {
Gizmos.DrawIcon(transform.position + new Vector3(0,0.128f,0), "icon-warning"); Gizmos.DrawIcon(transform.position + new Vector3(0, 0.128f, 0), "icon-warning");
} }
} }
} }

View File

@ -8,15 +8,15 @@ public abstract class SkeletonUtilityConstraint : MonoBehaviour {
protected SkeletonUtilityBone utilBone; protected SkeletonUtilityBone utilBone;
protected SkeletonUtility skeletonUtility; protected SkeletonUtility skeletonUtility;
protected virtual void OnEnable(){ protected virtual void OnEnable () {
utilBone = GetComponent<SkeletonUtilityBone>(); utilBone = GetComponent<SkeletonUtilityBone>();
skeletonUtility = SkeletonUtility.GetInParent<SkeletonUtility>(transform); skeletonUtility = SkeletonUtility.GetInParent<SkeletonUtility>(transform);
skeletonUtility.RegisterConstraint(this); skeletonUtility.RegisterConstraint(this);
} }
protected virtual void OnDisable(){ protected virtual void OnDisable () {
skeletonUtility.UnregisterConstraint(this); skeletonUtility.UnregisterConstraint(this);
} }
public abstract void DoUpdate(); public abstract void DoUpdate ();
} }

View File

@ -7,41 +7,36 @@ public class SkeletonUtilityEyeConstraint : SkeletonUtilityConstraint {
public float radius = 0.5f; public float radius = 0.5f;
public Transform target; public Transform target;
public Vector3 targetPosition; public Vector3 targetPosition;
public float speed = 10; public float speed = 10;
Vector3[] origins; Vector3[] origins;
Vector3 centerPoint; Vector3 centerPoint;
protected override void OnEnable () protected override void OnEnable () {
{ if (!Application.isPlaying)
if(!Application.isPlaying)
return; return;
base.OnEnable (); base.OnEnable();
Bounds centerBounds = new Bounds( eyes[0].localPosition, Vector3.zero ); Bounds centerBounds = new Bounds(eyes[0].localPosition, Vector3.zero);
origins = new Vector3[eyes.Length]; origins = new Vector3[eyes.Length];
for(int i = 0; i < eyes.Length; i++){ for (int i = 0; i < eyes.Length; i++) {
origins[i] = eyes[i].localPosition; origins[i] = eyes[i].localPosition;
centerBounds.Encapsulate( origins[i] ); centerBounds.Encapsulate(origins[i]);
} }
centerPoint = centerBounds.center; centerPoint = centerBounds.center;
} }
protected override void OnDisable () protected override void OnDisable () {
{ if (!Application.isPlaying)
if(!Application.isPlaying)
return; return;
base.OnDisable (); base.OnDisable();
} }
public override void DoUpdate () public override void DoUpdate () {
{
if(target != null) if (target != null)
targetPosition = target.position; targetPosition = target.position;
Vector3 goal = targetPosition; Vector3 goal = targetPosition;
@ -49,10 +44,10 @@ public class SkeletonUtilityEyeConstraint : SkeletonUtilityConstraint {
Vector3 center = transform.TransformPoint(centerPoint); Vector3 center = transform.TransformPoint(centerPoint);
Vector3 dir = goal - center; Vector3 dir = goal - center;
if(dir.magnitude > 1) if (dir.magnitude > 1)
dir.Normalize(); dir.Normalize();
for(int i = 0; i < eyes.Length; i++){ for (int i = 0; i < eyes.Length; i++) {
center = transform.TransformPoint(origins[i]); center = transform.TransformPoint(origins[i]);
eyes[i].position = Vector3.MoveTowards(eyes[i].position, center + (dir * radius), speed * Time.deltaTime); eyes[i].position = Vector3.MoveTowards(eyes[i].position, center + (dir * radius), speed * Time.deltaTime);
} }

View File

@ -34,71 +34,63 @@ public class SkeletonUtilityGroundConstraint : SkeletonUtilityConstraint {
Vector3 rayOrigin; Vector3 rayOrigin;
Vector3 rayDir = new Vector3(0,-1,0); Vector3 rayDir = new Vector3(0, -1, 0);
float hitY; float hitY;
float lastHitY; float lastHitY;
protected override void OnEnable () protected override void OnEnable () {
{ base.OnEnable();
base.OnEnable ();
} }
protected override void OnDisable () protected override void OnDisable () {
{ base.OnDisable();
base.OnDisable ();
} }
public override void DoUpdate() public override void DoUpdate () {
{ rayOrigin = transform.position + new Vector3(castOffset, castDistance, 0);
rayOrigin = transform.position + new Vector3(castOffset,castDistance,0);
hitY = float.MinValue; hitY = float.MinValue;
if(use2D){ if (use2D) {
RaycastHit2D hit; RaycastHit2D hit;
if(useRadius){ if (useRadius) {
#if UNITY_4_3 #if UNITY_4_3
//NOTE: Unity 4.3.x does not have CircleCast //NOTE: Unity 4.3.x does not have CircleCast
hit = Physics2D.Raycast(rayOrigin , rayDir, castDistance + groundOffset, groundMask); hit = Physics2D.Raycast(rayOrigin , rayDir, castDistance + groundOffset, groundMask);
#else #else
hit = Physics2D.CircleCast( rayOrigin, castRadius, rayDir, castDistance + groundOffset, groundMask ); hit = Physics2D.CircleCast(rayOrigin, castRadius, rayDir, castDistance + groundOffset, groundMask);
#endif #endif
} } else {
else{ hit = Physics2D.Raycast(rayOrigin, rayDir, castDistance + groundOffset, groundMask);
hit = Physics2D.Raycast(rayOrigin , rayDir, castDistance + groundOffset, groundMask);
} }
if(hit.collider != null){ if (hit.collider != null) {
hitY = hit.point.y + groundOffset; hitY = hit.point.y + groundOffset;
if(Application.isPlaying){ if (Application.isPlaying) {
hitY = Mathf.MoveTowards( lastHitY, hitY, adjustSpeed * Time.deltaTime ); hitY = Mathf.MoveTowards(lastHitY, hitY, adjustSpeed * Time.deltaTime);
} }
} else {
if (Application.isPlaying)
hitY = Mathf.MoveTowards(lastHitY, transform.position.y, adjustSpeed * Time.deltaTime);
} }
else{ } else {
if(Application.isPlaying)
hitY = Mathf.MoveTowards( lastHitY, transform.position.y, adjustSpeed * Time.deltaTime );
}
}
else{
RaycastHit hit; RaycastHit hit;
bool validHit = false; bool validHit = false;
if(useRadius){ if (useRadius) {
validHit = Physics.SphereCast( rayOrigin, castRadius, rayDir, out hit, castDistance + groundOffset, groundMask ); validHit = Physics.SphereCast(rayOrigin, castRadius, rayDir, out hit, castDistance + groundOffset, groundMask);
} } else {
else{ validHit = Physics.Raycast(rayOrigin, rayDir, out hit, castDistance + groundOffset, groundMask);
validHit = Physics.Raycast( rayOrigin, rayDir, out hit, castDistance + groundOffset, groundMask);
} }
if(validHit){ if (validHit) {
hitY = hit.point.y + groundOffset; hitY = hit.point.y + groundOffset;
if(Application.isPlaying){ if (Application.isPlaying) {
hitY = Mathf.MoveTowards( lastHitY, hitY, adjustSpeed * Time.deltaTime ); hitY = Mathf.MoveTowards(lastHitY, hitY, adjustSpeed * Time.deltaTime);
} }
} } else {
else{ if (Application.isPlaying)
if(Application.isPlaying) hitY = Mathf.MoveTowards(lastHitY, transform.position.y, adjustSpeed * Time.deltaTime);
hitY = Mathf.MoveTowards( lastHitY, transform.position.y, adjustSpeed * Time.deltaTime );
} }
} }
@ -110,21 +102,18 @@ public class SkeletonUtilityGroundConstraint : SkeletonUtilityConstraint {
utilBone.bone.Y = transform.localPosition.y; utilBone.bone.Y = transform.localPosition.y;
lastHitY = hitY; lastHitY = hitY;
} }
void OnDrawGizmos(){ void OnDrawGizmos () {
Vector3 hitEnd = rayOrigin + (rayDir * Mathf.Min(castDistance, rayOrigin.y - hitY)); Vector3 hitEnd = rayOrigin + (rayDir * Mathf.Min(castDistance, rayOrigin.y - hitY));
Vector3 clearEnd = rayOrigin + (rayDir * castDistance); Vector3 clearEnd = rayOrigin + (rayDir * castDistance);
Gizmos.DrawLine(rayOrigin, hitEnd); Gizmos.DrawLine(rayOrigin, hitEnd);
if(useRadius){ if (useRadius) {
Gizmos.DrawLine(new Vector3(hitEnd.x - castRadius, hitEnd.y - groundOffset, hitEnd.z), new Vector3(hitEnd.x + castRadius, hitEnd.y - groundOffset, hitEnd.z)); Gizmos.DrawLine(new Vector3(hitEnd.x - castRadius, hitEnd.y - groundOffset, hitEnd.z), new Vector3(hitEnd.x + castRadius, hitEnd.y - groundOffset, hitEnd.z));
Gizmos.DrawLine(new Vector3(clearEnd.x - castRadius, clearEnd.y, clearEnd.z), new Vector3(clearEnd.x + castRadius, clearEnd.y, clearEnd.z)); Gizmos.DrawLine(new Vector3(clearEnd.x - castRadius, clearEnd.y, clearEnd.z), new Vector3(clearEnd.x + castRadius, clearEnd.y, clearEnd.z));
} }
Gizmos.color = Color.red; Gizmos.color = Color.red;
Gizmos.DrawLine(hitEnd, clearEnd); Gizmos.DrawLine(hitEnd, clearEnd);
} }

View File

@ -3,15 +3,13 @@ using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
public class SkeletonUtilityKinematicShadow : MonoBehaviour { public class SkeletonUtilityKinematicShadow : MonoBehaviour {
public bool hideShadow = true; public bool hideShadow = true;
Dictionary<Transform, Transform> shadowTable; Dictionary<Transform, Transform> shadowTable;
GameObject shadowRoot; GameObject shadowRoot;
void Start(){ void Start () {
shadowRoot = (GameObject)Instantiate(gameObject); shadowRoot = (GameObject)Instantiate(gameObject);
if(hideShadow) if (hideShadow)
shadowRoot.hideFlags = HideFlags.HideInHierarchy; shadowRoot.hideFlags = HideFlags.HideInHierarchy;
shadowRoot.transform.parent = transform.root; shadowRoot.transform.parent = transform.root;
@ -28,20 +26,20 @@ public class SkeletonUtilityKinematicShadow : MonoBehaviour {
shadowRoot.transform.localScale = Vector3.one; shadowRoot.transform.localScale = Vector3.one;
var shadowJoints = shadowRoot.GetComponentsInChildren<Joint>(); var shadowJoints = shadowRoot.GetComponentsInChildren<Joint>();
foreach(Joint j in shadowJoints){ foreach (Joint j in shadowJoints) {
j.connectedAnchor *= scale; j.connectedAnchor *= scale;
} }
var joints = GetComponentsInChildren<Joint>(); var joints = GetComponentsInChildren<Joint>();
foreach(var j in joints) foreach (var j in joints)
Destroy(j); Destroy(j);
var rbs = GetComponentsInChildren<Rigidbody>(); var rbs = GetComponentsInChildren<Rigidbody>();
foreach(var rb in rbs) foreach (var rb in rbs)
Destroy(rb); Destroy(rb);
var colliders = GetComponentsInChildren<Collider>(); var colliders = GetComponentsInChildren<Collider>();
foreach(var c in colliders) foreach (var c in colliders)
Destroy(c); Destroy(c);
@ -50,30 +48,30 @@ public class SkeletonUtilityKinematicShadow : MonoBehaviour {
var bones = GetComponentsInChildren<SkeletonUtilityBone>(); var bones = GetComponentsInChildren<SkeletonUtilityBone>();
//build bone lookup //build bone lookup
foreach(var b in bones){ foreach (var b in bones) {
if(b.gameObject == gameObject) if (b.gameObject == gameObject)
continue; continue;
foreach(var sb in shadowBones){ foreach (var sb in shadowBones) {
if(sb.rigidbody == null) if (sb.rigidbody == null)
continue; continue;
if(sb.boneName == b.boneName){ if (sb.boneName == b.boneName) {
shadowTable.Add( sb.transform, b.transform ); shadowTable.Add(sb.transform, b.transform);
break; break;
} }
} }
} }
foreach(var b in shadowBones) foreach (var b in shadowBones)
Destroy(b); Destroy(b);
} }
void FixedUpdate(){ void FixedUpdate () {
shadowRoot.rigidbody.MovePosition( transform.position ); shadowRoot.rigidbody.MovePosition(transform.position);
shadowRoot.rigidbody.MoveRotation( transform.rotation ); shadowRoot.rigidbody.MoveRotation(transform.rotation);
foreach(var pair in shadowTable){ foreach (var pair in shadowTable) {
pair.Value.localPosition = pair.Key.localPosition; pair.Value.localPosition = pair.Key.localPosition;
pair.Value.localRotation = pair.Key.localRotation; pair.Value.localRotation = pair.Key.localRotation;
} }

View File

@ -3,46 +3,42 @@ using System.Collections;
[ExecuteInEditMode] [ExecuteInEditMode]
public class SkeletonUtilitySubmeshRenderer : MonoBehaviour { public class SkeletonUtilitySubmeshRenderer : MonoBehaviour {
public Renderer parentRenderer; public Renderer parentRenderer;
[System.NonSerialized] [System.NonSerialized]
public Mesh mesh; public Mesh mesh;
public int submeshIndex = 0; public int submeshIndex = 0;
public int sortingOrder = 0; public int sortingOrder = 0;
public int sortingLayerID = 0; public int sortingLayerID = 0;
public Material hiddenPassMaterial; public Material hiddenPassMaterial;
Renderer cachedRenderer; Renderer cachedRenderer;
MeshFilter filter; MeshFilter filter;
Material[] sharedMaterials; Material[] sharedMaterials;
MeshFilter parentFilter; MeshFilter parentFilter;
void Awake(){ void Awake () {
cachedRenderer = renderer; cachedRenderer = renderer;
sharedMaterials = cachedRenderer.sharedMaterials; sharedMaterials = cachedRenderer.sharedMaterials;
filter = GetComponent<MeshFilter>(); filter = GetComponent<MeshFilter>();
if(parentRenderer != null) if (parentRenderer != null)
Initialize( parentRenderer ); Initialize(parentRenderer);
} }
void OnEnable(){ void OnEnable () {
parentRenderer = transform.parent.GetComponent<Renderer>(); parentRenderer = transform.parent.GetComponent<Renderer>();
parentRenderer.GetComponent<SkeletonRenderer>().OnReset += HandleSkeletonReset; parentRenderer.GetComponent<SkeletonRenderer>().OnReset += HandleSkeletonReset;
} }
void OnDisable(){ void OnDisable () {
parentRenderer.GetComponent<SkeletonRenderer>().OnReset -= HandleSkeletonReset; parentRenderer.GetComponent<SkeletonRenderer>().OnReset -= HandleSkeletonReset;
} }
void HandleSkeletonReset(SkeletonRenderer r){ void HandleSkeletonReset (SkeletonRenderer r) {
if(parentRenderer != null) if (parentRenderer != null)
Initialize(parentRenderer); Initialize(parentRenderer);
} }
public void Initialize(Renderer parentRenderer){ public void Initialize (Renderer parentRenderer) {
this.parentRenderer = parentRenderer; this.parentRenderer = parentRenderer;
parentFilter = parentRenderer.GetComponent<MeshFilter>(); parentFilter = parentRenderer.GetComponent<MeshFilter>();
mesh = parentFilter.sharedMesh; mesh = parentFilter.sharedMesh;
@ -50,52 +46,50 @@ public class SkeletonUtilitySubmeshRenderer : MonoBehaviour {
Debug.Log("Mesh: " + mesh); Debug.Log("Mesh: " + mesh);
} }
public void Update(){ public void Update () {
if(mesh == null || mesh != parentFilter.sharedMesh){ if (mesh == null || mesh != parentFilter.sharedMesh) {
mesh = parentFilter.sharedMesh; mesh = parentFilter.sharedMesh;
filter.sharedMesh = mesh; filter.sharedMesh = mesh;
} }
if(cachedRenderer == null) if (cachedRenderer == null)
cachedRenderer = renderer; cachedRenderer = renderer;
if(mesh == null || submeshIndex > mesh.subMeshCount - 1){ if (mesh == null || submeshIndex > mesh.subMeshCount - 1) {
cachedRenderer.enabled = false; cachedRenderer.enabled = false;
return; return;
} } else {
else{
renderer.enabled = true; renderer.enabled = true;
} }
bool changed = false; bool changed = false;
if(sharedMaterials.Length != parentRenderer.sharedMaterials.Length){ if (sharedMaterials.Length != parentRenderer.sharedMaterials.Length) {
sharedMaterials = parentRenderer.sharedMaterials; sharedMaterials = parentRenderer.sharedMaterials;
changed = true; changed = true;
} }
for(int i = 0; i < renderer.sharedMaterials.Length; i++){ for (int i = 0; i < renderer.sharedMaterials.Length; i++) {
if(i == submeshIndex) if (i == submeshIndex)
continue; continue;
if(sharedMaterials[i] != hiddenPassMaterial){ if (sharedMaterials[i] != hiddenPassMaterial) {
sharedMaterials[i] = hiddenPassMaterial; sharedMaterials[i] = hiddenPassMaterial;
changed = true; changed = true;
} }
} }
if(sharedMaterials[submeshIndex] != parentRenderer.sharedMaterials[submeshIndex]){ if (sharedMaterials[submeshIndex] != parentRenderer.sharedMaterials[submeshIndex]) {
sharedMaterials[submeshIndex] = parentRenderer.sharedMaterials[submeshIndex]; sharedMaterials[submeshIndex] = parentRenderer.sharedMaterials[submeshIndex];
changed = true; changed = true;
} }
if(changed){ if (changed) {
cachedRenderer.sharedMaterials = sharedMaterials; cachedRenderer.sharedMaterials = sharedMaterials;
} }
cachedRenderer.sortingLayerID = sortingLayerID; cachedRenderer.sortingLayerID = sortingLayerID;
cachedRenderer.sortingOrder = sortingOrder; cachedRenderer.sortingOrder = sortingOrder;
} }

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<PolicySet name="Spine">
<TextStylePolicy inheritsSet="Mono" inheritsScope="text/plain" scope="text/x-csharp">
<FileWidth>130</FileWidth>
<TabWidth>3</TabWidth>
<IndentWidth>3</IndentWidth>
</TextStylePolicy>
<CSharpFormattingPolicy inheritsSet="Mono" inheritsScope="text/x-csharp" scope="text/x-csharp">
<IndentNamespaceBody>False</IndentNamespaceBody>
<AlignEmbeddedUsingStatements>False</AlignEmbeddedUsingStatements>
<AlignEmbeddedIfStatements>False</AlignEmbeddedIfStatements>
<NamespaceBraceStyle>EndOfLine</NamespaceBraceStyle>
<ClassBraceStyle>EndOfLine</ClassBraceStyle>
<InterfaceBraceStyle>EndOfLine</InterfaceBraceStyle>
<StructBraceStyle>EndOfLine</StructBraceStyle>
<EnumBraceStyle>EndOfLine</EnumBraceStyle>
<MethodBraceStyle>EndOfLine</MethodBraceStyle>
<ConstructorBraceStyle>EndOfLine</ConstructorBraceStyle>
<DestructorBraceStyle>EndOfLine</DestructorBraceStyle>
<ElseIfNewLinePlacement>SameLine</ElseIfNewLinePlacement>
<BeforeMethodCallParentheses>False</BeforeMethodCallParentheses>
<AfterDelegateDeclarationParameterComma>True</AfterDelegateDeclarationParameterComma>
<NewParentheses>False</NewParentheses>
<SpacesBeforeBrackets>False</SpacesBeforeBrackets>
<BlankLinesBeforeUsings>1</BlankLinesBeforeUsings>
<BlankLinesBeforeFirstDeclaration>1</BlankLinesBeforeFirstDeclaration>
</CSharpFormattingPolicy>
</PolicySet>