Merge pull request #310 from Fenrisul/master
[Unity TK2D] Brought TK2D inline with native Unity runtime
5
spine-tk2d/Assets/Gizmos.meta
Normal file
@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a260a1ff5965c2c4f88aea3e7d433965
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
BIN
spine-tk2d/Assets/Gizmos/SkeletonDataAsset Icon.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
46
spine-tk2d/Assets/Gizmos/SkeletonDataAsset Icon.png.meta
Normal file
@ -0,0 +1,46 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 68defdbc95b30a74a9ad396bfc9a2277
|
||||
TextureImporter:
|
||||
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:
|
||||
@ -40,11 +40,11 @@ public class Goblins : MonoBehaviour {
|
||||
public void Start () {
|
||||
skeletonAnimation = GetComponent<SkeletonAnimation>();
|
||||
headBone = skeletonAnimation.skeleton.FindBone("head");
|
||||
skeletonAnimation.UpdateBones += UpdateBones;
|
||||
skeletonAnimation.UpdateLocal += UpdateLocal;
|
||||
}
|
||||
|
||||
// This is called after the animation is applied to the skeleton and can be used to adjust the bones dynamically.
|
||||
public void UpdateBones (SkeletonAnimation skeletonAnimation) {
|
||||
public void UpdateLocal (SkeletonAnimation skeletonAnimation) {
|
||||
headBone.Rotation += 15;
|
||||
}
|
||||
|
||||
|
||||
@ -36,14 +36,14 @@ 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 {
|
||||
[System.NonSerialized]
|
||||
public bool valid;
|
||||
[AddComponentMenu("Spine/BoneFollower")]
|
||||
public class BoneFollower : MonoBehaviour {
|
||||
|
||||
[System.NonSerialized]
|
||||
public bool
|
||||
valid;
|
||||
public SkeletonRenderer skeletonRenderer;
|
||||
public Bone bone;
|
||||
|
||||
public bool followZPosition = true;
|
||||
public bool followBoneRotation = true;
|
||||
|
||||
@ -51,46 +51,66 @@ public class BoneComponent : MonoBehaviour {
|
||||
get { return skeletonRenderer; }
|
||||
set {
|
||||
skeletonRenderer = value;
|
||||
Reset ();
|
||||
Reset();
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
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;
|
||||
}
|
||||
|
||||
if (bone == null) {
|
||||
if (boneName == null || boneName.Length == 0) return;
|
||||
if (boneName == null || boneName.Length == 0)
|
||||
return;
|
||||
bone = skeletonRenderer.skeleton.FindBone(boneName);
|
||||
if (bone == null) {
|
||||
Debug.LogError("Bone not found: " + boneName, this);
|
||||
return;
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -100,22 +120,24 @@ public class BoneComponent : MonoBehaviour {
|
||||
if (cachedTransform.parent == skeletonTransform) {
|
||||
cachedTransform.localPosition = new Vector3(bone.worldX, bone.worldY, followZPosition ? 0f : cachedTransform.localPosition.z);
|
||||
|
||||
if(followBoneRotation) {
|
||||
if (followBoneRotation) {
|
||||
Vector3 rotation = cachedTransform.localRotation.eulerAngles;
|
||||
cachedTransform.localRotation = Quaternion.Euler(rotation.x, rotation.y, bone.worldRotation * flipRotation);
|
||||
}
|
||||
|
||||
} else {
|
||||
Vector3 targetWorldPosition = skeletonTransform.TransformPoint(new Vector3(bone.worldX, bone.worldY, 0f));
|
||||
if(!followZPosition) targetWorldPosition.z = cachedTransform.position.z;
|
||||
if (!followZPosition)
|
||||
targetWorldPosition.z = cachedTransform.position.z;
|
||||
|
||||
cachedTransform.position = targetWorldPosition;
|
||||
|
||||
if(followBoneRotation) {
|
||||
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: d08aa5caf52eae44ba81cc81ca1dad5d
|
||||
guid: a1fd8daaed7b64148a34acb96ba14ce1
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
@ -27,30 +27,57 @@
|
||||
* 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(BoneComponent))]
|
||||
public class BoneComponentInspector : Editor {
|
||||
[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 = SkeletonUtility.GetInParent<SkeletonRenderer>(component.transform);
|
||||
|
||||
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();
|
||||
BoneComponent component = (BoneComponent)target;
|
||||
|
||||
FindRenderer();
|
||||
|
||||
EditorGUILayout.PropertyField(skeletonRenderer);
|
||||
|
||||
if (component.valid) {
|
||||
String[] bones = new String[component.skeletonRenderer.skeleton.Data.Bones.Count + 1];
|
||||
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;
|
||||
@ -64,13 +91,14 @@ public class BoneComponentInspector : Editor {
|
||||
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")
|
||||
(Event.current.type == EventType.ValidateCommand && Event.current.commandName == "UndoRedoPerformed")
|
||||
) {
|
||||
component.Reset();
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 99e3e8311529bbc48a5c3a5b9714e162
|
||||
guid: c71ca35fd6241cb49a0b0756a664fcf7
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
5
spine-tk2d/Assets/spine-tk2d/Editor/GUI.meta
Normal file
@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bfaea6b7e7f52bc46b8d1c3cb5e9eaa1
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
BIN
spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-animation.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
@ -0,0 +1,47 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 52b12ec801461494185a4d3dc66f3d1d
|
||||
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-tk2d/Assets/spine-tk2d/Editor/GUI/icon-animationRoot.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
@ -0,0 +1,47 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3d1be4ea889f3a14b864352fe49a1bde
|
||||
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-tk2d/Assets/spine-tk2d/Editor/GUI/icon-bone.png
Normal file
|
After Width: | Height: | Size: 515 B |
47
spine-tk2d/Assets/spine-tk2d/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-tk2d/Assets/spine-tk2d/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-tk2d/Assets/spine-tk2d/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-tk2d/Assets/spine-tk2d/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:
|
||||
BIN
spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-event.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
47
spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-event.png.meta
Normal file
@ -0,0 +1,47 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d226a80acc775714aa78b85e16a00e9b
|
||||
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-tk2d/Assets/spine-tk2d/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-tk2d/Assets/spine-tk2d/Editor/GUI/icon-image.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
47
spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-image.png.meta
Normal file
@ -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-tk2d/Assets/spine-tk2d/Editor/GUI/icon-mesh.png
Normal file
|
After Width: | Height: | Size: 603 B |
47
spine-tk2d/Assets/spine-tk2d/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-tk2d/Assets/spine-tk2d/Editor/GUI/icon-null.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
47
spine-tk2d/Assets/spine-tk2d/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-tk2d/Assets/spine-tk2d/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:
|
||||
BIN
spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-skeleton.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
@ -0,0 +1,47 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f2216037084d99d4481810cb521ed96f
|
||||
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-tk2d/Assets/spine-tk2d/Editor/GUI/icon-skeletonUtility.png
Normal file
|
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-tk2d/Assets/spine-tk2d/Editor/GUI/icon-skin.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
47
spine-tk2d/Assets/spine-tk2d/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:
|
||||
BIN
spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-skinPlaceholder.png
Normal file
|
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:
|
||||
BIN
spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-skinsRoot.png
Normal file
|
After Width: | Height: | Size: 790 B |
@ -0,0 +1,47 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8bd14c7643597a74ba2edc10a5e4c4ed
|
||||
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-tk2d/Assets/spine-tk2d/Editor/GUI/icon-slot.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
47
spine-tk2d/Assets/spine-tk2d/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:
|
||||
BIN
spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-spine.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
47
spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-spine.png.meta
Normal file
@ -0,0 +1,47 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4e7c964fa5e07024c8bf1debecc3b7c8
|
||||
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-tk2d/Assets/spine-tk2d/Editor/GUI/icon-subMeshRenderer.png
Normal file
|
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-tk2d/Assets/spine-tk2d/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:
|
||||
@ -27,28 +27,47 @@
|
||||
* 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;
|
||||
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 () {
|
||||
base.gui();
|
||||
|
||||
SkeletonAnimation component = (SkeletonAnimation)target;
|
||||
if (!component.valid) return;
|
||||
if (!component.valid)
|
||||
return;
|
||||
|
||||
//catch case where SetAnimation was used to set track 0 without using AnimationName
|
||||
if (Application.isPlaying) {
|
||||
TrackEntry currentState = component.state.GetCurrent(0);
|
||||
if (currentState != null) {
|
||||
if (component.AnimationName != animationName.stringValue) {
|
||||
animationName.stringValue = currentState.Animation.Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//TODO: Refactor this to use GenericMenu and callbacks to avoid interfering with control by other behaviours.
|
||||
// Animation name.
|
||||
{
|
||||
String[] animations = new String[component.skeleton.Data.Animations.Count + 1];
|
||||
@ -67,12 +86,26 @@ public class SkeletonAnimationInspector : SkeletonRendererInspector {
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
String selectedAnimationName = animationIndex == 0 ? null : animations[animationIndex];
|
||||
component.AnimationName = selectedAnimationName;
|
||||
animationName.stringValue = selectedAnimationName;
|
||||
if (component.AnimationName != selectedAnimationName) {
|
||||
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,8 +28,17 @@
|
||||
* 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;
|
||||
|
||||
#if !UNITY_4_3
|
||||
using UnityEditor.AnimatedValues;
|
||||
#endif
|
||||
using UnityEngine;
|
||||
using Spine;
|
||||
|
||||
@ -37,39 +46,75 @@ using Spine;
|
||||
public class SkeletonDataAssetInspector : Editor {
|
||||
private SerializedProperty spriteCollection, skeletonJSON, scale, fromAnimation, toAnimation, duration, defaultMix;
|
||||
private bool showAnimationStateData = true;
|
||||
|
||||
|
||||
#if UNITY_4_3
|
||||
private bool m_showAnimationList = true;
|
||||
#else
|
||||
private AnimBool m_showAnimationList = new AnimBool(true);
|
||||
#endif
|
||||
|
||||
private bool m_initialized = false;
|
||||
private SkeletonDataAsset m_skeletonDataAsset;
|
||||
private string m_skeletonDataAssetGUID;
|
||||
|
||||
void OnEnable () {
|
||||
spriteCollection = serializedObject.FindProperty("spriteCollection");
|
||||
skeletonJSON = serializedObject.FindProperty("skeletonJSON");
|
||||
scale = serializedObject.FindProperty("scale");
|
||||
fromAnimation = serializedObject.FindProperty("fromAnimation");
|
||||
toAnimation = serializedObject.FindProperty("toAnimation");
|
||||
duration = serializedObject.FindProperty("duration");
|
||||
defaultMix = serializedObject.FindProperty("defaultMix");
|
||||
}
|
||||
try {
|
||||
|
||||
spriteCollection = serializedObject.FindProperty("spriteCollection");
|
||||
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 () {
|
||||
m_initialized = false;
|
||||
EditorApplication.update -= Update;
|
||||
this.DestroyPreviewInstances();
|
||||
if (this.m_previewUtility != null) {
|
||||
this.m_previewUtility.Cleanup();
|
||||
this.m_previewUtility = null;
|
||||
}
|
||||
}
|
||||
|
||||
override public void OnInspectorGUI () {
|
||||
serializedObject.Update();
|
||||
SkeletonDataAsset asset = (SkeletonDataAsset)target;
|
||||
|
||||
tk2dSpriteCollection sprites = EditorGUILayout.ObjectField("Sprite Collection", asset.spriteCollection, typeof(tk2dSpriteCollection), false) as tk2dSpriteCollection;
|
||||
if (sprites != null)
|
||||
spriteCollection.objectReferenceValue = sprites.spriteCollection;
|
||||
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.PropertyField(spriteCollection);
|
||||
EditorGUILayout.PropertyField(skeletonJSON);
|
||||
EditorGUILayout.PropertyField(scale);
|
||||
if (EditorGUI.EndChangeCheck()) {
|
||||
if (m_previewUtility != null) {
|
||||
m_previewUtility.Cleanup();
|
||||
m_previewUtility = null;
|
||||
}
|
||||
}
|
||||
|
||||
SkeletonData skeletonData = asset.GetSkeletonData(asset.spriteCollection == null || asset.skeletonJSON == null);
|
||||
if (skeletonData != null) {
|
||||
showAnimationStateData = EditorGUILayout.Foldout(showAnimationStateData, "Animation State Data");
|
||||
if (showAnimationStateData) {
|
||||
EditorGUILayout.PropertyField(defaultMix);
|
||||
|
||||
// Animation names.
|
||||
|
||||
// Animation names
|
||||
String[] animations = new String[skeletonData.Animations.Count];
|
||||
for (int i = 0; i < animations.Length; i++)
|
||||
animations[i] = skeletonData.Animations[i].Name;
|
||||
|
||||
|
||||
for (int i = 0; i < fromAnimation.arraySize; i++) {
|
||||
SerializedProperty from = fromAnimation.GetArrayElementAtIndex(i);
|
||||
SerializedProperty to = toAnimation.GetArrayElementAtIndex(i);
|
||||
@ -95,14 +140,471 @@ public class SkeletonDataAssetInspector : Editor {
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
if (GUILayout.Button(new GUIContent("Setup Pose", SpineEditorUtilities.Icons.skeleton), GUILayout.Width(105), GUILayout.Height(18))) {
|
||||
StopAnimation();
|
||||
m_skeletonAnimation.skeleton.SetToSetupPose();
|
||||
m_requireRefresh = true;
|
||||
}
|
||||
|
||||
#if UNITY_4_3
|
||||
m_showAnimationList = EditorGUILayout.Foldout(m_showAnimationList, new GUIContent("Animations", SpineEditorUtilities.Icons.animationRoot));
|
||||
if(m_showAnimationList){
|
||||
#else
|
||||
m_showAnimationList.target = EditorGUILayout.Foldout(m_showAnimationList.target, new GUIContent("Animations", SpineEditorUtilities.Icons.animationRoot));
|
||||
if (EditorGUILayout.BeginFadeGroup(m_showAnimationList.faded)) {
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
EditorGUILayout.LabelField("Name", "Duration");
|
||||
foreach (Spine.Animation a in skeletonData.Animations) {
|
||||
GUILayout.BeginHorizontal();
|
||||
|
||||
if (m_skeletonAnimation != null && m_skeletonAnimation.state != null) {
|
||||
if (m_skeletonAnimation.state.GetCurrent(0) != null && m_skeletonAnimation.state.GetCurrent(0).Animation == a) {
|
||||
GUI.contentColor = Color.black;
|
||||
if (GUILayout.Button("\u25BA", GUILayout.Width(24))) {
|
||||
StopAnimation();
|
||||
}
|
||||
GUI.contentColor = Color.white;
|
||||
} else {
|
||||
if (GUILayout.Button("\u25BA", GUILayout.Width(24))) {
|
||||
PlayAnimation(a.Name, true);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
GUILayout.Label("?", GUILayout.Width(24));
|
||||
}
|
||||
EditorGUILayout.LabelField(new GUIContent(a.Name, SpineEditorUtilities.Icons.animation), new GUIContent(a.Duration.ToString("f3") + "s" + ("(" + (Mathf.RoundToInt(a.Duration * 30)) + ")").PadLeft(12, ' ')));
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
}
|
||||
#if !UNITY_4_3
|
||||
EditorGUILayout.EndFadeGroup();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
if (!Application.isPlaying) {
|
||||
if (serializedObject.ApplyModifiedProperties() ||
|
||||
(UnityEngine.Event.current.type == EventType.ValidateCommand && UnityEngine.Event.current.commandName == "UndoRedoPerformed")
|
||||
) {
|
||||
) {
|
||||
asset.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//preview window stuff
|
||||
private PreviewRenderUtility m_previewUtility;
|
||||
private GameObject m_previewInstance;
|
||||
private Vector2 previewDir;
|
||||
private SkeletonAnimation m_skeletonAnimation;
|
||||
private SkeletonData m_skeletonData;
|
||||
private static int sliderHash = "Slider".GetHashCode();
|
||||
private float m_lastTime;
|
||||
private bool m_playing;
|
||||
private bool m_requireRefresh;
|
||||
private Color m_originColor = new Color(0.3f, 0.3f, 0.3f, 1);
|
||||
|
||||
private void StopAnimation () {
|
||||
m_skeletonAnimation.state.ClearTrack(0);
|
||||
m_playing = false;
|
||||
}
|
||||
|
||||
List<Spine.Event> m_animEvents = new List<Spine.Event>();
|
||||
List<float> m_animEventFrames = new List<float>();
|
||||
|
||||
private void PlayAnimation (string animName, bool loop) {
|
||||
m_animEvents.Clear();
|
||||
m_animEventFrames.Clear();
|
||||
|
||||
m_skeletonAnimation.state.SetAnimation(0, animName, loop);
|
||||
|
||||
Spine.Animation a = m_skeletonAnimation.state.GetCurrent(0).Animation;
|
||||
foreach (Timeline t in a.Timelines) {
|
||||
if (t.GetType() == typeof(EventTimeline)) {
|
||||
EventTimeline et = (EventTimeline)t;
|
||||
|
||||
for (int i = 0; i < et.Events.Length; i++) {
|
||||
m_animEvents.Add(et.Events[i]);
|
||||
m_animEventFrames.Add(et.Frames[i]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
m_playing = true;
|
||||
}
|
||||
|
||||
private void InitPreview () {
|
||||
if (this.m_previewUtility == null) {
|
||||
this.m_lastTime = Time.realtimeSinceStartup;
|
||||
this.m_previewUtility = new PreviewRenderUtility(true);
|
||||
this.m_previewUtility.m_Camera.isOrthoGraphic = true;
|
||||
this.m_previewUtility.m_Camera.orthographicSize = (scale.floatValue * (m_skeletonDataAsset.spriteCollection.invOrthoSize * m_skeletonDataAsset.spriteCollection.halfTargetHeight)) / 100;
|
||||
this.m_previewUtility.m_Camera.cullingMask = -2147483648;
|
||||
this.CreatePreviewInstances();
|
||||
}
|
||||
}
|
||||
|
||||
private void CreatePreviewInstances () {
|
||||
this.DestroyPreviewInstances();
|
||||
if (this.m_previewInstance == null) {
|
||||
string skinName = EditorPrefs.GetString(m_skeletonDataAssetGUID + "_lastSkin", "");
|
||||
|
||||
m_previewInstance = SpineEditorUtilities.SpawnAnimatedSkeleton((SkeletonDataAsset)target, skinName).gameObject;
|
||||
//m_previewInstance.transform.localScale = Vector3.one * 0.01f;
|
||||
m_previewInstance.hideFlags = HideFlags.HideAndDontSave;
|
||||
m_previewInstance.layer = 0x1f;
|
||||
|
||||
|
||||
m_skeletonAnimation = m_previewInstance.GetComponent<SkeletonAnimation>();
|
||||
m_skeletonAnimation.initialSkinName = skinName;
|
||||
m_skeletonAnimation.LateUpdate();
|
||||
m_skeletonData = m_skeletonAnimation.skeletonDataAsset.GetSkeletonData(true);
|
||||
|
||||
m_previewInstance.renderer.enabled = false;
|
||||
|
||||
m_initialized = true;
|
||||
AdjustCameraGoals(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void DestroyPreviewInstances () {
|
||||
if (this.m_previewInstance != null) {
|
||||
DestroyImmediate(this.m_previewInstance);
|
||||
m_previewInstance = null;
|
||||
}
|
||||
m_initialized = false;
|
||||
}
|
||||
|
||||
public override bool HasPreviewGUI () {
|
||||
//TODO: validate json data
|
||||
return skeletonJSON.objectReferenceValue != null;
|
||||
}
|
||||
|
||||
Texture m_previewTex = new Texture();
|
||||
|
||||
public override void OnInteractivePreviewGUI (Rect r, GUIStyle background) {
|
||||
this.InitPreview();
|
||||
|
||||
if (UnityEngine.Event.current.type == EventType.Repaint) {
|
||||
if (m_requireRefresh) {
|
||||
this.m_previewUtility.BeginPreview(r, background);
|
||||
this.DoRenderPreview(true);
|
||||
this.m_previewTex = this.m_previewUtility.EndPreview();
|
||||
m_requireRefresh = false;
|
||||
}
|
||||
if (this.m_previewTex != null)
|
||||
GUI.DrawTexture(r, m_previewTex, ScaleMode.StretchToFill, false);
|
||||
}
|
||||
|
||||
DrawSkinToolbar(r);
|
||||
NormalizedTimeBar(r);
|
||||
//TODO: implement panning
|
||||
// this.previewDir = Drag2D(this.previewDir, r);
|
||||
MouseScroll(r);
|
||||
}
|
||||
|
||||
float m_orthoGoal = 1;
|
||||
Vector3 m_posGoal = new Vector3(0, 0, -10);
|
||||
double m_adjustFrameEndTime = 0;
|
||||
|
||||
private void AdjustCameraGoals (bool calculateMixTime) {
|
||||
if (calculateMixTime) {
|
||||
if (m_skeletonAnimation.state.GetCurrent(0) != null) {
|
||||
m_adjustFrameEndTime = EditorApplication.timeSinceStartup + m_skeletonAnimation.state.GetCurrent(0).Mix;
|
||||
}
|
||||
}
|
||||
|
||||
GameObject go = this.m_previewInstance;
|
||||
Bounds bounds = go.renderer.bounds;
|
||||
m_orthoGoal = bounds.size.y;
|
||||
m_posGoal = bounds.center + new Vector3(0, 0, -10);
|
||||
}
|
||||
|
||||
private void AdjustCameraGoals () {
|
||||
AdjustCameraGoals(false);
|
||||
}
|
||||
|
||||
private void AdjustCamera () {
|
||||
if (m_previewUtility == null)
|
||||
return;
|
||||
|
||||
|
||||
if (EditorApplication.timeSinceStartup < m_adjustFrameEndTime) {
|
||||
AdjustCameraGoals();
|
||||
}
|
||||
|
||||
float orthoSet = Mathf.Lerp(this.m_previewUtility.m_Camera.orthographicSize, m_orthoGoal, 0.1f);
|
||||
|
||||
this.m_previewUtility.m_Camera.orthographicSize = orthoSet;
|
||||
|
||||
|
||||
float dist = Vector3.Distance(m_previewUtility.m_Camera.transform.position, m_posGoal);
|
||||
if (dist > m_skeletonDataAsset.scale) {
|
||||
Vector3 pos = Vector3.Lerp(this.m_previewUtility.m_Camera.transform.position, m_posGoal, 0.1f);
|
||||
pos.x = 0;
|
||||
this.m_previewUtility.m_Camera.transform.position = pos;
|
||||
this.m_previewUtility.m_Camera.transform.rotation = Quaternion.identity;
|
||||
m_requireRefresh = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void DoRenderPreview (bool drawHandles) {
|
||||
GameObject go = this.m_previewInstance;
|
||||
|
||||
if (m_requireRefresh) {
|
||||
go.renderer.enabled = true;
|
||||
|
||||
if (EditorApplication.isPlaying) {
|
||||
//do nothing
|
||||
} else {
|
||||
m_skeletonAnimation.Update((Time.realtimeSinceStartup - m_lastTime));
|
||||
}
|
||||
|
||||
m_lastTime = Time.realtimeSinceStartup;
|
||||
|
||||
if (!EditorApplication.isPlaying)
|
||||
m_skeletonAnimation.LateUpdate();
|
||||
|
||||
if (drawHandles) {
|
||||
Handles.SetCamera(m_previewUtility.m_Camera);
|
||||
Handles.color = m_originColor;
|
||||
|
||||
Handles.DrawLine(new Vector3(-1000 * m_skeletonDataAsset.scale, 0, 0), new Vector3(1000 * m_skeletonDataAsset.scale, 0, 0));
|
||||
Handles.DrawLine(new Vector3(0, 1000 * m_skeletonDataAsset.scale, 0), new Vector3(0, -1000 * m_skeletonDataAsset.scale, 0));
|
||||
}
|
||||
|
||||
this.m_previewUtility.m_Camera.Render();
|
||||
go.renderer.enabled = false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void Update () {
|
||||
AdjustCamera();
|
||||
|
||||
if (m_playing) {
|
||||
m_requireRefresh = true;
|
||||
Repaint();
|
||||
} else if (m_requireRefresh) {
|
||||
Repaint();
|
||||
} else {
|
||||
#if !UNITY_4_3
|
||||
if (m_showAnimationList.isAnimating)
|
||||
Repaint();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void DrawSkinToolbar (Rect r) {
|
||||
if (m_skeletonAnimation == null)
|
||||
return;
|
||||
|
||||
if (m_skeletonAnimation.skeleton != null) {
|
||||
string label = (m_skeletonAnimation.skeleton != null && m_skeletonAnimation.skeleton.Skin != null) ? m_skeletonAnimation.skeleton.Skin.Name : "default";
|
||||
|
||||
Rect popRect = new Rect(r);
|
||||
popRect.y += 32;
|
||||
popRect.x += 4;
|
||||
popRect.height = 24;
|
||||
popRect.width = 40;
|
||||
EditorGUI.DropShadowLabel(popRect, new GUIContent("Skin", SpineEditorUtilities.Icons.skinsRoot));
|
||||
|
||||
popRect.y += 11;
|
||||
popRect.width = 150;
|
||||
popRect.x += 44;
|
||||
|
||||
if (GUI.Button(popRect, label, EditorStyles.popup)) {
|
||||
SelectSkinContext();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SelectSkinContext () {
|
||||
GenericMenu menu = new GenericMenu();
|
||||
|
||||
foreach (Skin s in m_skeletonData.Skins) {
|
||||
menu.AddItem(new GUIContent(s.Name), this.m_skeletonAnimation.skeleton.Skin == s, SetSkin, (object)s);
|
||||
}
|
||||
|
||||
menu.ShowAsContext();
|
||||
}
|
||||
|
||||
void SetSkin (object o) {
|
||||
Skin skin = (Skin)o;
|
||||
|
||||
m_skeletonAnimation.initialSkinName = skin.Name;
|
||||
m_skeletonAnimation.Reset();
|
||||
m_requireRefresh = true;
|
||||
|
||||
EditorPrefs.SetString(m_skeletonDataAssetGUID + "_lastSkin", skin.Name);
|
||||
}
|
||||
|
||||
void NormalizedTimeBar (Rect r) {
|
||||
Rect barRect = new Rect(r);
|
||||
barRect.height = 32;
|
||||
barRect.x += 4;
|
||||
barRect.width -= 4;
|
||||
|
||||
GUI.Box(barRect, "");
|
||||
|
||||
Rect lineRect = new Rect(barRect);
|
||||
float width = lineRect.width;
|
||||
TrackEntry t = m_skeletonAnimation.state.GetCurrent(0);
|
||||
|
||||
if (t != null) {
|
||||
int loopCount = (int)(t.Time / t.EndTime);
|
||||
float currentTime = t.Time - (t.EndTime * loopCount);
|
||||
|
||||
float normalizedTime = currentTime / t.Animation.Duration;
|
||||
|
||||
lineRect.x = barRect.x + (width * normalizedTime) - 0.5f;
|
||||
lineRect.width = 2;
|
||||
|
||||
GUI.color = Color.red;
|
||||
GUI.DrawTexture(lineRect, EditorGUIUtility.whiteTexture);
|
||||
GUI.color = Color.white;
|
||||
|
||||
for (int i = 0; i < m_animEvents.Count; i++) {
|
||||
//TODO: Tooltip
|
||||
//Spine.Event spev = animEvents[i];
|
||||
|
||||
float fr = m_animEventFrames[i];
|
||||
|
||||
Rect evRect = new Rect(barRect);
|
||||
evRect.x = Mathf.Clamp(((fr / t.Animation.Duration) * width) - (SpineEditorUtilities.Icons._event.width / 2), barRect.x, float.MaxValue);
|
||||
evRect.width = SpineEditorUtilities.Icons._event.width;
|
||||
evRect.height = SpineEditorUtilities.Icons._event.height;
|
||||
evRect.y += SpineEditorUtilities.Icons._event.height;
|
||||
GUI.DrawTexture(evRect, SpineEditorUtilities.Icons._event);
|
||||
|
||||
|
||||
//TODO: Tooltip
|
||||
/*
|
||||
UnityEngine.Event ev = UnityEngine.Event.current;
|
||||
if(ev.isMouse){
|
||||
if(evRect.Contains(ev.mousePosition)){
|
||||
Rect tooltipRect = new Rect(evRect);
|
||||
tooltipRect.width = 500;
|
||||
tooltipRect.y -= 4;
|
||||
tooltipRect.x += 4;
|
||||
GUI.Label(tooltipRect, spev.Data.Name);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MouseScroll (Rect position) {
|
||||
UnityEngine.Event current = UnityEngine.Event.current;
|
||||
int controlID = GUIUtility.GetControlID(sliderHash, FocusType.Passive);
|
||||
|
||||
switch (current.GetTypeForControl(controlID)) {
|
||||
case EventType.ScrollWheel:
|
||||
if (position.Contains(current.mousePosition)) {
|
||||
|
||||
m_orthoGoal += current.delta.y * ((SkeletonDataAsset)target).scale * 10;
|
||||
GUIUtility.hotControl = controlID;
|
||||
current.Use();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//TODO: Implement preview panning
|
||||
/*
|
||||
static Vector2 Drag2D(Vector2 scrollPosition, Rect position)
|
||||
{
|
||||
int controlID = GUIUtility.GetControlID(sliderHash, FocusType.Passive);
|
||||
UnityEngine.Event current = UnityEngine.Event.current;
|
||||
switch (current.GetTypeForControl(controlID))
|
||||
{
|
||||
case EventType.MouseDown:
|
||||
if (position.Contains(current.mousePosition) && (position.width > 50f))
|
||||
{
|
||||
GUIUtility.hotControl = controlID;
|
||||
current.Use();
|
||||
EditorGUIUtility.SetWantsMouseJumping(1);
|
||||
}
|
||||
return scrollPosition;
|
||||
|
||||
case EventType.MouseUp:
|
||||
if (GUIUtility.hotControl == controlID)
|
||||
{
|
||||
GUIUtility.hotControl = 0;
|
||||
}
|
||||
EditorGUIUtility.SetWantsMouseJumping(0);
|
||||
return scrollPosition;
|
||||
|
||||
case EventType.MouseMove:
|
||||
return scrollPosition;
|
||||
|
||||
case EventType.MouseDrag:
|
||||
if (GUIUtility.hotControl == controlID)
|
||||
{
|
||||
scrollPosition -= (Vector2) (((current.delta * (!current.shift ? ((float) 1) : ((float) 3))) / Mathf.Min(position.width, position.height)) * 140f);
|
||||
scrollPosition.y = Mathf.Clamp(scrollPosition.y, -90f, 90f);
|
||||
current.Use();
|
||||
GUI.changed = true;
|
||||
}
|
||||
return scrollPosition;
|
||||
}
|
||||
return scrollPosition;
|
||||
}
|
||||
*/
|
||||
|
||||
public override GUIContent GetPreviewTitle () {
|
||||
return new GUIContent("Preview");
|
||||
}
|
||||
|
||||
public override void OnPreviewSettings () {
|
||||
if (!m_initialized) {
|
||||
GUILayout.HorizontalSlider(0, 0, 2, GUILayout.MaxWidth(64));
|
||||
} else {
|
||||
float speed = GUILayout.HorizontalSlider(m_skeletonAnimation.timeScale, 0, 2, GUILayout.MaxWidth(64));
|
||||
|
||||
//snap to nearest 0.25
|
||||
float y = speed / 0.25f;
|
||||
int q = Mathf.RoundToInt(y);
|
||||
speed = q * 0.25f;
|
||||
|
||||
m_skeletonAnimation.timeScale = speed;
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: Fix first-import error
|
||||
//TODO: Update preview without thumbnail
|
||||
public override Texture2D RenderStaticPreview (string assetPath, UnityEngine.Object[] subAssets, int width, int height) {
|
||||
Texture2D tex = new Texture2D(width, height, TextureFormat.ARGB32, false);
|
||||
|
||||
this.InitPreview();
|
||||
|
||||
if (this.m_previewUtility.m_Camera == null)
|
||||
return null;
|
||||
|
||||
m_requireRefresh = true;
|
||||
this.DoRenderPreview(false);
|
||||
AdjustCameraGoals(false);
|
||||
|
||||
this.m_previewUtility.m_Camera.orthographicSize = m_orthoGoal / 2;
|
||||
this.m_previewUtility.m_Camera.transform.position = m_posGoal;
|
||||
this.m_previewUtility.BeginStaticPreview(new Rect(0, 0, width, height));
|
||||
this.DoRenderPreview(false);
|
||||
|
||||
//TODO: Figure out why this is throwing errors on first attempt
|
||||
// if(m_previewUtility != null){
|
||||
// Handles.SetCamera(this.m_previewUtility.m_Camera);
|
||||
// Handles.BeginGUI();
|
||||
// GUI.DrawTexture(new Rect(40,60,width,height), SpineEditorUtilities.Icons.spine, ScaleMode.StretchToFill);
|
||||
// Handles.EndGUI();
|
||||
// }
|
||||
tex = this.m_previewUtility.EndStaticPreview();
|
||||
return tex;
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cffb121e3cd80644d84c585b9c7448e8
|
||||
guid: 01cbef8f24d105f4bafa9668d669e040
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
|
||||
268
spine-tk2d/Assets/spine-tk2d/Editor/SpineEditorUtilities.cs
Normal file
@ -0,0 +1,268 @@
|
||||
#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;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Spine;
|
||||
|
||||
[InitializeOnLoad]
|
||||
public class SpineEditorUtilities : AssetPostprocessor {
|
||||
|
||||
public static class Icons {
|
||||
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;
|
||||
public static Texture2D image;
|
||||
public static Texture2D boundingBox;
|
||||
public static Texture2D mesh;
|
||||
public static Texture2D skin;
|
||||
public static Texture2D skinsRoot;
|
||||
public static Texture2D animation;
|
||||
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 {
|
||||
if (_boneMesh == null) {
|
||||
_boneMesh = new Mesh();
|
||||
_boneMesh.vertices = new Vector3[4] {
|
||||
Vector3.zero,
|
||||
new Vector3(-0.1f, 0.1f, 0),
|
||||
Vector3.up,
|
||||
new Vector3(0.1f, 0.1f, 0)
|
||||
};
|
||||
_boneMesh.uv = new Vector2[4];
|
||||
_boneMesh.triangles = new int[6]{0,1,2,2,3,0};
|
||||
_boneMesh.RecalculateBounds();
|
||||
_boneMesh.RecalculateNormals();
|
||||
}
|
||||
|
||||
return _boneMesh;
|
||||
}
|
||||
}
|
||||
|
||||
internal static Mesh _boneMesh;
|
||||
|
||||
public static Material boneMaterial {
|
||||
get {
|
||||
if (_boneMaterial == null) {
|
||||
#if UNITY_4_3
|
||||
_boneMaterial = new Material(Shader.Find("Particles/Alpha Blended"));
|
||||
_boneMaterial.SetColor("_TintColor", new Color(0.4f, 0.4f, 0.4f, 0.25f));
|
||||
#else
|
||||
_boneMaterial = new Material(Shader.Find("Spine/Bones"));
|
||||
_boneMaterial.SetColor("_Color", new Color(0.4f, 0.4f, 0.4f, 0.25f));
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
return _boneMaterial;
|
||||
}
|
||||
}
|
||||
|
||||
internal static Material _boneMaterial;
|
||||
|
||||
public static void Initialize () {
|
||||
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");
|
||||
image = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-image.png");
|
||||
boundingBox = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-boundingBox.png");
|
||||
mesh = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-mesh.png");
|
||||
skin = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-skinPlaceholder.png");
|
||||
skinsRoot = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-skinsRoot.png");
|
||||
animation = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-animation.png");
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
public static string editorPath = "";
|
||||
public static string editorGUIPath = "";
|
||||
static Dictionary<int, GameObject> skeletonRendererTable;
|
||||
static Dictionary<int, SkeletonUtilityBone> skeletonUtilityBoneTable;
|
||||
public static float defaultScale = 0.01f;
|
||||
public static float defaultMix = 0.2f;
|
||||
public static string defaultShader = "Spine/Skeleton";
|
||||
|
||||
static SpineEditorUtilities () {
|
||||
DirectoryInfo rootDir = new DirectoryInfo(Application.dataPath);
|
||||
FileInfo[] files = rootDir.GetFiles("SpineEditorUtilities.cs", SearchOption.AllDirectories);
|
||||
editorPath = Path.GetDirectoryName(files[0].FullName.Replace("\\", "/").Replace(Application.dataPath, "Assets"));
|
||||
editorGUIPath = editorPath + "/GUI";
|
||||
|
||||
Icons.Initialize();
|
||||
|
||||
skeletonRendererTable = new Dictionary<int, GameObject>();
|
||||
skeletonUtilityBoneTable = new Dictionary<int, SkeletonUtilityBone>();
|
||||
|
||||
EditorApplication.hierarchyWindowChanged += HierarchyWindowChanged;
|
||||
EditorApplication.hierarchyWindowItemOnGUI += HierarchyWindowItemOnGUI;
|
||||
|
||||
HierarchyWindowChanged();
|
||||
}
|
||||
|
||||
static void HierarchyWindowChanged () {
|
||||
skeletonRendererTable.Clear();
|
||||
skeletonUtilityBoneTable.Clear();
|
||||
|
||||
SkeletonRenderer[] arr = Object.FindObjectsOfType<SkeletonRenderer>();
|
||||
|
||||
foreach (SkeletonRenderer r in arr)
|
||||
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 (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 -= 26;
|
||||
|
||||
if (skeletonUtilityBoneTable[instanceId] != null) {
|
||||
if (skeletonUtilityBoneTable[instanceId].transform.childCount == 0)
|
||||
r.x += 13;
|
||||
|
||||
r.y += 2;
|
||||
|
||||
r.width = 13;
|
||||
r.height = 13;
|
||||
|
||||
if (skeletonUtilityBoneTable[instanceId].mode == SkeletonUtilityBone.Mode.Follow) {
|
||||
GUI.DrawTexture(r, Icons.bone);
|
||||
} else {
|
||||
GUI.DrawTexture(r, Icons.poseBones);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[MenuItem("Assets/Spine/Spawn")]
|
||||
static void SpawnAnimatedSkeleton () {
|
||||
Object[] arr = Selection.objects;
|
||||
foreach (Object o in arr) {
|
||||
string guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(o));
|
||||
string skinName = EditorPrefs.GetString(guid + "_lastSkin", "");
|
||||
|
||||
SpawnAnimatedSkeleton((SkeletonDataAsset)o, skinName);
|
||||
SceneView.RepaintAll();
|
||||
}
|
||||
}
|
||||
|
||||
[MenuItem("Assets/Spine/Spawn", true)]
|
||||
static bool ValidateSpawnAnimatedSkeleton () {
|
||||
Object[] arr = Selection.objects;
|
||||
|
||||
if (arr.Length == 0)
|
||||
return false;
|
||||
|
||||
foreach (Object o in arr) {
|
||||
if (o.GetType() != typeof(SkeletonDataAsset))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static SkeletonAnimation SpawnAnimatedSkeleton (SkeletonDataAsset skeletonDataAsset, string skinName) {
|
||||
return SpawnAnimatedSkeleton(skeletonDataAsset, skeletonDataAsset.GetSkeletonData(true).FindSkin(skinName));
|
||||
}
|
||||
|
||||
public static SkeletonAnimation SpawnAnimatedSkeleton (SkeletonDataAsset skeletonDataAsset, Skin skin = null) {
|
||||
GameObject go = new GameObject(skeletonDataAsset.name.Replace("_SkeletonData", ""), typeof(MeshFilter), typeof(MeshRenderer), typeof(SkeletonAnimation));
|
||||
SkeletonAnimation anim = go.GetComponent<SkeletonAnimation>();
|
||||
anim.skeletonDataAsset = skeletonDataAsset;
|
||||
|
||||
|
||||
|
||||
SkeletonData data = skeletonDataAsset.GetSkeletonData(true);
|
||||
|
||||
if (data == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (skin == null)
|
||||
skin = data.DefaultSkin;
|
||||
|
||||
if (skin == null)
|
||||
skin = data.Skins[0];
|
||||
|
||||
anim.Reset();
|
||||
|
||||
anim.skeleton.SetSkin(skin);
|
||||
anim.initialSkinName = skin.Name;
|
||||
|
||||
anim.skeleton.Update(1);
|
||||
anim.state.Update(1);
|
||||
anim.state.Apply(anim.skeleton);
|
||||
anim.skeleton.UpdateWorldTransform();
|
||||
|
||||
return anim;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f834d5cd806ec4645915ac315edbdc60
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
69
spine-tk2d/Assets/spine-tk2d/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-tk2d/Assets/spine-tk2d/Shaders/Bones.shader.meta
Normal file
@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 66988de88a15abd4e8846c6805485f57
|
||||
ShaderImporter:
|
||||
defaultTextures: []
|
||||
userData:
|
||||
BIN
spine-tk2d/Assets/spine-tk2d/Shaders/HiddenPass.mat
Normal file
4
spine-tk2d/Assets/spine-tk2d/Shaders/HiddenPass.mat.meta
Normal file
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 43227e5adadc6f24bb4bf74b92a56fb4
|
||||
NativeFormatImporter:
|
||||
userData:
|
||||
21
spine-tk2d/Assets/spine-tk2d/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:
|
||||
@ -41,18 +41,23 @@ public class SkeletonAnimation : SkeletonRenderer {
|
||||
public bool loop;
|
||||
public Spine.AnimationState state;
|
||||
|
||||
public delegate void UpdateBonesDelegate(SkeletonAnimation skeleton);
|
||||
public UpdateBonesDelegate UpdateBones;
|
||||
public delegate void UpdateBonesDelegate (SkeletonAnimation skeleton);
|
||||
|
||||
public UpdateBonesDelegate UpdateLocal;
|
||||
public UpdateBonesDelegate UpdateWorld;
|
||||
public UpdateBonesDelegate UpdateComplete;
|
||||
[SerializeField]
|
||||
private String _animationName;
|
||||
private String
|
||||
_animationName;
|
||||
|
||||
public String AnimationName {
|
||||
get {
|
||||
TrackEntry entry = state.GetCurrent(0);
|
||||
return entry == null ? null : entry.Animation.Name;
|
||||
}
|
||||
set {
|
||||
if (_animationName == value) return;
|
||||
if (_animationName == value)
|
||||
return;
|
||||
_animationName = value;
|
||||
if (value == null || value.Length == 0)
|
||||
state.ClearTrack(0);
|
||||
@ -63,7 +68,8 @@ public class SkeletonAnimation : SkeletonRenderer {
|
||||
|
||||
public override void Reset () {
|
||||
base.Reset();
|
||||
if (!valid) return;
|
||||
if (!valid)
|
||||
return;
|
||||
|
||||
state = new Spine.AnimationState(skeletonDataAsset.GetAnimationStateData());
|
||||
if (_animationName != null && _animationName.Length > 0) {
|
||||
@ -77,13 +83,26 @@ public class SkeletonAnimation : SkeletonRenderer {
|
||||
}
|
||||
|
||||
public virtual void Update (float deltaTime) {
|
||||
if (!valid) return;
|
||||
if (!valid)
|
||||
return;
|
||||
|
||||
deltaTime *= timeScale;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -53,14 +53,14 @@ public class SkeletonDataAsset : ScriptableObject {
|
||||
public SkeletonData GetSkeletonData (bool quiet) {
|
||||
if (spriteCollection == null) {
|
||||
if (!quiet)
|
||||
Debug.LogError("Sprite collection not set for skeleton data asset: " + name, this);
|
||||
Debug.LogError("SpriteCollection not set for SkeletonData asset: " + name, this);
|
||||
Reset();
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
if (skeletonJSON == null) {
|
||||
if (!quiet)
|
||||
Debug.LogError("Skeleton JSON file not set for skeleton data asset: " + name, this);
|
||||
Debug.LogError("Skeleton JSON file not set for SkeletonData asset: " + name, this);
|
||||
Reset();
|
||||
return null;
|
||||
}
|
||||
@ -81,7 +81,8 @@ public class SkeletonDataAsset : ScriptableObject {
|
||||
stateData = new AnimationStateData(skeletonData);
|
||||
stateData.DefaultMix = defaultMix;
|
||||
for (int i = 0, n = fromAnimation.Length; i < n; i++) {
|
||||
if (fromAnimation[i].Length == 0 || toAnimation[i].Length == 0) continue;
|
||||
if (fromAnimation[i].Length == 0 || toAnimation[i].Length == 0)
|
||||
continue;
|
||||
stateData.SetMix(fromAnimation[i], toAnimation[i], duration[i]);
|
||||
}
|
||||
|
||||
|
||||
108
spine-tk2d/Assets/spine-tk2d/SkeletonExtensions.cs
Normal file
@ -0,0 +1,108 @@
|
||||
/******************************************************************************
|
||||
* 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;
|
||||
|
||||
public static class SkeletonExtensions {
|
||||
|
||||
public static void SetColor (this Slot slot, Color color) {
|
||||
slot.A = color.a;
|
||||
slot.R = color.r;
|
||||
slot.G = color.g;
|
||||
slot.B = color.b;
|
||||
}
|
||||
|
||||
public static void SetColor (this Slot slot, Color32 color) {
|
||||
slot.A = color.a / 255f;
|
||||
slot.R = color.r / 255f;
|
||||
slot.G = color.g / 255f;
|
||||
slot.B = color.b / 255f;
|
||||
}
|
||||
|
||||
public static void SetColor (this RegionAttachment attachment, Color color) {
|
||||
attachment.A = color.a;
|
||||
attachment.R = color.r;
|
||||
attachment.G = color.g;
|
||||
attachment.B = color.b;
|
||||
}
|
||||
|
||||
public static void SetColor (this RegionAttachment attachment, Color32 color) {
|
||||
attachment.A = color.a / 255f;
|
||||
attachment.R = color.r / 255f;
|
||||
attachment.G = color.g / 255f;
|
||||
attachment.B = color.b / 255f;
|
||||
}
|
||||
|
||||
public static void SetColor (this MeshAttachment attachment, Color color) {
|
||||
attachment.A = color.a;
|
||||
attachment.R = color.r;
|
||||
attachment.G = color.g;
|
||||
attachment.B = color.b;
|
||||
}
|
||||
|
||||
public static void SetColor (this MeshAttachment attachment, Color32 color) {
|
||||
attachment.A = color.a / 255f;
|
||||
attachment.R = color.r / 255f;
|
||||
attachment.G = color.g / 255f;
|
||||
attachment.B = color.b / 255f;
|
||||
}
|
||||
|
||||
public static void SetColor (this SkinnedMeshAttachment attachment, Color color) {
|
||||
attachment.A = color.a;
|
||||
attachment.R = color.r;
|
||||
attachment.G = color.g;
|
||||
attachment.B = color.b;
|
||||
}
|
||||
|
||||
public static void SetColor (this SkinnedMeshAttachment attachment, Color32 color) {
|
||||
attachment.A = color.a / 255f;
|
||||
attachment.R = color.r / 255f;
|
||||
attachment.G = color.g / 255f;
|
||||
attachment.B = color.b / 255f;
|
||||
}
|
||||
|
||||
public static void SetPosition (this Bone bone, Vector2 position) {
|
||||
bone.X = position.x;
|
||||
bone.Y = position.y;
|
||||
}
|
||||
|
||||
public static void SetPosition (this Bone bone, Vector3 position) {
|
||||
bone.X = position.x;
|
||||
bone.Y = position.y;
|
||||
}
|
||||
|
||||
}
|
||||
8
spine-tk2d/Assets/spine-tk2d/SkeletonExtensions.cs.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ea85c8f6a91a6ab45881b0dbdaabb7d0
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@ -37,17 +37,20 @@ 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]
|
||||
public Skeleton skeleton;
|
||||
|
||||
public SkeletonDataAsset skeletonDataAsset;
|
||||
public String initialSkinName;
|
||||
public bool calculateNormals, calculateTangents;
|
||||
public float zSpacing;
|
||||
public bool renderMeshes = true, immutableTriangles;
|
||||
|
||||
public bool logErrors = false;
|
||||
private MeshFilter meshFilter;
|
||||
private Mesh mesh, mesh1, mesh2;
|
||||
private bool useMesh1;
|
||||
@ -61,9 +64,12 @@ public class SkeletonRenderer : MonoBehaviour {
|
||||
private readonly List<Submesh> submeshes = new List<Submesh>();
|
||||
|
||||
public virtual void Reset () {
|
||||
if (meshFilter != null) meshFilter.sharedMesh = null;
|
||||
if (mesh != null) DestroyImmediate(mesh);
|
||||
if (renderer != null) renderer.sharedMaterial = null;
|
||||
if (meshFilter != null)
|
||||
meshFilter.sharedMesh = null;
|
||||
if (mesh != null)
|
||||
DestroyImmediate(mesh);
|
||||
if (renderer != null)
|
||||
renderer.sharedMaterial = null;
|
||||
mesh = null;
|
||||
mesh1 = null;
|
||||
mesh2 = null;
|
||||
@ -78,11 +84,14 @@ public class SkeletonRenderer : MonoBehaviour {
|
||||
|
||||
valid = false;
|
||||
if (!skeletonDataAsset) {
|
||||
Debug.LogError("Missing SkeletonData asset.", this);
|
||||
if (logErrors)
|
||||
Debug.LogError("Missing SkeletonData asset.", this);
|
||||
|
||||
return;
|
||||
}
|
||||
SkeletonData skeletonData = skeletonDataAsset.GetSkeletonData(false);
|
||||
if (skeletonData == null) return;
|
||||
if (skeletonData == null)
|
||||
return;
|
||||
valid = true;
|
||||
|
||||
meshFilter = GetComponent<MeshFilter>();
|
||||
@ -93,6 +102,8 @@ 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 () {
|
||||
@ -108,8 +119,8 @@ public class SkeletonRenderer : MonoBehaviour {
|
||||
}
|
||||
|
||||
public virtual void LateUpdate () {
|
||||
if (!valid) return;
|
||||
|
||||
if (!valid)
|
||||
return;
|
||||
// Count vertices and submesh triangles.
|
||||
int vertexCount = 0;
|
||||
int submeshTriangleCount = 0, submeshFirstVertex = 0, submeshStartSlotIndex = 0;
|
||||
@ -119,7 +130,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;
|
||||
@ -129,24 +141,25 @@ public class SkeletonRenderer : MonoBehaviour {
|
||||
attachmentVertexCount = 4;
|
||||
attachmentTriangleCount = 6;
|
||||
} else {
|
||||
if (!renderMeshes) continue;
|
||||
if (!renderMeshes)
|
||||
continue;
|
||||
if (attachment is MeshAttachment) {
|
||||
MeshAttachment meshAttachment = (MeshAttachment)attachment;
|
||||
rendererObject = meshAttachment.RendererObject;
|
||||
attachmentVertexCount = meshAttachment.vertices.Length >> 1;
|
||||
attachmentTriangleCount = meshAttachment.triangles.Length;
|
||||
} else if (attachment is SkinnedMeshAttachment) {
|
||||
SkinnedMeshAttachment meshAttachment = (SkinnedMeshAttachment)attachment;
|
||||
rendererObject = meshAttachment.RendererObject;
|
||||
attachmentVertexCount = meshAttachment.uvs.Length >> 1;
|
||||
attachmentTriangleCount = meshAttachment.triangles.Length;
|
||||
} else
|
||||
continue;
|
||||
SkinnedMeshAttachment meshAttachment = (SkinnedMeshAttachment)attachment;
|
||||
rendererObject = meshAttachment.RendererObject;
|
||||
attachmentVertexCount = meshAttachment.uvs.Length >> 1;
|
||||
attachmentTriangleCount = meshAttachment.triangles.Length;
|
||||
} else
|
||||
continue;
|
||||
}
|
||||
|
||||
// Populate submesh when material changes.
|
||||
Material material = (Material)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;
|
||||
@ -209,7 +222,8 @@ public class SkeletonRenderer : MonoBehaviour {
|
||||
color.r = (byte)(r * slot.r * regionAttachment.r * color.a);
|
||||
color.g = (byte)(g * slot.g * regionAttachment.g * color.a);
|
||||
color.b = (byte)(b * slot.b * regionAttachment.b * color.a);
|
||||
if (slot.data.additiveBlending) color.a = 0;
|
||||
if (slot.data.additiveBlending)
|
||||
color.a = 0;
|
||||
colors[vertexIndex] = color;
|
||||
colors[vertexIndex + 1] = color;
|
||||
colors[vertexIndex + 2] = color;
|
||||
@ -223,18 +237,21 @@ public class SkeletonRenderer : MonoBehaviour {
|
||||
|
||||
vertexIndex += 4;
|
||||
} else {
|
||||
if (!renderMeshes) continue;
|
||||
if (!renderMeshes)
|
||||
continue;
|
||||
if (attachment is MeshAttachment) {
|
||||
MeshAttachment meshAttachment = (MeshAttachment)attachment;
|
||||
int meshVertexCount = meshAttachment.vertices.Length;
|
||||
if (tempVertices.Length < meshVertexCount) tempVertices = new float[meshVertexCount];
|
||||
if (tempVertices.Length < meshVertexCount)
|
||||
tempVertices = new float[meshVertexCount];
|
||||
meshAttachment.ComputeWorldVertices(slot, tempVertices);
|
||||
|
||||
color.a = (byte)(a * slot.a * meshAttachment.a);
|
||||
color.r = (byte)(r * slot.r * meshAttachment.r * color.a);
|
||||
color.g = (byte)(g * slot.g * meshAttachment.g * color.a);
|
||||
color.b = (byte)(b * slot.b * meshAttachment.b * color.a);
|
||||
if (slot.data.additiveBlending) color.a = 0;
|
||||
if (slot.data.additiveBlending)
|
||||
color.a = 0;
|
||||
|
||||
float[] meshUVs = meshAttachment.uvs;
|
||||
float z = i * zSpacing;
|
||||
@ -244,25 +261,27 @@ public class SkeletonRenderer : MonoBehaviour {
|
||||
uvs[vertexIndex] = new Vector2(meshUVs[ii], meshUVs[ii + 1]);
|
||||
}
|
||||
} else if (attachment is SkinnedMeshAttachment) {
|
||||
SkinnedMeshAttachment meshAttachment = (SkinnedMeshAttachment)attachment;
|
||||
int meshVertexCount = meshAttachment.uvs.Length;
|
||||
if (tempVertices.Length < meshVertexCount) tempVertices = new float[meshVertexCount];
|
||||
meshAttachment.ComputeWorldVertices(slot, tempVertices);
|
||||
SkinnedMeshAttachment meshAttachment = (SkinnedMeshAttachment)attachment;
|
||||
int meshVertexCount = meshAttachment.uvs.Length;
|
||||
if (tempVertices.Length < meshVertexCount)
|
||||
tempVertices = new float[meshVertexCount];
|
||||
meshAttachment.ComputeWorldVertices(slot, tempVertices);
|
||||
|
||||
color.a = (byte)(a * slot.a * meshAttachment.a);
|
||||
color.r = (byte)(r * slot.r * meshAttachment.r * color.a);
|
||||
color.g = (byte)(g * slot.g * meshAttachment.g * color.a);
|
||||
color.b = (byte)(b * slot.b * meshAttachment.b * color.a);
|
||||
if (slot.data.additiveBlending) color.a = 0;
|
||||
color.a = (byte)(a * slot.a * meshAttachment.a);
|
||||
color.r = (byte)(r * slot.r * meshAttachment.r * color.a);
|
||||
color.g = (byte)(g * slot.g * meshAttachment.g * color.a);
|
||||
color.b = (byte)(b * slot.b * meshAttachment.b * color.a);
|
||||
if (slot.data.additiveBlending)
|
||||
color.a = 0;
|
||||
|
||||
float[] meshUVs = meshAttachment.uvs;
|
||||
float z = i * zSpacing;
|
||||
for (int ii = 0; ii < meshVertexCount; ii += 2, vertexIndex++) {
|
||||
vertices[vertexIndex] = new Vector3(tempVertices[ii], tempVertices[ii + 1], z);
|
||||
colors[vertexIndex] = color;
|
||||
uvs[vertexIndex] = new Vector2(meshUVs[ii], meshUVs[ii + 1]);
|
||||
float[] meshUVs = meshAttachment.uvs;
|
||||
float z = i * zSpacing;
|
||||
for (int ii = 0; ii < meshVertexCount; ii += 2, vertexIndex++) {
|
||||
vertices[vertexIndex] = new Vector3(tempVertices[ii], tempVertices[ii + 1], z);
|
||||
colors[vertexIndex] = color;
|
||||
uvs[vertexIndex] = new Vector2(meshUVs[ii], meshUVs[ii + 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -310,7 +329,7 @@ public class SkeletonRenderer : MonoBehaviour {
|
||||
if (submeshes.Count <= submeshIndex)
|
||||
submeshes.Add(new Submesh());
|
||||
else if (immutableTriangles)
|
||||
return;
|
||||
return;
|
||||
|
||||
Submesh submesh = submeshes[submeshIndex];
|
||||
|
||||
@ -322,10 +341,10 @@ public class SkeletonRenderer : MonoBehaviour {
|
||||
triangles[i] = 0;
|
||||
submesh.triangleCount = triangleCount;
|
||||
} else if (trianglesCapacity != triangleCount) {
|
||||
// Reallocate triangles when not the exact size needed.
|
||||
submesh.triangles = triangles = new int[triangleCount];
|
||||
submesh.triangleCount = 0;
|
||||
}
|
||||
// Reallocate triangles when not the exact size needed.
|
||||
submesh.triangles = triangles = new int[triangleCount];
|
||||
submesh.triangleCount = 0;
|
||||
}
|
||||
|
||||
if (!renderMeshes) {
|
||||
// Use stored triangles if possible.
|
||||
@ -366,18 +385,18 @@ public class SkeletonRenderer : MonoBehaviour {
|
||||
attachmentVertexCount = meshAttachment.vertices.Length >> 1;
|
||||
attachmentTriangles = meshAttachment.triangles;
|
||||
} else if (attachment is SkinnedMeshAttachment) {
|
||||
SkinnedMeshAttachment meshAttachment = (SkinnedMeshAttachment)attachment;
|
||||
attachmentVertexCount = meshAttachment.uvs.Length >> 1;
|
||||
attachmentTriangles = meshAttachment.triangles;
|
||||
} else
|
||||
continue;
|
||||
SkinnedMeshAttachment meshAttachment = (SkinnedMeshAttachment)attachment;
|
||||
attachmentVertexCount = meshAttachment.uvs.Length >> 1;
|
||||
attachmentTriangles = meshAttachment.triangles;
|
||||
} else
|
||||
continue;
|
||||
for (int ii = 0, nn = attachmentTriangles.Length; ii < nn; ii++, triangleIndex++)
|
||||
triangles[triangleIndex] = firstVertex + attachmentTriangles[ii];
|
||||
firstVertex += attachmentVertexCount;
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
#if UNITY_EDITOR
|
||||
void OnDrawGizmos() {
|
||||
// Make selection easier by drawing a clear gizmo over the skeleton.
|
||||
if (vertices == null) return;
|
||||
@ -397,7 +416,7 @@ public class SkeletonRenderer : MonoBehaviour {
|
||||
Gizmos.matrix = transform.localToWorldMatrix;
|
||||
Gizmos.DrawCube(gizmosCenter, gizmosSize);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
class Submesh {
|
||||
|
||||
5
spine-tk2d/Assets/spine-tk2d/SkeletonUtility.meta
Normal file
@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f6e0caaafe294de48af468a6a9321473
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
5
spine-tk2d/Assets/spine-tk2d/SkeletonUtility/Editor.meta
Normal file
@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a751a9d1e3e26d64d997b66a781df8e9
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
@ -0,0 +1,304 @@
|
||||
/******************************************************************************
|
||||
* 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, flip, flipX;
|
||||
|
||||
//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");
|
||||
flip = this.serializedObject.FindProperty("flip");
|
||||
flipX = this.serializedObject.FindProperty("flipX");
|
||||
|
||||
EvaluateFlags();
|
||||
|
||||
if (utilityBone.valid == false && skeletonUtility != null && skeletonUtility.skeletonRenderer != null) {
|
||||
skeletonUtility.skeletonRenderer.Reset();
|
||||
}
|
||||
|
||||
canCreateHingeChain = CanCreateHingeChain();
|
||||
}
|
||||
|
||||
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);
|
||||
EditorGUILayout.PropertyField(flip);
|
||||
|
||||
EditorGUI.BeginDisabledGroup(containsFollows);
|
||||
{
|
||||
EditorGUILayout.PropertyField(overrideAlpha);
|
||||
EditorGUILayout.PropertyField(parentReference);
|
||||
|
||||
EditorGUI.BeginDisabledGroup(multiObject || !flip.boolValue);
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.PropertyField(flipX);
|
||||
if (EditorGUI.EndChangeCheck()) {
|
||||
FlipX(flipX.boolValue);
|
||||
}
|
||||
}
|
||||
EditorGUI.EndDisabledGroup();
|
||||
|
||||
}
|
||||
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 FlipX (bool state) {
|
||||
utilityBone.FlipX(state);
|
||||
if (Application.isPlaying == false) {
|
||||
skeletonUtility.skeletonAnimation.LateUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
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,311 @@
|
||||
/******************************************************************************
|
||||
* 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:
|
||||
346
spine-tk2d/Assets/spine-tk2d/SkeletonUtility/SkeletonUtility.cs
Normal file
@ -0,0 +1,346 @@
|
||||
/******************************************************************************
|
||||
* 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 static T GetInParent<T> (Transform origin) where T : Component {
|
||||
#if UNITY_4_3
|
||||
Transform parent = origin.parent;
|
||||
while(parent.GetComponent<T>() == null){
|
||||
parent = parent.parent;
|
||||
if(parent == null)
|
||||
return default(T);
|
||||
}
|
||||
|
||||
return parent.GetComponent<T>();
|
||||
#else
|
||||
return origin.GetComponentInParent<T>();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
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,293 @@
|
||||
/******************************************************************************
|
||||
* 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;
|
||||
public bool flip;
|
||||
public bool flipX;
|
||||
[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 = SkeletonUtility.GetInParent<SkeletonUtility>(transform);
|
||||
|
||||
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 skeletonFlipRotation = (skeleton.flipX ^ skeleton.flipY) ? -1f : 1f;
|
||||
|
||||
float flipCompensation = 0;
|
||||
if (flip && (flipX || (flipX != bone.flipX)) && bone.parent != null) {
|
||||
flipCompensation = bone.parent.WorldRotation * -2;
|
||||
}
|
||||
|
||||
if (mode == Mode.Follow) {
|
||||
if (flip) {
|
||||
flipX = bone.flipX;
|
||||
}
|
||||
|
||||
|
||||
if (position) {
|
||||
cachedTransform.localPosition = new Vector3(bone.x, bone.y, 0);
|
||||
}
|
||||
|
||||
if (rotation) {
|
||||
|
||||
if (bone.Data.InheritRotation) {
|
||||
if (bone.FlipX) {
|
||||
cachedTransform.localRotation = Quaternion.Euler(0, 180, bone.rotationIK - flipCompensation);
|
||||
} else {
|
||||
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 * skeletonFlipRotation));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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) {
|
||||
float angle = Mathf.LerpAngle(bone.Rotation, cachedTransform.localRotation.eulerAngles.z, overrideAlpha) + flipCompensation;
|
||||
|
||||
if (flip) {
|
||||
if ((!flipX && bone.flipX)) {
|
||||
angle -= flipCompensation;
|
||||
}
|
||||
|
||||
//TODO fix this...
|
||||
if (angle >= 360)
|
||||
angle -= 360;
|
||||
else if (angle <= -360)
|
||||
angle += 360;
|
||||
}
|
||||
|
||||
bone.Rotation = angle;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if (flip) {
|
||||
bone.flipX = flipX;
|
||||
}
|
||||
} else {
|
||||
|
||||
if (transformLerpComplete)
|
||||
return;
|
||||
|
||||
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) {
|
||||
float angle = Mathf.LerpAngle(bone.Rotation, Quaternion.LookRotation(flipX ? Vector3.forward * -1 : Vector3.forward, parentReference.InverseTransformDirection(cachedTransform.up)).eulerAngles.z, overrideAlpha) + flipCompensation;
|
||||
|
||||
if (flip) {
|
||||
if ((!flipX && bone.flipX)) {
|
||||
angle -= flipCompensation;
|
||||
}
|
||||
|
||||
//TODO fix this...
|
||||
if (angle >= 360)
|
||||
angle -= 360;
|
||||
else if (angle <= -360)
|
||||
angle += 360;
|
||||
}
|
||||
|
||||
bone.Rotation = angle;
|
||||
}
|
||||
|
||||
//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);
|
||||
}
|
||||
|
||||
if (flip) {
|
||||
bone.flipX = flipX;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
transformLerpComplete = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void FlipX (bool state) {
|
||||
if (state != flipX) {
|
||||
flipX = state;
|
||||
if (flipX && Mathf.Abs(transform.localRotation.eulerAngles.y) > 90) {
|
||||
skeletonUtility.skeletonAnimation.LateUpdate();
|
||||
return;
|
||||
} else if (!flipX && Mathf.Abs(transform.localRotation.eulerAngles.y) < 90) {
|
||||
skeletonUtility.skeletonAnimation.LateUpdate();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bone.FlipX = state;
|
||||
transform.RotateAround(transform.position, skeletonUtility.transform.up, 180);
|
||||
Vector3 euler = transform.localRotation.eulerAngles;
|
||||
euler.x = 0;
|
||||
euler.y = bone.FlipX ? 180 : 0;
|
||||
transform.localRotation = Quaternion.Euler(euler);
|
||||
}
|
||||
|
||||
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 = SkeletonUtility.GetInParent<SkeletonUtility>(transform);
|
||||
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,56 @@
|
||||
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,120 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
|
||||
[RequireComponent(typeof(SkeletonUtilityBone)), ExecuteInEditMode]
|
||||
public class SkeletonUtilityGroundConstraint : SkeletonUtilityConstraint {
|
||||
|
||||
#if UNITY_4_3
|
||||
public LayerMask groundMask;
|
||||
public bool use2D = false;
|
||||
public bool useRadius = false;
|
||||
public float castRadius = 0.1f;
|
||||
public float castDistance = 5f;
|
||||
public float castOffset = 0;
|
||||
public float groundOffset = 0;
|
||||
public float adjustSpeed = 5;
|
||||
#else
|
||||
[Tooltip("LayerMask for what objects to raycast against")]
|
||||
public LayerMask groundMask;
|
||||
[Tooltip("The 2D")]
|
||||
public bool use2D = false;
|
||||
[Tooltip("Uses SphereCast for 3D mode and CircleCast for 2D mode")]
|
||||
public bool useRadius = false;
|
||||
[Tooltip("The Radius")]
|
||||
public float castRadius = 0.1f;
|
||||
[Tooltip("How high above the target bone to begin casting from")]
|
||||
public float castDistance = 5f;
|
||||
[Tooltip("X-Axis adjustment")]
|
||||
public float castOffset = 0;
|
||||
[Tooltip("Y-Axis adjustment")]
|
||||
public float groundOffset = 0;
|
||||
[Tooltip("How fast the target IK position adjusts to the ground. Use smaller values to prevent snapping")]
|
||||
public float adjustSpeed = 5;
|
||||
#endif
|
||||
|
||||
|
||||
Vector3 rayOrigin;
|
||||
Vector3 rayDir = new Vector3(0, -1, 0);
|
||||
float hitY;
|
||||
float lastHitY;
|
||||
|
||||
protected override void OnEnable () {
|
||||
base.OnEnable();
|
||||
}
|
||||
|
||||
protected override void OnDisable () {
|
||||
base.OnDisable();
|
||||
}
|
||||
|
||||
public override void DoUpdate () {
|
||||
rayOrigin = transform.position + new Vector3(castOffset, castDistance, 0);
|
||||
|
||||
hitY = float.MinValue;
|
||||
if (use2D) {
|
||||
RaycastHit2D hit;
|
||||
|
||||
if (useRadius) {
|
||||
#if UNITY_4_3
|
||||
//NOTE: Unity 4.3.x does not have CircleCast
|
||||
hit = Physics2D.Raycast(rayOrigin , rayDir, castDistance + groundOffset, groundMask);
|
||||
#else
|
||||
hit = Physics2D.CircleCast(rayOrigin, castRadius, rayDir, castDistance + groundOffset, groundMask);
|
||||
#endif
|
||||
} else {
|
||||
hit = Physics2D.Raycast(rayOrigin, rayDir, castDistance + groundOffset, groundMask);
|
||||
}
|
||||
|
||||
if (hit.collider != null) {
|
||||
hitY = hit.point.y + groundOffset;
|
||||
if (Application.isPlaying) {
|
||||
hitY = Mathf.MoveTowards(lastHitY, hitY, adjustSpeed * Time.deltaTime);
|
||||
}
|
||||
} else {
|
||||
if (Application.isPlaying)
|
||||
hitY = Mathf.MoveTowards(lastHitY, transform.position.y, adjustSpeed * Time.deltaTime);
|
||||
}
|
||||
} else {
|
||||
RaycastHit hit;
|
||||
bool validHit = false;
|
||||
|
||||
if (useRadius) {
|
||||
validHit = Physics.SphereCast(rayOrigin, castRadius, rayDir, out hit, castDistance + groundOffset, groundMask);
|
||||
} else {
|
||||
validHit = Physics.Raycast(rayOrigin, rayDir, out hit, castDistance + groundOffset, groundMask);
|
||||
}
|
||||
|
||||
if (validHit) {
|
||||
hitY = hit.point.y + groundOffset;
|
||||
if (Application.isPlaying) {
|
||||
hitY = Mathf.MoveTowards(lastHitY, hitY, adjustSpeed * Time.deltaTime);
|
||||
}
|
||||
} else {
|
||||
if (Application.isPlaying)
|
||||
hitY = Mathf.MoveTowards(lastHitY, transform.position.y, adjustSpeed * Time.deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
Vector3 v = transform.position;
|
||||
v.y = Mathf.Clamp(v.y, Mathf.Min(lastHitY, hitY), float.MaxValue);
|
||||
transform.position = v;
|
||||
|
||||
utilBone.bone.X = transform.localPosition.x;
|
||||
utilBone.bone.Y = transform.localPosition.y;
|
||||
|
||||
lastHitY = hitY;
|
||||
}
|
||||
|
||||
void OnDrawGizmos () {
|
||||
Vector3 hitEnd = rayOrigin + (rayDir * Mathf.Min(castDistance, rayOrigin.y - hitY));
|
||||
Vector3 clearEnd = rayOrigin + (rayDir * castDistance);
|
||||
Gizmos.DrawLine(rayOrigin, hitEnd);
|
||||
|
||||
if (useRadius) {
|
||||
Gizmos.DrawLine(new Vector3(hitEnd.x - castRadius, hitEnd.y - groundOffset, hitEnd.z), new Vector3(hitEnd.x + castRadius, hitEnd.y - groundOffset, hitEnd.z));
|
||||
Gizmos.DrawLine(new Vector3(clearEnd.x - castRadius, clearEnd.y, clearEnd.z), new Vector3(clearEnd.x + castRadius, clearEnd.y, clearEnd.z));
|
||||
}
|
||||
|
||||
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,79 @@
|
||||
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,96 @@
|
||||
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:
|
||||