SkeletonUtility initial commit
@ -36,8 +36,9 @@ using Spine;
|
||||
|
||||
/// <summary>Sets a GameObject's transform to match a bone on a Spine skeleton.</summary>
|
||||
[ExecuteInEditMode]
|
||||
[AddComponentMenu("Spine/BoneComponent")]
|
||||
public class BoneComponent : MonoBehaviour {
|
||||
[AddComponentMenu("Spine/BoneFollower")]
|
||||
public class BoneFollower : MonoBehaviour {
|
||||
|
||||
[System.NonSerialized]
|
||||
public bool valid;
|
||||
|
||||
@ -55,31 +56,50 @@ public class BoneComponent : MonoBehaviour {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Make the rotation behavior more customizable
|
||||
// public bool followTransformRotation = false;
|
||||
|
||||
// TODO: Make transform follow bone scale? too specific? This is really useful for shared shadow assets.
|
||||
//public bool followBoneScale = false;
|
||||
|
||||
/// <summary>If a bone isn't set, boneName is used to find the bone.</summary>
|
||||
public String boneName;
|
||||
|
||||
public bool resetOnAwake = true;
|
||||
|
||||
protected Transform cachedTransform;
|
||||
protected Transform skeletonTransform;
|
||||
|
||||
|
||||
public void HandleResetRenderer(SkeletonRenderer skeletonRenderer){
|
||||
Reset();
|
||||
}
|
||||
|
||||
public void Reset () {
|
||||
bone = null;
|
||||
cachedTransform = transform;
|
||||
valid = skeletonRenderer != null && skeletonRenderer.valid;
|
||||
if (!valid) return;
|
||||
skeletonTransform = skeletonRenderer.transform;
|
||||
|
||||
skeletonRenderer.OnReset -= HandleResetRenderer;
|
||||
skeletonRenderer.OnReset += HandleResetRenderer;
|
||||
|
||||
if(Application.isEditor)
|
||||
DoUpdate();
|
||||
}
|
||||
|
||||
void OnDestroy(){
|
||||
//cleanup
|
||||
if(skeletonRenderer != null)
|
||||
skeletonRenderer.OnReset -= HandleResetRenderer;
|
||||
}
|
||||
|
||||
public void Awake () {
|
||||
Reset();
|
||||
if(resetOnAwake)
|
||||
Reset();
|
||||
}
|
||||
|
||||
public void LateUpdate () {
|
||||
void LateUpdate(){
|
||||
DoUpdate();
|
||||
}
|
||||
|
||||
|
||||
public void DoUpdate () {
|
||||
if (!valid) {
|
||||
Reset();
|
||||
return;
|
||||
@ -92,6 +112,9 @@ public class BoneComponent : MonoBehaviour {
|
||||
Debug.LogError("Bone not found: " + boneName, this);
|
||||
return;
|
||||
}
|
||||
else{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Spine.Skeleton skeleton = skeletonRenderer.skeleton;
|
||||
@ -113,9 +136,10 @@ public class BoneComponent : MonoBehaviour {
|
||||
|
||||
if(followBoneRotation) {
|
||||
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) );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 487b42efe96d8cc408a757541ea3f169
|
||||
guid: a1fd8daaed7b64148a34acb96ba14ce1
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
106
spine-unity/Assets/spine-unity/Editor/BoneFollowerInspector.cs
Normal file
@ -0,0 +1,106 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License
|
||||
* Version 2.1
|
||||
*
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable and
|
||||
* non-transferable license to install, execute and perform the Spine Runtimes
|
||||
* Software (the "Software") solely for internal use. Without the written
|
||||
* permission of Esoteric Software (typically granted by licensing Spine), you
|
||||
* may not (a) modify, translate, adapt or otherwise create derivative works,
|
||||
* improvements of the Software or develop new applications using the Software
|
||||
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
|
||||
* trademark, patent or other intellectual property or proprietary rights
|
||||
* notices on or in the Software, including any copy thereof. Redistributions
|
||||
* in binary or source form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
[CustomEditor(typeof(BoneFollower))]
|
||||
public class BoneFollowerInspector : Editor {
|
||||
private SerializedProperty boneName, skeletonRenderer, followZPosition, followBoneRotation;
|
||||
BoneFollower component;
|
||||
void OnEnable () {
|
||||
skeletonRenderer = serializedObject.FindProperty("skeletonRenderer");
|
||||
boneName = serializedObject.FindProperty("boneName");
|
||||
followBoneRotation = serializedObject.FindProperty("followBoneRotation");
|
||||
followZPosition = serializedObject.FindProperty("followZPosition");
|
||||
component = (BoneFollower)target;
|
||||
ForceReload();
|
||||
}
|
||||
|
||||
void FindRenderer(){
|
||||
if(skeletonRenderer.objectReferenceValue == null){
|
||||
SkeletonRenderer parentRenderer = component.GetComponentInParent<SkeletonRenderer>();
|
||||
if(parentRenderer != null){
|
||||
skeletonRenderer.objectReferenceValue = (UnityEngine.Object)parentRenderer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ForceReload(){
|
||||
if(component.skeletonRenderer != null){
|
||||
if(component.skeletonRenderer.valid == false)
|
||||
component.skeletonRenderer.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
override public void OnInspectorGUI () {
|
||||
serializedObject.Update();
|
||||
|
||||
FindRenderer();
|
||||
|
||||
EditorGUILayout.PropertyField(skeletonRenderer);
|
||||
|
||||
if (component.valid) {
|
||||
String[] bones = new String[1];
|
||||
try{
|
||||
bones = new String[component.skeletonRenderer.skeleton.Data.Bones.Count + 1];
|
||||
}
|
||||
catch{
|
||||
|
||||
}
|
||||
|
||||
bones[0] = "<None>";
|
||||
for (int i = 0; i < bones.Length - 1; i++)
|
||||
bones[i + 1] = component.skeletonRenderer.skeleton.Data.Bones[i].Name;
|
||||
Array.Sort<String>(bones);
|
||||
int boneIndex = Math.Max(0, Array.IndexOf(bones, boneName.stringValue));
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("Bone");
|
||||
EditorGUIUtility.LookLikeControls();
|
||||
boneIndex = EditorGUILayout.Popup(boneIndex, bones);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
boneName.stringValue = boneIndex == 0 ? null : bones[boneIndex];
|
||||
EditorGUILayout.PropertyField(followBoneRotation);
|
||||
EditorGUILayout.PropertyField(followZPosition);
|
||||
}
|
||||
else{
|
||||
GUILayout.Label("INVALID");
|
||||
}
|
||||
|
||||
if (serializedObject.ApplyModifiedProperties() ||
|
||||
(Event.current.type == EventType.ValidateCommand && Event.current.commandName == "UndoRedoPerformed")
|
||||
) {
|
||||
component.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c71ca35fd6241cb49a0b0756a664fcf7
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@ -1,6 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 52b12ec801461494185a4d3dc66f3d1d
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 2
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3d1be4ea889f3a14b864352fe49a1bde
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 2
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
|
||||
BIN
spine-unity/Assets/spine-unity/Editor/GUI/icon-bone.png
Normal file
|
After Width: | Height: | Size: 515 B |
47
spine-unity/Assets/spine-unity/Editor/GUI/icon-bone.png.meta
Normal file
@ -0,0 +1,47 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8322793223a533a4ca8be6f430256dfc
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 2
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
linearTexture: 1
|
||||
correctGamma: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: .25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -3
|
||||
maxTextureSize: 1024
|
||||
textureSettings:
|
||||
filterMode: -1
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapMode: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: .5, y: .5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaIsTransparency: 1
|
||||
textureType: 2
|
||||
buildTargetSettings: []
|
||||
spriteSheet:
|
||||
sprites: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
BIN
spine-unity/Assets/spine-unity/Editor/GUI/icon-boneNib.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
@ -0,0 +1,47 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 97a43f11e00735147a9dc3dff6d68191
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 2
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
linearTexture: 1
|
||||
correctGamma: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: .25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -3
|
||||
maxTextureSize: 1024
|
||||
textureSettings:
|
||||
filterMode: -1
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapMode: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: .5, y: .5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaIsTransparency: 1
|
||||
textureType: 2
|
||||
buildTargetSettings: []
|
||||
spriteSheet:
|
||||
sprites: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
BIN
spine-unity/Assets/spine-unity/Editor/GUI/icon-boundingBox.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
@ -0,0 +1,47 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 955aed20030d0504b8a9c6934a5cb47a
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 2
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
linearTexture: 1
|
||||
correctGamma: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: .25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -1
|
||||
maxTextureSize: 1024
|
||||
textureSettings:
|
||||
filterMode: -1
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapMode: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: .5, y: .5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaIsTransparency: 1
|
||||
textureType: 2
|
||||
buildTargetSettings: []
|
||||
spriteSheet:
|
||||
sprites: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
BIN
spine-unity/Assets/spine-unity/Editor/GUI/icon-constraintNib.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
@ -0,0 +1,47 @@
|
||||
fileFormatVersion: 2
|
||||
guid: de1a4f5ad4bdf1a4ea072c4d59ba87d8
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 2
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
linearTexture: 1
|
||||
correctGamma: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: .25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -3
|
||||
maxTextureSize: 1024
|
||||
textureSettings:
|
||||
filterMode: -1
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapMode: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: .5, y: .5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaIsTransparency: 1
|
||||
textureType: 2
|
||||
buildTargetSettings: []
|
||||
spriteSheet:
|
||||
sprites: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
@ -1,6 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d226a80acc775714aa78b85e16a00e9b
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 2
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
|
||||
BIN
spine-unity/Assets/spine-unity/Editor/GUI/icon-hingeChain.png
Normal file
|
After Width: | Height: | Size: 757 B |
@ -0,0 +1,47 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2c2c6d283dcf3654baf40001c982891c
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 2
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
linearTexture: 0
|
||||
correctGamma: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: .25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -1
|
||||
maxTextureSize: 1024
|
||||
textureSettings:
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -1
|
||||
wrapMode: -1
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: .5, y: .5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaIsTransparency: 0
|
||||
textureType: -1
|
||||
buildTargetSettings: []
|
||||
spriteSheet:
|
||||
sprites: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
BIN
spine-unity/Assets/spine-unity/Editor/GUI/icon-image.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
@ -0,0 +1,47 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2b3a6f35bbaa8414eb51a344743ee641
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 2
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
linearTexture: 1
|
||||
correctGamma: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: .25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -3
|
||||
maxTextureSize: 1024
|
||||
textureSettings:
|
||||
filterMode: -1
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapMode: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: .5, y: .5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaIsTransparency: 1
|
||||
textureType: 2
|
||||
buildTargetSettings: []
|
||||
spriteSheet:
|
||||
sprites: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
BIN
spine-unity/Assets/spine-unity/Editor/GUI/icon-mesh.png
Normal file
|
After Width: | Height: | Size: 603 B |
47
spine-unity/Assets/spine-unity/Editor/GUI/icon-mesh.png.meta
Normal file
@ -0,0 +1,47 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a309a2e14638a204091b915126910f45
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 2
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
linearTexture: 1
|
||||
correctGamma: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: .25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -1
|
||||
maxTextureSize: 1024
|
||||
textureSettings:
|
||||
filterMode: -1
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapMode: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: .5, y: .5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaIsTransparency: 1
|
||||
textureType: 2
|
||||
buildTargetSettings: []
|
||||
spriteSheet:
|
||||
sprites: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
BIN
spine-unity/Assets/spine-unity/Editor/GUI/icon-null.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
47
spine-unity/Assets/spine-unity/Editor/GUI/icon-null.png.meta
Normal file
@ -0,0 +1,47 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d1de1604dfe4cb64c9d31246a8e43c78
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 2
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
linearTexture: 1
|
||||
correctGamma: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: .25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -3
|
||||
maxTextureSize: 1024
|
||||
textureSettings:
|
||||
filterMode: -1
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapMode: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: .5, y: .5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaIsTransparency: 1
|
||||
textureType: 2
|
||||
buildTargetSettings: []
|
||||
spriteSheet:
|
||||
sprites: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
BIN
spine-unity/Assets/spine-unity/Editor/GUI/icon-poseBones.png
Normal file
|
After Width: | Height: | Size: 555 B |
@ -0,0 +1,47 @@
|
||||
fileFormatVersion: 2
|
||||
guid: da6f6d414e43aac46a57cc5a87208db4
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 2
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
linearTexture: 1
|
||||
correctGamma: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: .25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -3
|
||||
maxTextureSize: 1024
|
||||
textureSettings:
|
||||
filterMode: -1
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapMode: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: .5, y: .5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaIsTransparency: 1
|
||||
textureType: 2
|
||||
buildTargetSettings: []
|
||||
spriteSheet:
|
||||
sprites: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
@ -1,6 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f2216037084d99d4481810cb521ed96f
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 2
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@ -0,0 +1,47 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5bb0631368b462047869d8788673cb48
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 2
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
linearTexture: 1
|
||||
correctGamma: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: .25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -3
|
||||
maxTextureSize: 1024
|
||||
textureSettings:
|
||||
filterMode: -1
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapMode: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: .5, y: .5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaIsTransparency: 1
|
||||
textureType: 2
|
||||
buildTargetSettings: []
|
||||
spriteSheet:
|
||||
sprites: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
BIN
spine-unity/Assets/spine-unity/Editor/GUI/icon-skin.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
47
spine-unity/Assets/spine-unity/Editor/GUI/icon-skin.png.meta
Normal file
@ -0,0 +1,47 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bfd9f3d2607e9e44c97384d7575a17dc
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 2
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
linearTexture: 1
|
||||
correctGamma: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: .25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -3
|
||||
maxTextureSize: 1024
|
||||
textureSettings:
|
||||
filterMode: -1
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapMode: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: .5, y: .5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaIsTransparency: 1
|
||||
textureType: 2
|
||||
buildTargetSettings: []
|
||||
spriteSheet:
|
||||
sprites: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
|
After Width: | Height: | Size: 3.3 KiB |
@ -0,0 +1,47 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 04c82a4acf7b5244e947f2709ec3a6cf
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 2
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
linearTexture: 1
|
||||
correctGamma: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: .25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -3
|
||||
maxTextureSize: 1024
|
||||
textureSettings:
|
||||
filterMode: -1
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapMode: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: .5, y: .5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaIsTransparency: 1
|
||||
textureType: 2
|
||||
buildTargetSettings: []
|
||||
spriteSheet:
|
||||
sprites: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
@ -1,6 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8bd14c7643597a74ba2edc10a5e4c4ed
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 2
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
|
||||
BIN
spine-unity/Assets/spine-unity/Editor/GUI/icon-slot.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
47
spine-unity/Assets/spine-unity/Editor/GUI/icon-slot.png.meta
Normal file
@ -0,0 +1,47 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0338faf3e7d93e2478fcbc022d13e081
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 2
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
linearTexture: 1
|
||||
correctGamma: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: .25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -3
|
||||
maxTextureSize: 1024
|
||||
textureSettings:
|
||||
filterMode: -1
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapMode: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: .5, y: .5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaIsTransparency: 1
|
||||
textureType: 2
|
||||
buildTargetSettings: []
|
||||
spriteSheet:
|
||||
sprites: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
@ -1,6 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4e7c964fa5e07024c8bf1debecc3b7c8
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 2
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
|
||||
|
After Width: | Height: | Size: 3.5 KiB |
@ -0,0 +1,47 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f31c0c0d608e8ba4f9a1afb032092287
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 2
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
linearTexture: 0
|
||||
correctGamma: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: .25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -1
|
||||
maxTextureSize: 1024
|
||||
textureSettings:
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -1
|
||||
wrapMode: -1
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: .5, y: .5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaIsTransparency: 0
|
||||
textureType: -1
|
||||
buildTargetSettings: []
|
||||
spriteSheet:
|
||||
sprites: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
BIN
spine-unity/Assets/spine-unity/Editor/GUI/icon-warning.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
@ -0,0 +1,47 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 754d724c1bd750048852e8cf3d4a05ee
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 2
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
linearTexture: 1
|
||||
correctGamma: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: .25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -3
|
||||
maxTextureSize: 1024
|
||||
textureSettings:
|
||||
filterMode: -1
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapMode: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: .5, y: .5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaIsTransparency: 1
|
||||
textureType: 2
|
||||
buildTargetSettings: []
|
||||
spriteSheet:
|
||||
sprites: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
@ -31,16 +31,23 @@
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using Spine;
|
||||
|
||||
[CustomEditor(typeof(SkeletonAnimation))]
|
||||
public class SkeletonAnimationInspector : SkeletonRendererInspector {
|
||||
protected SerializedProperty animationName, loop, timeScale;
|
||||
protected bool isPrefab;
|
||||
|
||||
protected override void OnEnable () {
|
||||
base.OnEnable();
|
||||
animationName = serializedObject.FindProperty("_animationName");
|
||||
loop = serializedObject.FindProperty("loop");
|
||||
timeScale = serializedObject.FindProperty("timeScale");
|
||||
|
||||
if(PrefabUtility.GetPrefabType(this.target) == PrefabType.Prefab)
|
||||
isPrefab = true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
protected override void gui () {
|
||||
@ -49,6 +56,25 @@ public class SkeletonAnimationInspector : SkeletonRendererInspector {
|
||||
SkeletonAnimation component = (SkeletonAnimation)target;
|
||||
if (!component.valid) return;
|
||||
|
||||
//catch case where SetAnimation was used to set track 0 without using AnimationName
|
||||
if(Application.isPlaying){
|
||||
TrackEntry currentState = component.state.GetCurrent(0);
|
||||
if(currentState != null){
|
||||
if(component.AnimationName != animationName.stringValue){
|
||||
animationName.stringValue = currentState.Animation.Name;
|
||||
}
|
||||
|
||||
if(loop.boolValue != currentState.Loop){
|
||||
loop.boolValue = currentState.Loop;
|
||||
}
|
||||
|
||||
if(timeScale.floatValue != currentState.TimeScale){
|
||||
timeScale.floatValue = currentState.TimeScale;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Animation name.
|
||||
{
|
||||
String[] animations = new String[component.skeleton.Data.Animations.Count + 1];
|
||||
@ -69,10 +95,21 @@ public class SkeletonAnimationInspector : SkeletonRendererInspector {
|
||||
String selectedAnimationName = animationIndex == 0 ? null : animations[animationIndex];
|
||||
component.AnimationName = selectedAnimationName;
|
||||
animationName.stringValue = selectedAnimationName;
|
||||
|
||||
|
||||
}
|
||||
|
||||
EditorGUILayout.PropertyField(loop);
|
||||
EditorGUILayout.PropertyField(timeScale);
|
||||
component.timeScale = Math.Max(component.timeScale, 0);
|
||||
EditorGUILayout.Space();
|
||||
|
||||
if(!isPrefab){
|
||||
if(component.GetComponent<SkeletonUtility>() == null){
|
||||
if(GUILayout.Button(new GUIContent("Add Skeleton Utility", SpineEditorUtilities.Icons.skeletonUtility), GUILayout.Height(30))){
|
||||
component.gameObject.AddComponent<SkeletonUtility>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,6 +28,11 @@
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Automatic import and advanced preview added by Mitch Thompson
|
||||
* Full irrevocable rights and permissions granted to Esoteric Software
|
||||
*****************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
@ -53,18 +58,26 @@ public class SkeletonDataAssetInspector : Editor {
|
||||
private string m_skeletonDataAssetGUID;
|
||||
|
||||
void OnEnable () {
|
||||
atlasAsset = serializedObject.FindProperty("atlasAsset");
|
||||
skeletonJSON = serializedObject.FindProperty("skeletonJSON");
|
||||
scale = serializedObject.FindProperty("scale");
|
||||
fromAnimation = serializedObject.FindProperty("fromAnimation");
|
||||
toAnimation = serializedObject.FindProperty("toAnimation");
|
||||
duration = serializedObject.FindProperty("duration");
|
||||
defaultMix = serializedObject.FindProperty("defaultMix");
|
||||
|
||||
m_skeletonDataAsset = (SkeletonDataAsset)target;
|
||||
m_skeletonDataAssetGUID = AssetDatabase.AssetPathToGUID( AssetDatabase.GetAssetPath(m_skeletonDataAsset) );
|
||||
|
||||
EditorApplication.update += Update;
|
||||
try{
|
||||
|
||||
atlasAsset = serializedObject.FindProperty("atlasAsset");
|
||||
skeletonJSON = serializedObject.FindProperty("skeletonJSON");
|
||||
scale = serializedObject.FindProperty("scale");
|
||||
fromAnimation = serializedObject.FindProperty("fromAnimation");
|
||||
toAnimation = serializedObject.FindProperty("toAnimation");
|
||||
duration = serializedObject.FindProperty("duration");
|
||||
defaultMix = serializedObject.FindProperty("defaultMix");
|
||||
|
||||
m_skeletonDataAsset = (SkeletonDataAsset)target;
|
||||
m_skeletonDataAssetGUID = AssetDatabase.AssetPathToGUID( AssetDatabase.GetAssetPath(m_skeletonDataAsset) );
|
||||
|
||||
EditorApplication.update += Update;
|
||||
|
||||
}
|
||||
catch{
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void OnDestroy(){
|
||||
|
||||
@ -1,4 +1,38 @@
|
||||
#pragma warning disable 0219
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License
|
||||
* Version 2.1
|
||||
*
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable and
|
||||
* non-transferable license to install, execute and perform the Spine Runtimes
|
||||
* Software (the "Software") solely for internal use. Without the written
|
||||
* permission of Esoteric Software (typically granted by licensing Spine), you
|
||||
* may not (a) modify, translate, adapt or otherwise create derivative works,
|
||||
* improvements of the Software or develop new applications using the Software
|
||||
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
|
||||
* trademark, patent or other intellectual property or proprietary rights
|
||||
* notices on or in the Software, including any copy thereof. Redistributions
|
||||
* in binary or source form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Spine Editor Utilities created by Mitch Thompson
|
||||
* Full irrevocable rights and permissions granted to Esoteric Software
|
||||
*****************************************************************************/
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
@ -15,6 +49,7 @@ public class SpineEditorUtilities : AssetPostprocessor {
|
||||
public static Texture2D skeleton;
|
||||
public static Texture2D nullBone;
|
||||
public static Texture2D bone;
|
||||
public static Texture2D poseBones;
|
||||
public static Texture2D boneNib;
|
||||
public static Texture2D slot;
|
||||
public static Texture2D skinPlaceholder;
|
||||
@ -27,6 +62,11 @@ public class SpineEditorUtilities : AssetPostprocessor {
|
||||
public static Texture2D animationRoot;
|
||||
public static Texture2D spine;
|
||||
public static Texture2D _event;
|
||||
public static Texture2D constraintNib;
|
||||
public static Texture2D warning;
|
||||
public static Texture2D skeletonUtility;
|
||||
public static Texture2D hingeChain;
|
||||
public static Texture2D subMeshRenderer;
|
||||
|
||||
public static Mesh boneMesh{
|
||||
get{
|
||||
@ -61,6 +101,7 @@ public class SpineEditorUtilities : AssetPostprocessor {
|
||||
skeleton = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-skeleton.png");
|
||||
nullBone = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-null.png");
|
||||
bone = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-bone.png");
|
||||
poseBones = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-poseBones.png");
|
||||
boneNib = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-boneNib.png");
|
||||
slot = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-slot.png");
|
||||
skinPlaceholder = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-skinPlaceholder.png");
|
||||
@ -73,6 +114,12 @@ public class SpineEditorUtilities : AssetPostprocessor {
|
||||
animationRoot = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-animationRoot.png");
|
||||
spine = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-spine.png");
|
||||
_event = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-event.png");
|
||||
constraintNib = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-constraintNib.png");
|
||||
warning = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-warning.png");
|
||||
skeletonUtility = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-skeletonUtility.png");
|
||||
hingeChain = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-hingeChain.png");
|
||||
subMeshRenderer = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-subMeshRenderer.png");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -81,8 +128,9 @@ public class SpineEditorUtilities : AssetPostprocessor {
|
||||
|
||||
public static string editorPath = "";
|
||||
public static string editorGUIPath = "";
|
||||
|
||||
static List<int> skeletonRendererInstanceIDs;
|
||||
|
||||
static Dictionary<int, GameObject> skeletonRendererTable;
|
||||
static Dictionary<int, SkeletonUtilityBone> skeletonUtilityBoneTable;
|
||||
|
||||
public static float defaultScale = 0.01f;
|
||||
public static float defaultMix = 0.2f;
|
||||
@ -96,7 +144,8 @@ public class SpineEditorUtilities : AssetPostprocessor {
|
||||
|
||||
Icons.Initialize();
|
||||
|
||||
skeletonRendererInstanceIDs = new List<int>();
|
||||
skeletonRendererTable = new Dictionary<int, GameObject>();
|
||||
skeletonUtilityBoneTable = new Dictionary<int, SkeletonUtilityBone>();
|
||||
|
||||
EditorApplication.hierarchyWindowChanged += HierarchyWindowChanged;
|
||||
EditorApplication.hierarchyWindowItemOnGUI += HierarchyWindowItemOnGUI;
|
||||
@ -105,22 +154,49 @@ public class SpineEditorUtilities : AssetPostprocessor {
|
||||
}
|
||||
|
||||
static void HierarchyWindowChanged(){
|
||||
skeletonRendererInstanceIDs.Clear();
|
||||
skeletonRendererTable.Clear();
|
||||
skeletonUtilityBoneTable.Clear();
|
||||
|
||||
SkeletonRenderer[] arr = Object.FindObjectsOfType<SkeletonRenderer>();
|
||||
|
||||
foreach(SkeletonRenderer r in arr)
|
||||
skeletonRendererInstanceIDs.Add(r.gameObject.GetInstanceID());
|
||||
skeletonRendererTable.Add( r.gameObject.GetInstanceID(), r.gameObject );
|
||||
|
||||
SkeletonUtilityBone[] boneArr = Object.FindObjectsOfType<SkeletonUtilityBone>();
|
||||
foreach(SkeletonUtilityBone b in boneArr)
|
||||
skeletonUtilityBoneTable.Add(b.gameObject.GetInstanceID(), b);
|
||||
}
|
||||
|
||||
static void HierarchyWindowItemOnGUI(int instanceId, Rect selectionRect){
|
||||
if(skeletonRendererInstanceIDs.Contains(instanceId)){
|
||||
if(skeletonRendererTable.ContainsKey(instanceId)){
|
||||
Rect r = new Rect (selectionRect);
|
||||
r.x = r.width - 15;
|
||||
r.width = 15;
|
||||
|
||||
GUI.Label(r, Icons.spine);
|
||||
}
|
||||
else if(skeletonUtilityBoneTable.ContainsKey(instanceId)){
|
||||
Rect r = new Rect (selectionRect);
|
||||
//r.x = r.width - 15;
|
||||
r.x -= 26;
|
||||
|
||||
if(skeletonUtilityBoneTable[instanceId] != null){
|
||||
if( skeletonUtilityBoneTable[instanceId].transform.childCount == 0 )
|
||||
r.x += 15;
|
||||
|
||||
|
||||
r.width = 15;
|
||||
|
||||
if( skeletonUtilityBoneTable[instanceId].mode == SkeletonUtilityBone.Mode.Follow ){
|
||||
GUI.Label(r, Icons.bone);
|
||||
}
|
||||
else{
|
||||
GUI.Label(r, Icons.poseBones);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[MenuItem("Assets/Spine/Ingest")]
|
||||
@ -335,20 +411,24 @@ public class SpineEditorUtilities : AssetPostprocessor {
|
||||
|
||||
string primaryName = Path.GetFileNameWithoutExtension(spineJson.name);
|
||||
string assetPath = Path.GetDirectoryName( AssetDatabase.GetAssetPath(spineJson));
|
||||
string filePath = assetPath + "/" + primaryName + "_SkeletonData.asset";
|
||||
|
||||
if(spineJson != null && atlasAsset != null){
|
||||
|
||||
SkeletonDataAsset skelDataAsset = SkeletonDataAsset.CreateInstance<SkeletonDataAsset>();
|
||||
skelDataAsset.atlasAsset = atlasAsset;
|
||||
skelDataAsset.skeletonJSON = spineJson;
|
||||
skelDataAsset.fromAnimation = new string[0];
|
||||
skelDataAsset.toAnimation = new string[0];
|
||||
skelDataAsset.duration = new float[0];
|
||||
skelDataAsset.defaultMix = defaultMix;
|
||||
skelDataAsset.scale = defaultScale;
|
||||
|
||||
AssetDatabase.CreateAsset(skelDataAsset, assetPath + "/" + primaryName + "_SkeletonData.asset");
|
||||
AssetDatabase.SaveAssets();
|
||||
SkeletonDataAsset skelDataAsset = (SkeletonDataAsset)AssetDatabase.LoadAssetAtPath(filePath, typeof(SkeletonDataAsset));
|
||||
if(skelDataAsset == null){
|
||||
skelDataAsset = SkeletonDataAsset.CreateInstance<SkeletonDataAsset>();
|
||||
skelDataAsset.atlasAsset = atlasAsset;
|
||||
skelDataAsset.skeletonJSON = spineJson;
|
||||
skelDataAsset.fromAnimation = new string[0];
|
||||
skelDataAsset.toAnimation = new string[0];
|
||||
skelDataAsset.duration = new float[0];
|
||||
skelDataAsset.defaultMix = defaultMix;
|
||||
skelDataAsset.scale = defaultScale;
|
||||
|
||||
AssetDatabase.CreateAsset(skelDataAsset, filePath);
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
|
||||
return skelDataAsset;
|
||||
}
|
||||
|
||||
69
spine-unity/Assets/spine-unity/Shaders/Bones.shader
Normal file
@ -0,0 +1,69 @@
|
||||
Shader "Spine/Bones" {
|
||||
Properties {
|
||||
_Color ("Color", Color) = (0.5,0.5,0.5,0.5)
|
||||
_MainTex ("Particle Texture", 2D) = "white" {}
|
||||
}
|
||||
|
||||
Category {
|
||||
Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }
|
||||
Blend SrcAlpha OneMinusSrcAlpha
|
||||
AlphaTest Greater .01
|
||||
ColorMask RGB
|
||||
|
||||
Lighting Off Cull Off ZTest Always ZWrite Off Fog { Mode Off }
|
||||
|
||||
SubShader {
|
||||
Pass {
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#pragma multi_compile_particles
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
sampler2D _MainTex;
|
||||
fixed4 _Color;
|
||||
|
||||
struct appdata_t {
|
||||
float4 vertex : POSITION;
|
||||
fixed4 color : COLOR;
|
||||
float2 texcoord : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct v2f {
|
||||
float4 vertex : SV_POSITION;
|
||||
fixed4 color : COLOR;
|
||||
float2 texcoord : TEXCOORD0;
|
||||
#ifdef SOFTPARTICLES_ON
|
||||
float4 projPos : TEXCOORD1;
|
||||
#endif
|
||||
};
|
||||
|
||||
float4 _MainTex_ST;
|
||||
|
||||
v2f vert (appdata_t v)
|
||||
{
|
||||
v2f o;
|
||||
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
|
||||
#ifdef SOFTPARTICLES_ON
|
||||
o.projPos = ComputeScreenPos (o.vertex);
|
||||
COMPUTE_EYEDEPTH(o.projPos.z);
|
||||
#endif
|
||||
o.color = v.color;
|
||||
o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex);
|
||||
return o;
|
||||
}
|
||||
|
||||
sampler2D_float _CameraDepthTexture;
|
||||
|
||||
|
||||
fixed4 frag (v2f i) : SV_Target
|
||||
{
|
||||
return 2.0f * i.color * _Color * tex2D(_MainTex, i.texcoord);
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
5
spine-unity/Assets/spine-unity/Shaders/Bones.shader.meta
Normal file
@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 66988de88a15abd4e8846c6805485f57
|
||||
ShaderImporter:
|
||||
defaultTextures: []
|
||||
userData:
|
||||
BIN
spine-unity/Assets/spine-unity/Shaders/HiddenPass.mat
Normal file
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 43227e5adadc6f24bb4bf74b92a56fb4
|
||||
NativeFormatImporter:
|
||||
userData:
|
||||
21
spine-unity/Assets/spine-unity/Shaders/HiddenPass.shader
Normal file
@ -0,0 +1,21 @@
|
||||
Shader "Spine/HiddenPass" {
|
||||
SubShader
|
||||
|
||||
{
|
||||
|
||||
Tags {"Queue" = "Geometry-1" }
|
||||
|
||||
Lighting Off
|
||||
|
||||
Pass
|
||||
|
||||
{
|
||||
|
||||
ZWrite Off
|
||||
|
||||
ColorMask 0
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 913475501bf19374c84390868a9d6d3d
|
||||
ShaderImporter:
|
||||
defaultTextures: []
|
||||
userData:
|
||||
@ -42,7 +42,9 @@ public class SkeletonAnimation : SkeletonRenderer {
|
||||
public Spine.AnimationState state;
|
||||
|
||||
public delegate void UpdateBonesDelegate(SkeletonAnimation skeleton);
|
||||
public UpdateBonesDelegate UpdateBones;
|
||||
public UpdateBonesDelegate UpdateLocal;
|
||||
public UpdateBonesDelegate UpdateWorld;
|
||||
public UpdateBonesDelegate UpdateComplete;
|
||||
|
||||
[SerializeField]
|
||||
private String _animationName;
|
||||
@ -83,7 +85,19 @@ public class SkeletonAnimation : SkeletonRenderer {
|
||||
skeleton.Update(deltaTime);
|
||||
state.Update(deltaTime);
|
||||
state.Apply(skeleton);
|
||||
if (UpdateBones != null) UpdateBones(this);
|
||||
|
||||
if (UpdateLocal != null)
|
||||
UpdateLocal(this);
|
||||
|
||||
skeleton.UpdateWorldTransform();
|
||||
|
||||
if (UpdateWorld != null){
|
||||
UpdateWorld(this);
|
||||
skeleton.UpdateWorldTransform();
|
||||
}
|
||||
|
||||
if (UpdateComplete != null){
|
||||
UpdateComplete(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,39 @@
|
||||
using UnityEngine;
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License
|
||||
* Version 2.1
|
||||
*
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable and
|
||||
* non-transferable license to install, execute and perform the Spine Runtimes
|
||||
* Software (the "Software") solely for internal use. Without the written
|
||||
* permission of Esoteric Software (typically granted by licensing Spine), you
|
||||
* may not (a) modify, translate, adapt or otherwise create derivative works,
|
||||
* improvements of the Software or develop new applications using the Software
|
||||
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
|
||||
* trademark, patent or other intellectual property or proprietary rights
|
||||
* notices on or in the Software, including any copy thereof. Redistributions
|
||||
* in binary or source form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Spine Extensions created by Mitch Thompson
|
||||
* Full irrevocable rights and permissions granted to Esoteric Software
|
||||
*****************************************************************************/
|
||||
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using Spine;
|
||||
|
||||
|
||||
@ -37,6 +37,10 @@ using Spine;
|
||||
/// <summary>Renders a skeleton.</summary>
|
||||
[ExecuteInEditMode, RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
|
||||
public class SkeletonRenderer : MonoBehaviour {
|
||||
|
||||
public delegate void SkeletonRendererDelegate(SkeletonRenderer skeletonRenderer);
|
||||
public SkeletonRendererDelegate OnReset;
|
||||
|
||||
[System.NonSerialized]
|
||||
public bool valid;
|
||||
[System.NonSerialized]
|
||||
@ -96,6 +100,7 @@ public class SkeletonRenderer : MonoBehaviour {
|
||||
skeleton = new Skeleton(skeletonData);
|
||||
if (initialSkinName != null && initialSkinName.Length > 0 && initialSkinName != "default")
|
||||
skeleton.SetSkin(initialSkinName);
|
||||
if(OnReset != null) OnReset(this);
|
||||
}
|
||||
|
||||
public void Awake () {
|
||||
@ -112,7 +117,6 @@ public class SkeletonRenderer : MonoBehaviour {
|
||||
|
||||
public virtual void LateUpdate () {
|
||||
if (!valid) return;
|
||||
|
||||
// Count vertices and submesh triangles.
|
||||
int vertexCount = 0;
|
||||
int submeshTriangleCount = 0, submeshFirstVertex = 0, submeshStartSlotIndex = 0;
|
||||
@ -122,7 +126,8 @@ public class SkeletonRenderer : MonoBehaviour {
|
||||
int drawOrderCount = drawOrder.Count;
|
||||
bool renderMeshes = this.renderMeshes;
|
||||
for (int i = 0; i < drawOrderCount; i++) {
|
||||
Attachment attachment = drawOrder[i].attachment;
|
||||
Slot slot = drawOrder[i];
|
||||
Attachment attachment = slot.attachment;
|
||||
|
||||
object rendererObject;
|
||||
int attachmentVertexCount, attachmentTriangleCount;
|
||||
@ -149,7 +154,7 @@ public class SkeletonRenderer : MonoBehaviour {
|
||||
|
||||
// Populate submesh when material changes.
|
||||
Material material = (Material)((AtlasRegion)rendererObject).page.rendererObject;
|
||||
if (lastMaterial != material && lastMaterial != null) {
|
||||
if ((lastMaterial != material && lastMaterial != null) || slot.Data.name[0] == '*') {
|
||||
AddSubmesh(lastMaterial, submeshStartSlotIndex, i, submeshTriangleCount, submeshFirstVertex, false);
|
||||
submeshTriangleCount = 0;
|
||||
submeshFirstVertex = vertexCount;
|
||||
|
||||
5
spine-unity/Assets/spine-unity/SkeletonUtility.meta
Normal file
@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f6e0caaafe294de48af468a6a9321473
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a751a9d1e3e26d64d997b66a781df8e9
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
@ -0,0 +1,287 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License
|
||||
* Version 2.1
|
||||
*
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable and
|
||||
* non-transferable license to install, execute and perform the Spine Runtimes
|
||||
* Software (the "Software") solely for internal use. Without the written
|
||||
* permission of Esoteric Software (typically granted by licensing Spine), you
|
||||
* may not (a) modify, translate, adapt or otherwise create derivative works,
|
||||
* improvements of the Software or develop new applications using the Software
|
||||
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
|
||||
* trademark, patent or other intellectual property or proprietary rights
|
||||
* notices on or in the Software, including any copy thereof. Redistributions
|
||||
* in binary or source form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Skeleton Utility created by Mitch Thompson
|
||||
* Full irrevocable rights and permissions granted to Esoteric Software
|
||||
*****************************************************************************/
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Spine;
|
||||
|
||||
[CustomEditor(typeof(SkeletonUtilityBone)), CanEditMultipleObjects]
|
||||
public class SkeletonUtilityBoneInspector : Editor {
|
||||
SerializedProperty mode, boneName, zPosition, position, rotation, scale, overrideAlpha, parentReference;
|
||||
|
||||
//multi selected flags
|
||||
bool containsFollows, containsOverrides, multiObject;
|
||||
|
||||
//single selected helpers
|
||||
SkeletonUtilityBone utilityBone;
|
||||
SkeletonUtility skeletonUtility;
|
||||
bool canCreateHingeChain = false;
|
||||
|
||||
void OnEnable(){
|
||||
mode = this.serializedObject.FindProperty("mode");
|
||||
boneName = this.serializedObject.FindProperty("boneName");
|
||||
zPosition = this.serializedObject.FindProperty("zPosition");
|
||||
position = this.serializedObject.FindProperty("position");
|
||||
rotation = this.serializedObject.FindProperty("rotation");
|
||||
scale = this.serializedObject.FindProperty("scale");
|
||||
overrideAlpha = this.serializedObject.FindProperty("overrideAlpha");
|
||||
parentReference = this.serializedObject.FindProperty("parentReference");
|
||||
|
||||
EvaluateFlags();
|
||||
|
||||
if(utilityBone.valid == false && skeletonUtility != null && skeletonUtility.skeletonRenderer != null){
|
||||
skeletonUtility.skeletonRenderer.Reset();
|
||||
}
|
||||
|
||||
canCreateHingeChain = CanCreateHingeChain();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Evaluates the flags.
|
||||
/// </summary>
|
||||
void EvaluateFlags(){
|
||||
utilityBone = (SkeletonUtilityBone)target;
|
||||
skeletonUtility = utilityBone.skeletonUtility;
|
||||
|
||||
if(Selection.objects.Length == 1){
|
||||
containsFollows = utilityBone.mode == SkeletonUtilityBone.Mode.Follow;
|
||||
containsOverrides = utilityBone.mode == SkeletonUtilityBone.Mode.Override;
|
||||
}
|
||||
else{
|
||||
int boneCount = 0;
|
||||
foreach(Object o in Selection.objects){
|
||||
if(o is GameObject){
|
||||
GameObject go = (GameObject)o;
|
||||
SkeletonUtilityBone sub = go.GetComponent<SkeletonUtilityBone>();
|
||||
if(sub != null){
|
||||
boneCount++;
|
||||
if(sub.mode == SkeletonUtilityBone.Mode.Follow)
|
||||
containsFollows = true;
|
||||
if(sub.mode == SkeletonUtilityBone.Mode.Override)
|
||||
containsOverrides = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(boneCount > 1)
|
||||
multiObject = true;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI ()
|
||||
{
|
||||
serializedObject.Update();
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.PropertyField(mode);
|
||||
if(EditorGUI.EndChangeCheck()){
|
||||
containsOverrides = mode.enumValueIndex == 1;
|
||||
containsFollows = mode.enumValueIndex == 0;
|
||||
}
|
||||
|
||||
EditorGUI.BeginDisabledGroup( multiObject );
|
||||
{
|
||||
string str = boneName.stringValue;
|
||||
if(str == "") str = "<None>";
|
||||
if(multiObject) str = "<Multiple>";
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
EditorGUILayout.PrefixLabel("Bone");
|
||||
|
||||
if(GUILayout.Button( str, EditorStyles.popup )){
|
||||
BoneSelectorContextMenu( str, ((SkeletonUtilityBone)target).skeletonUtility.skeletonRenderer.skeleton.Bones, "<None>", TargetBoneSelected );
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
EditorGUI.EndDisabledGroup();
|
||||
|
||||
EditorGUILayout.PropertyField(zPosition);
|
||||
EditorGUILayout.PropertyField(position);
|
||||
EditorGUILayout.PropertyField(rotation);
|
||||
EditorGUILayout.PropertyField(scale);
|
||||
|
||||
EditorGUI.BeginDisabledGroup( containsFollows );
|
||||
{
|
||||
EditorGUILayout.PropertyField(overrideAlpha);
|
||||
EditorGUILayout.PropertyField(parentReference);
|
||||
}
|
||||
EditorGUI.EndDisabledGroup();
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
{
|
||||
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)))
|
||||
BoneSelectorContextMenu( "", utilityBone.bone.Children, "<Recursively>", SpawnChildBoneSelected);
|
||||
}
|
||||
EditorGUI.EndDisabledGroup();
|
||||
|
||||
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)))
|
||||
SpawnOverride();
|
||||
}
|
||||
EditorGUI.EndDisabledGroup();
|
||||
|
||||
EditorGUI.BeginDisabledGroup( multiObject || !utilityBone.valid || !canCreateHingeChain );
|
||||
{
|
||||
if(GUILayout.Button(new GUIContent("Create Hinge Chain", SpineEditorUtilities.Icons.hingeChain), GUILayout.Width(150), GUILayout.Height(24)))
|
||||
CreateHingeChain();
|
||||
}
|
||||
EditorGUI.EndDisabledGroup();
|
||||
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
void BoneSelectorContextMenu(string current, List<Bone> bones, string topValue, GenericMenu.MenuFunction2 callback){
|
||||
GenericMenu menu = new GenericMenu();
|
||||
|
||||
if(topValue != "")
|
||||
menu.AddItem( new GUIContent(topValue), current == topValue, callback, null );
|
||||
|
||||
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.ShowAsContext();
|
||||
|
||||
}
|
||||
|
||||
|
||||
void TargetBoneSelected(object obj){
|
||||
if(obj == null){
|
||||
boneName.stringValue = "";
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
else{
|
||||
Bone bone = (Bone)obj;
|
||||
boneName.stringValue = bone.Data.Name;
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
utilityBone.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
void SpawnChildBoneSelected(object obj){
|
||||
if(obj == null){
|
||||
//add recursively
|
||||
foreach(var bone in utilityBone.bone.Children){
|
||||
GameObject go = skeletonUtility.SpawnBoneRecursively( bone, utilityBone.transform, utilityBone.mode, utilityBone.position, utilityBone.rotation, utilityBone.scale );
|
||||
SkeletonUtilityBone[] newUtilityBones = go.GetComponentsInChildren<SkeletonUtilityBone>();
|
||||
foreach(SkeletonUtilityBone utilBone in newUtilityBones)
|
||||
SkeletonUtilityInspector.AttachIcon(utilBone);
|
||||
}
|
||||
}
|
||||
else{
|
||||
Bone bone = (Bone)obj;
|
||||
GameObject go = skeletonUtility.SpawnBone( bone, utilityBone.transform, utilityBone.mode, utilityBone.position, utilityBone.rotation, utilityBone.scale );
|
||||
SkeletonUtilityInspector.AttachIcon(go.GetComponent<SkeletonUtilityBone>());
|
||||
Selection.activeGameObject = go;
|
||||
EditorGUIUtility.PingObject(go);
|
||||
}
|
||||
}
|
||||
|
||||
void SpawnOverride(){
|
||||
GameObject go = skeletonUtility.SpawnBone( utilityBone.bone, utilityBone.transform.parent, SkeletonUtilityBone.Mode.Override, utilityBone.position, utilityBone.rotation, utilityBone.scale);
|
||||
go.name = go.name + " [Override]";
|
||||
SkeletonUtilityInspector.AttachIcon(go.GetComponent<SkeletonUtilityBone>());
|
||||
Selection.activeGameObject = go;
|
||||
EditorGUIUtility.PingObject(go);
|
||||
}
|
||||
|
||||
bool CanCreateHingeChain(){
|
||||
if(utilityBone == null) return false;
|
||||
if(utilityBone.rigidbody != null) return false;
|
||||
if(utilityBone.bone != null && utilityBone.bone.Children.Count == 0) return false;
|
||||
|
||||
Rigidbody[] rigidbodies = utilityBone.GetComponentsInChildren<Rigidbody>();
|
||||
|
||||
if(rigidbodies.Length > 0) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CreateHingeChain(){
|
||||
var utilBoneArr = utilityBone.GetComponentsInChildren<SkeletonUtilityBone>();
|
||||
|
||||
foreach(var utilBone in utilBoneArr){
|
||||
AttachRigidbody(utilBone);
|
||||
}
|
||||
|
||||
utilityBone.rigidbody.isKinematic = true;
|
||||
|
||||
foreach(var utilBone in utilBoneArr){
|
||||
if(utilBone == utilityBone)
|
||||
continue;
|
||||
|
||||
utilBone.mode = SkeletonUtilityBone.Mode.Override;
|
||||
|
||||
HingeJoint joint = utilBone.gameObject.AddComponent<HingeJoint>();
|
||||
joint.axis = Vector3.forward;
|
||||
joint.connectedBody = utilBone.transform.parent.rigidbody;
|
||||
joint.useLimits = true;
|
||||
JointLimits limits = new JointLimits();
|
||||
limits.min = -20;
|
||||
limits.max = 20;
|
||||
joint.limits = limits;
|
||||
utilBone.rigidbody.mass = utilBone.transform.parent.rigidbody.mass * 0.75f;
|
||||
}
|
||||
}
|
||||
|
||||
void AttachRigidbody(SkeletonUtilityBone utilBone){
|
||||
if(utilBone.GetComponent<Collider>() == null){
|
||||
if(utilBone.bone.Data.Length == 0){
|
||||
SphereCollider sphere = utilBone.gameObject.AddComponent<SphereCollider>();
|
||||
sphere.radius = 0.1f;
|
||||
}
|
||||
else{
|
||||
float length = utilBone.bone.Data.Length;
|
||||
BoxCollider box = utilBone.gameObject.AddComponent<BoxCollider>();
|
||||
box.size = new Vector3( length, length / 3, 0.2f);
|
||||
box.center = new Vector3(length / 2, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
utilBone.gameObject.AddComponent<Rigidbody>();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b3ae20b4bcc31f645afd6f5b64f82473
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@ -0,0 +1,316 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License
|
||||
* Version 2.1
|
||||
*
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable and
|
||||
* non-transferable license to install, execute and perform the Spine Runtimes
|
||||
* Software (the "Software") solely for internal use. Without the written
|
||||
* permission of Esoteric Software (typically granted by licensing Spine), you
|
||||
* may not (a) modify, translate, adapt or otherwise create derivative works,
|
||||
* improvements of the Software or develop new applications using the Software
|
||||
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
|
||||
* trademark, patent or other intellectual property or proprietary rights
|
||||
* notices on or in the Software, including any copy thereof. Redistributions
|
||||
* in binary or source form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Skeleton Utility created by Mitch Thompson
|
||||
* Full irrevocable rights and permissions granted to Esoteric Software
|
||||
*****************************************************************************/
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
#if UNITY_4_3
|
||||
//nothing
|
||||
#else
|
||||
using UnityEditor.AnimatedValues;
|
||||
#endif
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Spine;
|
||||
|
||||
using System.Reflection;
|
||||
|
||||
[CustomEditor(typeof(SkeletonUtility))]
|
||||
public class SkeletonUtilityInspector : Editor {
|
||||
|
||||
public static void AttachIcon(SkeletonUtilityBone utilityBone){
|
||||
Skeleton skeleton = utilityBone.skeletonUtility.skeletonRenderer.skeleton;
|
||||
Texture2D icon;
|
||||
if(utilityBone.bone.Data.Length == 0)
|
||||
icon = SpineEditorUtilities.Icons.nullBone;
|
||||
else
|
||||
icon = SpineEditorUtilities.Icons.boneNib;
|
||||
|
||||
foreach(IkConstraint c in skeleton.IkConstraints){
|
||||
if(c.Target == utilityBone.bone){
|
||||
icon = SpineEditorUtilities.Icons.constraintNib;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
typeof(EditorGUIUtility).InvokeMember("SetIconForObject", BindingFlags.InvokeMethod | BindingFlags.Static | BindingFlags.NonPublic, null, null, new object[2]{ utilityBone.gameObject, icon});
|
||||
}
|
||||
|
||||
static void AttachIconsToChildren(Transform root){
|
||||
if(root != null){
|
||||
var utilityBones = root.GetComponentsInChildren<SkeletonUtilityBone>();
|
||||
foreach(var utilBone in utilityBones){
|
||||
AttachIcon(utilBone);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static SkeletonUtilityInspector(){
|
||||
#if UNITY_4_3
|
||||
showSlots = false;
|
||||
#else
|
||||
showSlots = new AnimBool(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
SkeletonUtility skeletonUtility;
|
||||
|
||||
Skeleton skeleton;
|
||||
SkeletonRenderer skeletonRenderer;
|
||||
Transform transform;
|
||||
bool isPrefab;
|
||||
|
||||
|
||||
Dictionary<Slot, List<Attachment>> attachmentTable = new Dictionary<Slot, List<Attachment>>();
|
||||
|
||||
|
||||
//GUI stuff
|
||||
#if UNITY_4_3
|
||||
static bool showSlots;
|
||||
#else
|
||||
static AnimBool showSlots;
|
||||
#endif
|
||||
|
||||
void OnEnable(){
|
||||
skeletonUtility = (SkeletonUtility)target;
|
||||
skeletonRenderer = skeletonUtility.GetComponent<SkeletonRenderer>();
|
||||
skeleton = skeletonRenderer.skeleton;
|
||||
transform = skeletonRenderer.transform;
|
||||
|
||||
if(skeleton == null){
|
||||
skeletonRenderer.Reset();
|
||||
skeletonRenderer.LateUpdate();
|
||||
|
||||
skeleton = skeletonRenderer.skeleton;
|
||||
}
|
||||
|
||||
UpdateAttachments();
|
||||
|
||||
if(PrefabUtility.GetPrefabType(this.target) == PrefabType.Prefab)
|
||||
isPrefab = true;
|
||||
|
||||
}
|
||||
|
||||
void OnDestroy(){
|
||||
|
||||
}
|
||||
|
||||
void OnSceneGUI(){
|
||||
if(skeleton == null){
|
||||
OnEnable();
|
||||
return;
|
||||
}
|
||||
|
||||
float flipRotation = skeleton.FlipX ? -1 : 1;
|
||||
|
||||
foreach(Bone b in skeleton.Bones){
|
||||
Vector3 vec = transform.TransformPoint(new Vector3(b.WorldX, b.WorldY, 0));
|
||||
|
||||
Quaternion rot = Quaternion.Euler(0,0,b.WorldRotation * flipRotation);
|
||||
Vector3 forward = transform.TransformDirection( rot * Vector3.right);
|
||||
forward *= flipRotation;
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAttachments(){
|
||||
attachmentTable = new Dictionary<Slot, List<Attachment>>();
|
||||
Skin skin = skeleton.Skin;
|
||||
|
||||
if(skin == null){
|
||||
skin = skeletonRenderer.skeletonDataAsset.GetSkeletonData(true).DefaultSkin;
|
||||
}
|
||||
|
||||
for(int i = skeleton.Slots.Count-1; i >= 0; i--){
|
||||
List<Attachment> attachments = new List<Attachment>();
|
||||
skin.FindAttachmentsForSlot(i, attachments);
|
||||
|
||||
attachmentTable.Add(skeleton.Slots[i], attachments);
|
||||
}
|
||||
}
|
||||
|
||||
void SpawnHierarchyButton(string label, string tooltip, SkeletonUtilityBone.Mode mode, bool pos, bool rot, bool sca, params GUILayoutOption[] options){
|
||||
GUIContent content = new GUIContent(label, tooltip);
|
||||
if(GUILayout.Button(content, options)){
|
||||
if(skeletonUtility.skeletonRenderer == null)
|
||||
skeletonUtility.skeletonRenderer = skeletonUtility.GetComponent<SkeletonRenderer>();
|
||||
|
||||
if(skeletonUtility.boneRoot != null){
|
||||
return;
|
||||
}
|
||||
|
||||
skeletonUtility.SpawnHierarchy(mode, pos, rot, sca);
|
||||
|
||||
SkeletonUtilityBone[] boneComps = skeletonUtility.GetComponentsInChildren<SkeletonUtilityBone>();
|
||||
foreach(SkeletonUtilityBone b in boneComps)
|
||||
AttachIcon(b);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI ()
|
||||
{
|
||||
if(isPrefab){
|
||||
GUILayout.Label(new GUIContent("Cannot edit Prefabs", SpineEditorUtilities.Icons.warning));
|
||||
return;
|
||||
}
|
||||
|
||||
skeletonUtility.boneRoot = (Transform)EditorGUILayout.ObjectField( "Bone Root", skeletonUtility.boneRoot, typeof(Transform), true);
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
EditorGUI.BeginDisabledGroup(skeletonUtility.boneRoot != null);
|
||||
{
|
||||
if(GUILayout.Button(new GUIContent("Spawn Hierarchy", SpineEditorUtilities.Icons.skeleton), GUILayout.Width(150), GUILayout.Height(24)))
|
||||
SpawnHierarchyContextMenu();
|
||||
}
|
||||
EditorGUI.EndDisabledGroup();
|
||||
|
||||
if(GUILayout.Button(new GUIContent("Spawn Submeshes", SpineEditorUtilities.Icons.subMeshRenderer), GUILayout.Width(150), GUILayout.Height(24)))
|
||||
skeletonUtility.SpawnSubRenderers(true);
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
skeleton.FlipX = EditorGUILayout.ToggleLeft("Flip X", skeleton.FlipX);
|
||||
skeleton.FlipY = EditorGUILayout.ToggleLeft("Flip Y", skeleton.FlipY);
|
||||
if(EditorGUI.EndChangeCheck()){
|
||||
skeletonRenderer.LateUpdate();
|
||||
SceneView.RepaintAll();
|
||||
}
|
||||
|
||||
#if UNITY_4_3
|
||||
showSlots = EditorGUILayout.Foldout(showSlots, "Slots");
|
||||
#else
|
||||
showSlots.target = EditorGUILayout.Foldout(showSlots.target, "Slots");
|
||||
if(EditorGUILayout.BeginFadeGroup(showSlots.faded)){
|
||||
#endif
|
||||
foreach(KeyValuePair<Slot, List<Attachment>> pair in attachmentTable){
|
||||
|
||||
Slot slot = pair.Key;
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUI.indentLevel = 1;
|
||||
EditorGUILayout.LabelField(new GUIContent(slot.Data.Name, SpineEditorUtilities.Icons.slot), GUILayout.ExpandWidth(false));
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
Color c = EditorGUILayout.ColorField(new Color(slot.R, slot.G, slot.B, slot.A), GUILayout.Width(60));
|
||||
|
||||
if(EditorGUI.EndChangeCheck()){
|
||||
slot.SetColor( c );
|
||||
skeletonRenderer.LateUpdate();
|
||||
}
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
|
||||
|
||||
foreach(Attachment attachment in pair.Value){
|
||||
|
||||
if(slot.Attachment == attachment){
|
||||
GUI.contentColor = Color.white;
|
||||
}
|
||||
else{
|
||||
GUI.contentColor = Color.grey;
|
||||
}
|
||||
|
||||
EditorGUI.indentLevel = 2;
|
||||
bool isAttached = attachment == slot.Attachment;
|
||||
|
||||
Texture2D icon = null;
|
||||
|
||||
if(attachment is MeshAttachment || attachment is SkinnedMeshAttachment)
|
||||
icon = SpineEditorUtilities.Icons.mesh;
|
||||
else
|
||||
icon = SpineEditorUtilities.Icons.image;
|
||||
|
||||
bool swap = EditorGUILayout.ToggleLeft( new GUIContent( attachment.Name, icon ), attachment == slot.Attachment );
|
||||
|
||||
if(!isAttached && swap){
|
||||
slot.Attachment = attachment;
|
||||
skeletonRenderer.LateUpdate();
|
||||
}
|
||||
else if(isAttached && !swap){
|
||||
slot.Attachment = null;
|
||||
skeletonRenderer.LateUpdate();
|
||||
}
|
||||
|
||||
GUI.contentColor = Color.white;
|
||||
}
|
||||
}
|
||||
#if UNITY_4_3
|
||||
|
||||
#else
|
||||
}
|
||||
EditorGUILayout.EndFadeGroup();
|
||||
if(showSlots.isAnimating)
|
||||
Repaint();
|
||||
#endif
|
||||
}
|
||||
|
||||
void SpawnHierarchyContextMenu(){
|
||||
GenericMenu menu = new GenericMenu();
|
||||
|
||||
menu.AddItem(new GUIContent("Follow"), false, SpawnFollowHierarchy);
|
||||
menu.AddItem(new GUIContent("Follow (Root Only)"), false, SpawnFollowHierarchyRootOnly);
|
||||
menu.AddSeparator("");
|
||||
menu.AddItem(new GUIContent("Override"), false, SpawnOverrideHierarchy);
|
||||
menu.AddItem(new GUIContent("Override (Root Only)"), false, SpawnOverrideHierarchyRootOnly);
|
||||
|
||||
menu.ShowAsContext();
|
||||
}
|
||||
|
||||
void SpawnFollowHierarchy(){
|
||||
Selection.activeGameObject = skeletonUtility.SpawnHierarchy( SkeletonUtilityBone.Mode.Follow, true, true, true );
|
||||
AttachIconsToChildren( skeletonUtility.boneRoot );
|
||||
}
|
||||
|
||||
void SpawnFollowHierarchyRootOnly(){
|
||||
Selection.activeGameObject = skeletonUtility.SpawnRoot( SkeletonUtilityBone.Mode.Follow, true, true, true );
|
||||
AttachIconsToChildren( skeletonUtility.boneRoot );
|
||||
}
|
||||
|
||||
void SpawnOverrideHierarchy(){
|
||||
Selection.activeGameObject = skeletonUtility.SpawnHierarchy( SkeletonUtilityBone.Mode.Override, true, true, true );
|
||||
AttachIconsToChildren( skeletonUtility.boneRoot );
|
||||
}
|
||||
|
||||
void SpawnOverrideHierarchyRootOnly(){
|
||||
Selection.activeGameObject = skeletonUtility.SpawnRoot( SkeletonUtilityBone.Mode.Override, true, true, true );
|
||||
AttachIconsToChildren( skeletonUtility.boneRoot );
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a5b90df955eb8c2429ac67c8b2de6c5c
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@ -0,0 +1,335 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License
|
||||
* Version 2.1
|
||||
*
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable and
|
||||
* non-transferable license to install, execute and perform the Spine Runtimes
|
||||
* Software (the "Software") solely for internal use. Without the written
|
||||
* permission of Esoteric Software (typically granted by licensing Spine), you
|
||||
* may not (a) modify, translate, adapt or otherwise create derivative works,
|
||||
* improvements of the Software or develop new applications using the Software
|
||||
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
|
||||
* trademark, patent or other intellectual property or proprietary rights
|
||||
* notices on or in the Software, including any copy thereof. Redistributions
|
||||
* in binary or source form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Skeleton Utility created by Mitch Thompson
|
||||
* Full irrevocable rights and permissions granted to Esoteric Software
|
||||
*****************************************************************************/
|
||||
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Spine;
|
||||
|
||||
[RequireComponent(typeof(SkeletonAnimation))]
|
||||
[ExecuteInEditMode]
|
||||
public class SkeletonUtility : MonoBehaviour {
|
||||
public delegate void SkeletonUtilityDelegate();
|
||||
public event SkeletonUtilityDelegate OnReset;
|
||||
|
||||
public Transform boneRoot;
|
||||
|
||||
void Update(){
|
||||
if(boneRoot != null && skeletonRenderer.skeleton != null){
|
||||
Vector3 flipScale = Vector3.one;
|
||||
if(skeletonRenderer.skeleton.FlipX)
|
||||
flipScale.x = -1;
|
||||
|
||||
if(skeletonRenderer.skeleton.FlipY)
|
||||
flipScale.y = -1;
|
||||
|
||||
boneRoot.localScale = flipScale;
|
||||
}
|
||||
}
|
||||
|
||||
[HideInInspector]
|
||||
public SkeletonRenderer skeletonRenderer;
|
||||
|
||||
[HideInInspector]
|
||||
public SkeletonAnimation skeletonAnimation;
|
||||
|
||||
[System.NonSerialized]
|
||||
public List<SkeletonUtilityBone> utilityBones = new List<SkeletonUtilityBone>();
|
||||
|
||||
[System.NonSerialized]
|
||||
public List<SkeletonUtilityConstraint> utilityConstraints = new List<SkeletonUtilityConstraint>();
|
||||
// Dictionary<Bone, SkeletonUtilityBone> utilityBoneTable;
|
||||
|
||||
|
||||
protected bool hasTransformBones;
|
||||
protected bool hasUtilityConstraints;
|
||||
protected bool needToReprocessBones;
|
||||
|
||||
void OnEnable(){
|
||||
if(skeletonRenderer == null){
|
||||
skeletonRenderer = GetComponent<SkeletonRenderer>();
|
||||
}
|
||||
|
||||
if(skeletonAnimation == null){
|
||||
skeletonAnimation = GetComponent<SkeletonAnimation>();
|
||||
}
|
||||
|
||||
skeletonRenderer.OnReset -= HandleRendererReset;
|
||||
skeletonRenderer.OnReset += HandleRendererReset;
|
||||
|
||||
if(skeletonAnimation != null){
|
||||
skeletonAnimation.UpdateLocal -= UpdateLocal;
|
||||
skeletonAnimation.UpdateLocal += UpdateLocal;
|
||||
}
|
||||
|
||||
|
||||
CollectBones();
|
||||
}
|
||||
|
||||
void Start(){
|
||||
//recollect because order of operations failure when switching between game mode and edit mode...
|
||||
// CollectBones();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void OnDisable(){
|
||||
skeletonRenderer.OnReset -= HandleRendererReset;
|
||||
|
||||
if(skeletonAnimation != null){
|
||||
skeletonAnimation.UpdateLocal -= UpdateLocal;
|
||||
skeletonAnimation.UpdateWorld -= UpdateWorld;
|
||||
skeletonAnimation.UpdateComplete -= UpdateComplete;
|
||||
}
|
||||
}
|
||||
|
||||
void HandleRendererReset(SkeletonRenderer r){
|
||||
if(OnReset != null)
|
||||
OnReset();
|
||||
|
||||
CollectBones();
|
||||
}
|
||||
|
||||
public void RegisterBone(SkeletonUtilityBone bone){
|
||||
if(utilityBones.Contains(bone))
|
||||
return;
|
||||
else{
|
||||
utilityBones.Add(bone);
|
||||
needToReprocessBones = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void UnregisterBone(SkeletonUtilityBone bone){
|
||||
utilityBones.Remove(bone);
|
||||
}
|
||||
|
||||
public void RegisterConstraint(SkeletonUtilityConstraint constraint){
|
||||
|
||||
if(utilityConstraints.Contains(constraint))
|
||||
return;
|
||||
else{
|
||||
utilityConstraints.Add(constraint);
|
||||
needToReprocessBones = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void UnregisterConstraint(SkeletonUtilityConstraint constraint){
|
||||
utilityConstraints.Remove(constraint);
|
||||
}
|
||||
|
||||
public void CollectBones(){
|
||||
if(skeletonRenderer.skeleton == null)
|
||||
return;
|
||||
|
||||
if(boneRoot != null){
|
||||
List<string> constraintTargetNames = new List<string>();
|
||||
|
||||
foreach(IkConstraint c in skeletonRenderer.skeleton.IkConstraints){
|
||||
constraintTargetNames.Add(c.Target.Data.Name);
|
||||
}
|
||||
|
||||
foreach(var b in utilityBones){
|
||||
if(b.bone == null){
|
||||
return;
|
||||
}
|
||||
if(b.mode == SkeletonUtilityBone.Mode.Override){
|
||||
hasTransformBones = true;
|
||||
}
|
||||
|
||||
if(constraintTargetNames.Contains( b.bone.Data.Name )){
|
||||
hasUtilityConstraints = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(utilityConstraints.Count > 0)
|
||||
hasUtilityConstraints = true;
|
||||
|
||||
if(skeletonAnimation != null){
|
||||
skeletonAnimation.UpdateWorld -= UpdateWorld;
|
||||
skeletonAnimation.UpdateComplete -= UpdateComplete;
|
||||
|
||||
if(hasTransformBones || hasUtilityConstraints){
|
||||
skeletonAnimation.UpdateWorld += UpdateWorld;
|
||||
}
|
||||
|
||||
if(hasUtilityConstraints){
|
||||
skeletonAnimation.UpdateComplete += UpdateComplete;
|
||||
}
|
||||
}
|
||||
|
||||
needToReprocessBones = false;
|
||||
}
|
||||
else{
|
||||
utilityBones.Clear();
|
||||
utilityConstraints.Clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void UpdateLocal(SkeletonAnimation anim){
|
||||
|
||||
if(needToReprocessBones)
|
||||
CollectBones();
|
||||
|
||||
if(utilityBones == null)
|
||||
return;
|
||||
|
||||
foreach(SkeletonUtilityBone b in utilityBones){
|
||||
b.transformLerpComplete = false;
|
||||
}
|
||||
|
||||
UpdateAllBones();
|
||||
}
|
||||
|
||||
void UpdateWorld(SkeletonAnimation anim){
|
||||
UpdateAllBones();
|
||||
|
||||
foreach(SkeletonUtilityConstraint c in utilityConstraints)
|
||||
c.DoUpdate();
|
||||
}
|
||||
|
||||
void UpdateComplete(SkeletonAnimation anim){
|
||||
UpdateAllBones();
|
||||
}
|
||||
|
||||
void UpdateAllBones(){
|
||||
if(boneRoot == null){
|
||||
CollectBones();
|
||||
}
|
||||
|
||||
if(utilityBones == null)
|
||||
return;
|
||||
|
||||
foreach(SkeletonUtilityBone b in utilityBones){
|
||||
b.DoUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
public Transform GetBoneRoot(){
|
||||
if(boneRoot != null)
|
||||
return boneRoot;
|
||||
|
||||
boneRoot = new GameObject("SkeletonUtility-Root").transform;
|
||||
boneRoot.parent = transform;
|
||||
boneRoot.localPosition = Vector3.zero;
|
||||
boneRoot.localRotation = Quaternion.identity;
|
||||
boneRoot.localScale = Vector3.one;
|
||||
|
||||
return boneRoot;
|
||||
}
|
||||
|
||||
public GameObject SpawnRoot(SkeletonUtilityBone.Mode mode, bool pos, bool rot, bool sca){
|
||||
GetBoneRoot();
|
||||
Skeleton skeleton = this.skeletonRenderer.skeleton;
|
||||
|
||||
GameObject go = SpawnBone( skeleton.RootBone, boneRoot, mode, pos, rot, sca );
|
||||
|
||||
CollectBones();
|
||||
|
||||
return go;
|
||||
}
|
||||
|
||||
public GameObject SpawnHierarchy(SkeletonUtilityBone.Mode mode, bool pos, bool rot, bool sca){
|
||||
GetBoneRoot();
|
||||
|
||||
Skeleton skeleton = this.skeletonRenderer.skeleton;
|
||||
|
||||
GameObject go = SpawnBoneRecursively(skeleton.RootBone, boneRoot, mode, pos, rot, sca);
|
||||
|
||||
CollectBones();
|
||||
|
||||
return go;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
foreach(Bone child in bone.Children){
|
||||
SpawnBoneRecursively(child, go.transform, mode, pos, rot, sca);
|
||||
}
|
||||
|
||||
return go;
|
||||
}
|
||||
|
||||
public GameObject SpawnBone(Bone bone, Transform parent, SkeletonUtilityBone.Mode mode, bool pos, bool rot, bool sca){
|
||||
GameObject go = new GameObject(bone.Data.Name);
|
||||
go.transform.parent = parent;
|
||||
|
||||
SkeletonUtilityBone b = go.AddComponent<SkeletonUtilityBone>();
|
||||
b.skeletonUtility = this;
|
||||
b.position = pos;
|
||||
b.rotation = rot;
|
||||
b.scale = sca;
|
||||
b.mode = mode;
|
||||
b.zPosition = true;
|
||||
b.Reset();
|
||||
b.bone = bone;
|
||||
b.boneName = bone.Data.Name;
|
||||
b.valid = true;
|
||||
|
||||
if(mode == SkeletonUtilityBone.Mode.Override){
|
||||
if(rot)
|
||||
go.transform.localRotation = Quaternion.Euler(0, 0, b.bone.RotationIK);
|
||||
|
||||
if(pos)
|
||||
go.transform.localPosition = new Vector3(b.bone.X, b.bone.Y, 0);
|
||||
|
||||
go.transform.localScale = new Vector3(b.bone.scaleX, b.bone.scaleY, 0);
|
||||
}
|
||||
|
||||
return go;
|
||||
}
|
||||
|
||||
public void SpawnSubRenderers(bool disablePrimaryRenderer){
|
||||
int submeshCount = GetComponent<MeshFilter>().sharedMesh.subMeshCount;
|
||||
|
||||
for(int i = 0; i < submeshCount; i++){
|
||||
GameObject go = new GameObject("Submesh " + i, typeof(MeshFilter), typeof(MeshRenderer));
|
||||
go.transform.parent = transform;
|
||||
go.transform.localPosition = Vector3.zero;
|
||||
go.transform.localRotation = Quaternion.identity;
|
||||
go.transform.localScale = Vector3.one;
|
||||
|
||||
SkeletonUtilitySubmeshRenderer s = go.AddComponent<SkeletonUtilitySubmeshRenderer>();
|
||||
s.sortingOrder = i * 10;
|
||||
s.submeshIndex = i;
|
||||
s.Initialize( renderer );
|
||||
s.Update();
|
||||
}
|
||||
|
||||
if(disablePrimaryRenderer)
|
||||
renderer.enabled = false;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7f726fb798ad621458c431cb9966d91d
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@ -0,0 +1,218 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License
|
||||
* Version 2.1
|
||||
*
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable and
|
||||
* non-transferable license to install, execute and perform the Spine Runtimes
|
||||
* Software (the "Software") solely for internal use. Without the written
|
||||
* permission of Esoteric Software (typically granted by licensing Spine), you
|
||||
* may not (a) modify, translate, adapt or otherwise create derivative works,
|
||||
* improvements of the Software or develop new applications using the Software
|
||||
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
|
||||
* trademark, patent or other intellectual property or proprietary rights
|
||||
* notices on or in the Software, including any copy thereof. Redistributions
|
||||
* in binary or source form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Skeleton Utility created by Mitch Thompson
|
||||
* Full irrevocable rights and permissions granted to Esoteric Software
|
||||
*****************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Spine;
|
||||
|
||||
/// <summary>Sets a GameObject's transform to match a bone on a Spine skeleton.</summary>
|
||||
[ExecuteInEditMode]
|
||||
[AddComponentMenu("Spine/SkeletonUtilityBone")]
|
||||
public class SkeletonUtilityBone : MonoBehaviour {
|
||||
|
||||
public enum Mode { Follow, Override }
|
||||
|
||||
[System.NonSerialized]
|
||||
public bool valid;
|
||||
|
||||
[System.NonSerialized]
|
||||
public SkeletonUtility skeletonUtility;
|
||||
|
||||
[System.NonSerialized]
|
||||
public Bone bone;
|
||||
|
||||
public Mode mode;
|
||||
|
||||
public bool zPosition = true;
|
||||
public bool position;
|
||||
public bool rotation;
|
||||
public bool scale;
|
||||
|
||||
[Range(0f,1f)]
|
||||
public float overrideAlpha = 1;
|
||||
|
||||
/// <summary>If a bone isn't set, boneName is used to find the bone.</summary>
|
||||
public String boneName;
|
||||
|
||||
public Transform parentReference;
|
||||
|
||||
[HideInInspector]
|
||||
public bool transformLerpComplete;
|
||||
|
||||
protected Transform cachedTransform;
|
||||
protected Transform skeletonTransform;
|
||||
|
||||
public bool NonUniformScaleWarning{
|
||||
get{
|
||||
return nonUniformScaleWarning;
|
||||
}
|
||||
}
|
||||
private bool nonUniformScaleWarning;
|
||||
|
||||
public void Reset () {
|
||||
bone = null;
|
||||
cachedTransform = transform;
|
||||
valid = skeletonUtility != null && skeletonUtility.skeletonRenderer != null && skeletonUtility.skeletonRenderer.valid;
|
||||
if (!valid) return;
|
||||
skeletonTransform = skeletonUtility.transform;
|
||||
|
||||
skeletonUtility.OnReset -= HandleOnReset;
|
||||
skeletonUtility.OnReset += HandleOnReset;
|
||||
|
||||
DoUpdate();
|
||||
}
|
||||
|
||||
void OnEnable(){
|
||||
skeletonUtility = GetComponentInParent<SkeletonUtility>();
|
||||
if(skeletonUtility == null)
|
||||
return;
|
||||
|
||||
skeletonUtility.RegisterBone(this);
|
||||
|
||||
skeletonUtility.OnReset += HandleOnReset;
|
||||
}
|
||||
|
||||
void HandleOnReset ()
|
||||
{
|
||||
Reset ();
|
||||
}
|
||||
|
||||
void OnDisable(){
|
||||
if(skeletonUtility != null){
|
||||
skeletonUtility.OnReset -= HandleOnReset;
|
||||
|
||||
skeletonUtility.UnregisterBone(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void DoUpdate () {
|
||||
|
||||
if (!valid) {
|
||||
Reset();
|
||||
return;
|
||||
}
|
||||
|
||||
Spine.Skeleton skeleton = skeletonUtility.skeletonRenderer.skeleton;
|
||||
|
||||
if (bone == null) {
|
||||
if (boneName == null || boneName.Length == 0) return;
|
||||
bone = skeleton.FindBone(boneName);
|
||||
if (bone == null) {
|
||||
Debug.LogError("Bone not found: " + boneName, this);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
float flipRotation = (skeleton.flipX ^ skeleton.flipY) ? -1f : 1f;
|
||||
|
||||
|
||||
if(mode == Mode.Follow){
|
||||
if(position){
|
||||
cachedTransform.localPosition = new Vector3(bone.x, bone.y, 0);
|
||||
}
|
||||
|
||||
if(rotation){
|
||||
|
||||
if(bone.Data.InheritRotation){
|
||||
cachedTransform.localRotation = Quaternion.Euler(0,0,bone.rotationIK);
|
||||
}
|
||||
else{
|
||||
Vector3 euler = skeletonTransform.rotation.eulerAngles;
|
||||
cachedTransform.rotation = Quaternion.Euler(euler.x, euler.y, skeletonTransform.rotation.eulerAngles.z + (bone.worldRotation * flipRotation) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(scale){
|
||||
cachedTransform.localScale = new Vector3(bone.scaleX, bone.scaleY, 1);
|
||||
|
||||
nonUniformScaleWarning = (bone.scaleX != bone.scaleY);
|
||||
}
|
||||
|
||||
}
|
||||
else if(mode == Mode.Override){
|
||||
if(transformLerpComplete)
|
||||
return;
|
||||
|
||||
if(parentReference == null){
|
||||
if(position){
|
||||
bone.x = Mathf.Lerp(bone.x, cachedTransform.localPosition.x, overrideAlpha);
|
||||
bone.y = Mathf.Lerp(bone.y, cachedTransform.localPosition.y, overrideAlpha);
|
||||
}
|
||||
|
||||
if(rotation){
|
||||
bone.rotation = Mathf.LerpAngle(bone.Rotation, cachedTransform.localRotation.eulerAngles.z, overrideAlpha);
|
||||
}
|
||||
|
||||
if(scale){
|
||||
bone.scaleX = Mathf.Lerp(bone.scaleX, cachedTransform.localScale.x, overrideAlpha);
|
||||
bone.scaleY = Mathf.Lerp(bone.scaleY, cachedTransform.localScale.y, overrideAlpha);
|
||||
|
||||
nonUniformScaleWarning = (bone.scaleX != bone.scaleY);
|
||||
}
|
||||
}
|
||||
else{
|
||||
if(position){
|
||||
Vector3 pos = parentReference.InverseTransformPoint(cachedTransform.position);
|
||||
bone.x = Mathf.Lerp(bone.x, pos.x, overrideAlpha);
|
||||
bone.y = Mathf.Lerp(bone.y, pos.y, overrideAlpha);
|
||||
}
|
||||
|
||||
if(rotation){
|
||||
bone.rotation = Mathf.LerpAngle(bone.Rotation, Quaternion.LookRotation( Vector3.forward, parentReference.InverseTransformDirection( cachedTransform.up ) ).eulerAngles.z, overrideAlpha);
|
||||
}
|
||||
|
||||
//TODO: Something about this
|
||||
if(scale){
|
||||
bone.scaleX = Mathf.Lerp(bone.scaleX, cachedTransform.localScale.x, overrideAlpha);
|
||||
bone.scaleY = Mathf.Lerp(bone.scaleY, cachedTransform.localScale.y, overrideAlpha);
|
||||
|
||||
nonUniformScaleWarning = (bone.scaleX != bone.scaleY);
|
||||
}
|
||||
}
|
||||
|
||||
transformLerpComplete = true;
|
||||
}
|
||||
}
|
||||
|
||||
void OnDrawGizmos(){
|
||||
if(NonUniformScaleWarning){
|
||||
Gizmos.DrawIcon(transform.position + new Vector3(0,0.128f,0), "icon-warning");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b238dfcde8209044b97d23f62bcaadf6
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@ -0,0 +1,22 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
|
||||
[RequireComponent(typeof(SkeletonUtilityBone)), ExecuteInEditMode]
|
||||
|
||||
public abstract class SkeletonUtilityConstraint : MonoBehaviour {
|
||||
|
||||
protected SkeletonUtilityBone utilBone;
|
||||
protected SkeletonUtility skeletonUtility;
|
||||
|
||||
protected virtual void OnEnable(){
|
||||
utilBone = GetComponent<SkeletonUtilityBone>();
|
||||
skeletonUtility = GetComponentInParent<SkeletonUtility>();
|
||||
skeletonUtility.RegisterConstraint(this);
|
||||
}
|
||||
|
||||
protected virtual void OnDisable(){
|
||||
skeletonUtility.UnregisterConstraint(this);
|
||||
}
|
||||
|
||||
public abstract void DoUpdate();
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 522dbfcc6c916df4396f14f35048d185
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@ -0,0 +1,61 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
|
||||
public class SkeletonUtilityEyeConstraint : SkeletonUtilityConstraint {
|
||||
|
||||
public Transform[] eyes;
|
||||
public float radius = 0.5f;
|
||||
public Transform target;
|
||||
public Vector3 targetPosition;
|
||||
|
||||
public float speed = 10;
|
||||
|
||||
Vector3[] origins;
|
||||
Vector3 centerPoint;
|
||||
|
||||
protected override void OnEnable ()
|
||||
{
|
||||
if(!Application.isPlaying)
|
||||
return;
|
||||
|
||||
base.OnEnable ();
|
||||
|
||||
Bounds centerBounds = new Bounds( eyes[0].localPosition, Vector3.zero );
|
||||
origins = new Vector3[eyes.Length];
|
||||
for(int i = 0; i < eyes.Length; i++){
|
||||
origins[i] = eyes[i].localPosition;
|
||||
centerBounds.Encapsulate( origins[i] );
|
||||
}
|
||||
|
||||
centerPoint = centerBounds.center;
|
||||
}
|
||||
|
||||
protected override void OnDisable ()
|
||||
{
|
||||
if(!Application.isPlaying)
|
||||
return;
|
||||
|
||||
base.OnDisable ();
|
||||
}
|
||||
|
||||
public override void DoUpdate ()
|
||||
{
|
||||
|
||||
if(target != null)
|
||||
targetPosition = target.position;
|
||||
|
||||
Vector3 goal = targetPosition;
|
||||
|
||||
Vector3 center = transform.TransformPoint(centerPoint);
|
||||
Vector3 dir = goal - center;
|
||||
|
||||
if(dir.magnitude > 1)
|
||||
dir.Normalize();
|
||||
|
||||
for(int i = 0; i < eyes.Length; i++){
|
||||
center = transform.TransformPoint(origins[i]);
|
||||
eyes[i].position = Vector3.MoveTowards(eyes[i].position, center + (dir * radius), speed * Time.deltaTime);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0d994c65b6daec64f80ae2ae04e9d999
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@ -0,0 +1,58 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
|
||||
[RequireComponent(typeof(SkeletonUtilityBone)), ExecuteInEditMode]
|
||||
public class SkeletonUtilityGroundConstraint : SkeletonUtilityConstraint {
|
||||
|
||||
public LayerMask groundMask;
|
||||
public bool use2D = true;
|
||||
public float castDistance = 5f;
|
||||
Vector3 rayOrigin;
|
||||
Vector3 rayDir = new Vector3(0,-1,0);
|
||||
float hitY;
|
||||
|
||||
protected override void OnEnable ()
|
||||
{
|
||||
base.OnEnable ();
|
||||
}
|
||||
|
||||
protected override void OnDisable ()
|
||||
{
|
||||
base.OnDisable ();
|
||||
}
|
||||
|
||||
public override void DoUpdate()
|
||||
{
|
||||
rayOrigin = transform.position + new Vector3(0,castDistance,0);
|
||||
|
||||
hitY = float.MinValue;
|
||||
if(use2D){
|
||||
RaycastHit2D hit = Physics2D.Raycast(rayOrigin , rayDir, castDistance, groundMask);
|
||||
if(hit.collider != null){
|
||||
hitY = hit.point.y;
|
||||
}
|
||||
}
|
||||
else{
|
||||
RaycastHit hit;
|
||||
if(Physics.Raycast( rayOrigin, rayDir, out hit, castDistance, groundMask)){
|
||||
hitY = hit.point.y;
|
||||
}
|
||||
}
|
||||
|
||||
Vector3 v = transform.position;
|
||||
v.y = Mathf.Clamp(v.y, hitY, float.MaxValue);
|
||||
transform.position = v;
|
||||
|
||||
utilBone.bone.X = transform.localPosition.x;
|
||||
utilBone.bone.Y = transform.localPosition.y;
|
||||
|
||||
}
|
||||
|
||||
void OnDrawGizmos(){
|
||||
Vector3 hitEnd = rayOrigin + (rayDir * Mathf.Min(castDistance, rayOrigin.y - hitY));
|
||||
Vector3 clearEnd = rayOrigin + (rayDir * castDistance);
|
||||
Gizmos.DrawLine(rayOrigin, hitEnd);
|
||||
Gizmos.color = Color.red;
|
||||
Gizmos.DrawLine(hitEnd, clearEnd);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3662334b99de5fe4396ab24e30c4fd12
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@ -0,0 +1,81 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class SkeletonUtilityKinematicShadow : MonoBehaviour {
|
||||
|
||||
public bool hideShadow = true;
|
||||
|
||||
Dictionary<Transform, Transform> shadowTable;
|
||||
GameObject shadowRoot;
|
||||
|
||||
void Start(){
|
||||
shadowRoot = (GameObject)Instantiate(gameObject);
|
||||
if(hideShadow)
|
||||
shadowRoot.hideFlags = HideFlags.HideInHierarchy;
|
||||
|
||||
shadowRoot.transform.parent = transform.root;
|
||||
|
||||
shadowTable = new Dictionary<Transform, Transform>();
|
||||
|
||||
Destroy(shadowRoot.GetComponent<SkeletonUtilityKinematicShadow>());
|
||||
|
||||
shadowRoot.transform.position = transform.position;
|
||||
shadowRoot.transform.rotation = transform.rotation;
|
||||
|
||||
Vector3 scaleRef = transform.TransformPoint(Vector3.right);
|
||||
float scale = Vector3.Distance(transform.position, scaleRef);
|
||||
shadowRoot.transform.localScale = Vector3.one;
|
||||
|
||||
var shadowJoints = shadowRoot.GetComponentsInChildren<Joint>();
|
||||
foreach(Joint j in shadowJoints){
|
||||
j.connectedAnchor *= scale;
|
||||
}
|
||||
|
||||
var joints = GetComponentsInChildren<Joint>();
|
||||
foreach(var j in joints)
|
||||
Destroy(j);
|
||||
|
||||
var rbs = GetComponentsInChildren<Rigidbody>();
|
||||
foreach(var rb in rbs)
|
||||
Destroy(rb);
|
||||
|
||||
var colliders = GetComponentsInChildren<Collider>();
|
||||
foreach(var c in colliders)
|
||||
Destroy(c);
|
||||
|
||||
|
||||
//match by bone name
|
||||
var shadowBones = shadowRoot.GetComponentsInChildren<SkeletonUtilityBone>();
|
||||
var bones = GetComponentsInChildren<SkeletonUtilityBone>();
|
||||
|
||||
//build bone lookup
|
||||
foreach(var b in bones){
|
||||
if(b.gameObject == gameObject)
|
||||
continue;
|
||||
|
||||
foreach(var sb in shadowBones){
|
||||
if(sb.rigidbody == null)
|
||||
continue;
|
||||
|
||||
if(sb.boneName == b.boneName){
|
||||
shadowTable.Add( sb.transform, b.transform );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach(var b in shadowBones)
|
||||
Destroy(b);
|
||||
}
|
||||
|
||||
void FixedUpdate(){
|
||||
shadowRoot.rigidbody.MovePosition( transform.position );
|
||||
shadowRoot.rigidbody.MoveRotation( transform.rotation );
|
||||
|
||||
foreach(var pair in shadowTable){
|
||||
pair.Value.localPosition = pair.Key.localPosition;
|
||||
pair.Value.localRotation = pair.Key.localRotation;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cfeac06b8a6aa1645813700e3e4c0863
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@ -0,0 +1,102 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
|
||||
[ExecuteInEditMode]
|
||||
public class SkeletonUtilitySubmeshRenderer : MonoBehaviour {
|
||||
|
||||
public Renderer parentRenderer;
|
||||
|
||||
[System.NonSerialized]
|
||||
public Mesh mesh;
|
||||
|
||||
public int submeshIndex = 0;
|
||||
public int sortingOrder = 0;
|
||||
public int sortingLayerID = 0;
|
||||
|
||||
public Material hiddenPassMaterial;
|
||||
Renderer cachedRenderer;
|
||||
MeshFilter filter;
|
||||
Material[] sharedMaterials;
|
||||
MeshFilter parentFilter;
|
||||
|
||||
void Awake(){
|
||||
cachedRenderer = renderer;
|
||||
sharedMaterials = cachedRenderer.sharedMaterials;
|
||||
filter = GetComponent<MeshFilter>();
|
||||
|
||||
if(parentRenderer != null)
|
||||
Initialize( parentRenderer );
|
||||
}
|
||||
|
||||
void OnEnable(){
|
||||
parentRenderer = transform.parent.GetComponent<Renderer>();
|
||||
parentRenderer.GetComponent<SkeletonRenderer>().OnReset += HandleSkeletonReset;
|
||||
}
|
||||
|
||||
void OnDisable(){
|
||||
parentRenderer.GetComponent<SkeletonRenderer>().OnReset -= HandleSkeletonReset;
|
||||
}
|
||||
|
||||
void HandleSkeletonReset(SkeletonRenderer r){
|
||||
if(parentRenderer != null)
|
||||
Initialize(parentRenderer);
|
||||
}
|
||||
|
||||
public void Initialize(Renderer parentRenderer){
|
||||
this.parentRenderer = parentRenderer;
|
||||
parentFilter = parentRenderer.GetComponent<MeshFilter>();
|
||||
mesh = parentFilter.sharedMesh;
|
||||
filter.sharedMesh = mesh;
|
||||
Debug.Log("Mesh: " + mesh);
|
||||
}
|
||||
|
||||
public void Update(){
|
||||
if(mesh == null || mesh != parentFilter.sharedMesh){
|
||||
mesh = parentFilter.sharedMesh;
|
||||
filter.sharedMesh = mesh;
|
||||
}
|
||||
|
||||
if(cachedRenderer == null)
|
||||
cachedRenderer = renderer;
|
||||
|
||||
if(mesh == null || submeshIndex > mesh.subMeshCount - 1){
|
||||
cachedRenderer.enabled = false;
|
||||
return;
|
||||
}
|
||||
else{
|
||||
renderer.enabled = true;
|
||||
}
|
||||
|
||||
bool changed = false;
|
||||
|
||||
if(sharedMaterials.Length != parentRenderer.sharedMaterials.Length){
|
||||
sharedMaterials = parentRenderer.sharedMaterials;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
for(int i = 0; i < renderer.sharedMaterials.Length; i++){
|
||||
if(i == submeshIndex)
|
||||
continue;
|
||||
|
||||
if(sharedMaterials[i] != hiddenPassMaterial){
|
||||
sharedMaterials[i] = hiddenPassMaterial;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(sharedMaterials[submeshIndex] != parentRenderer.sharedMaterials[submeshIndex]){
|
||||
sharedMaterials[submeshIndex] = parentRenderer.sharedMaterials[submeshIndex];
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if(changed){
|
||||
cachedRenderer.sharedMaterials = sharedMaterials;
|
||||
}
|
||||
|
||||
|
||||
cachedRenderer.sortingLayerID = sortingLayerID;
|
||||
cachedRenderer.sortingOrder = sortingOrder;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7820c1c2b0e52c6408de899d6939996e
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- parentRenderer: {instanceID: 0}
|
||||
- mesh: {instanceID: 0}
|
||||
- hiddenPassMaterial: {fileID: 2100000, guid: 43227e5adadc6f24bb4bf74b92a56fb4,
|
||||
type: 2}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||