Rewrote spine-tk2d to match spine-unity.
9
.gitignore
vendored
@ -49,6 +49,15 @@ spine-unity/*.sln
|
||||
Assembly-*.csproj
|
||||
Assembly-*.pidb
|
||||
|
||||
spine-tk2d/Assets/Spine/spine-csharp
|
||||
!spine-tk2d/Assets/Spine/spine-csharp/Place spine-csharp here.txt
|
||||
spine-tk2d/ProjectSettings
|
||||
spine-tk2d/Temp
|
||||
spine-tk2d/Library
|
||||
spine-tk2d/*.sln
|
||||
spine-tk2d/Assets/TK2DROOT*
|
||||
spine-tk2d/Assets/-tk2d*
|
||||
|
||||
spine-corona/spine-lua/
|
||||
!spine-corona/spine-lua/Place spine-lua here.txt
|
||||
|
||||
|
||||
5
spine-tk2d/Assets/Spine.meta
Normal file
@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1fdd5b9e3e0974d40b1b149ec5a15662
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
5
spine-tk2d/Assets/Spine/Editor.meta
Normal file
@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ad07f9d157ce0a1468016aa5b6683e2a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
61
spine-tk2d/Assets/Spine/Editor/Menus.cs
Normal file
@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using Spine;
|
||||
|
||||
public class Menus {
|
||||
[MenuItem("Assets/Create/Spine SkeletonData")]
|
||||
static public void CreateSkeletonData () {
|
||||
CreateAsset<SkeletonDataAsset>("New SkeletonData");
|
||||
}
|
||||
|
||||
static private void CreateAsset <T> (String path) where T : ScriptableObject {
|
||||
try {
|
||||
path = Path.GetDirectoryName(AssetDatabase.GetAssetPath(Selection.activeObject)) + "/" + path;
|
||||
} catch (Exception) {
|
||||
path = "Assets/" + path;
|
||||
}
|
||||
ScriptableObject asset = ScriptableObject.CreateInstance<T>();
|
||||
AssetDatabase.CreateAsset(asset, path + ".asset");
|
||||
AssetDatabase.SaveAssets();
|
||||
EditorUtility.FocusProjectWindow();
|
||||
Selection.activeObject = asset;
|
||||
}
|
||||
|
||||
[MenuItem("GameObject/Create Other/Spine SkeletonComponent")]
|
||||
static public void CreateSkeletonComponentGameObject () {
|
||||
GameObject gameObject = new GameObject("New SkeletonComponent", typeof(SkeletonComponent));
|
||||
EditorUtility.FocusProjectWindow();
|
||||
Selection.activeObject = gameObject;
|
||||
}
|
||||
|
||||
[MenuItem("GameObject/Create Other/Spine SkeletonAnimation")]
|
||||
static public void CreateSkeletonAnimationGameObject () {
|
||||
GameObject gameObject = new GameObject("New SkeletonAnimation", typeof(SkeletonAnimation));
|
||||
EditorUtility.FocusProjectWindow();
|
||||
Selection.activeObject = gameObject;
|
||||
}
|
||||
|
||||
[MenuItem("Component/Spine SkeletonComponent")]
|
||||
static public void CreateSkeletonComponent () {
|
||||
Selection.activeGameObject.AddComponent(typeof(SkeletonComponent));
|
||||
}
|
||||
|
||||
[MenuItem("Component/Spine SkeletonAnimation")]
|
||||
static public void CreateSkeletonAnimation () {
|
||||
Selection.activeGameObject.AddComponent(typeof(SkeletonAnimation));
|
||||
}
|
||||
|
||||
[MenuItem("Component/Spine SkeletonComponent", true)]
|
||||
static public bool ValidateCreateSkeletonComponent () {
|
||||
return Selection.activeGameObject != null
|
||||
&& Selection.activeGameObject.GetComponent(typeof(SkeletonComponent)) == null
|
||||
&& Selection.activeGameObject.GetComponent(typeof(SkeletonAnimation)) == null;
|
||||
}
|
||||
|
||||
[MenuItem("Component/Spine SkeletonAnimation", true)]
|
||||
static public bool ValidateCreateSkeletonAnimation () {
|
||||
return ValidateCreateSkeletonComponent();
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b2ccbecf56104874f886da59557ff3e4
|
||||
guid: 1907c00e57244fd4c8ff68eee5a58761
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
117
spine-tk2d/Assets/Spine/Editor/SkeletonAnimationInspector.cs
Normal file
@ -0,0 +1,117 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
******************************************************************************/
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
[CustomEditor(typeof(SkeletonAnimation))]
|
||||
public class SkeletonAnimationInspector : Editor {
|
||||
private SerializedProperty skeletonDataAsset, animationName, loop, useAnimationName, initialSkinName, timeScale;
|
||||
|
||||
void OnEnable () {
|
||||
skeletonDataAsset = serializedObject.FindProperty("skeletonDataAsset");
|
||||
animationName = serializedObject.FindProperty("animationName");
|
||||
loop = serializedObject.FindProperty("loop");
|
||||
useAnimationName = serializedObject.FindProperty("useAnimationName");
|
||||
initialSkinName = serializedObject.FindProperty("initialSkinName");
|
||||
timeScale = serializedObject.FindProperty("timeScale");
|
||||
}
|
||||
|
||||
override public void OnInspectorGUI () {
|
||||
serializedObject.Update();
|
||||
SkeletonComponent component = (SkeletonComponent)target;
|
||||
|
||||
EditorGUIUtility.LookLikeInspector();
|
||||
EditorGUILayout.PropertyField(skeletonDataAsset);
|
||||
|
||||
if (component.skeleton != null) {
|
||||
// Initial skin name.
|
||||
String[] skins = new String[component.skeleton.Data.Skins.Count + 1];
|
||||
int skinIndex = 0;
|
||||
for (int i = 0; i < skins.Length - 1; i++) {
|
||||
String name = component.skeleton.Data.Skins[i].Name;
|
||||
skins[i] = name;
|
||||
if (name == initialSkinName.stringValue)
|
||||
skinIndex = i;
|
||||
}
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("Initial Skin");
|
||||
EditorGUIUtility.LookLikeControls();
|
||||
skinIndex = EditorGUILayout.Popup(skinIndex, skins);
|
||||
EditorGUIUtility.LookLikeInspector();
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
initialSkinName.stringValue = skinIndex == 0 ? null : skins[skinIndex];
|
||||
|
||||
// Animation name.
|
||||
String[] animations = new String[component.skeleton.Data.Animations.Count + 2];
|
||||
animations[0] = "<No Change>";
|
||||
animations[1] = "<None>";
|
||||
int animationIndex = useAnimationName.boolValue ? 1 : 0;
|
||||
for (int i = 0; i < animations.Length - 2; i++) {
|
||||
String name = component.skeleton.Data.Animations[i].Name;
|
||||
animations[i + 2] = name;
|
||||
if (name == animationName.stringValue)
|
||||
animationIndex = i + 2;
|
||||
}
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("Animation");
|
||||
EditorGUIUtility.LookLikeControls();
|
||||
animationIndex = EditorGUILayout.Popup(animationIndex, animations);
|
||||
EditorGUIUtility.LookLikeInspector();
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
if (animationIndex == 0) {
|
||||
animationName.stringValue = null;
|
||||
useAnimationName.boolValue = false;
|
||||
} else if (animationIndex == 1) {
|
||||
animationName.stringValue = null;
|
||||
useAnimationName.boolValue = true;
|
||||
} else {
|
||||
animationName.stringValue = animations[animationIndex];
|
||||
useAnimationName.boolValue = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Animation loop.
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("Loop");
|
||||
loop.boolValue = EditorGUILayout.Toggle(loop.boolValue);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.PropertyField(timeScale);
|
||||
|
||||
if (serializedObject.ApplyModifiedProperties() ||
|
||||
(Event.current.type == EventType.ValidateCommand && Event.current.commandName == "UndoRedoPerformed")
|
||||
) {
|
||||
if (!Application.isPlaying) {
|
||||
component.Clear();
|
||||
component.Update();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c36a835202febaa4ba99b918635b1920
|
||||
guid: a21294688dd7a7349a5ca17241fb40e0
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
78
spine-tk2d/Assets/Spine/Editor/SkeletonComponentInspector.cs
Normal file
@ -0,0 +1,78 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
******************************************************************************/
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
[CustomEditor(typeof(SkeletonComponent))]
|
||||
public class SkeletonComponentInspector : Editor {
|
||||
private SerializedProperty skeletonDataAsset, initialSkinName, timeScale;
|
||||
|
||||
void OnEnable () {
|
||||
skeletonDataAsset = serializedObject.FindProperty("skeletonDataAsset");
|
||||
initialSkinName = serializedObject.FindProperty("initialSkinName");
|
||||
timeScale = serializedObject.FindProperty("timeScale");
|
||||
}
|
||||
|
||||
override public void OnInspectorGUI () {
|
||||
serializedObject.Update();
|
||||
SkeletonComponent component = (SkeletonComponent)target;
|
||||
|
||||
EditorGUIUtility.LookLikeInspector();
|
||||
EditorGUILayout.PropertyField(skeletonDataAsset);
|
||||
|
||||
if (component.skeleton != null) {
|
||||
// Initial skin name.
|
||||
String[] skins = new String[component.skeleton.Data.Skins.Count + 1];
|
||||
int skinIndex = 0;
|
||||
for (int i = 0; i < skins.Length - 1; i++) {
|
||||
String name = component.skeleton.Data.Skins[i].Name;
|
||||
skins[i] = name;
|
||||
if (name == initialSkinName.stringValue)
|
||||
skinIndex = i;
|
||||
}
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("Initial Skin");
|
||||
EditorGUIUtility.LookLikeControls();
|
||||
skinIndex = EditorGUILayout.Popup(skinIndex, skins);
|
||||
EditorGUIUtility.LookLikeInspector();
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
initialSkinName.stringValue = skinIndex == 0 ? null : skins[skinIndex];
|
||||
}
|
||||
|
||||
EditorGUILayout.PropertyField(timeScale);
|
||||
|
||||
if (serializedObject.ApplyModifiedProperties() ||
|
||||
(Event.current.type == EventType.ValidateCommand && Event.current.commandName == "UndoRedoPerformed")
|
||||
) {
|
||||
if (!Application.isPlaying) {
|
||||
component.Clear();
|
||||
component.Update();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c62fe2307a465b14793b8fdde54fdbe4
|
||||
guid: dbb89dadcac8d6b48869aeb81b0ae88f
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
101
spine-tk2d/Assets/Spine/Editor/SkeletonDataAssetInspector.cs
Normal file
@ -0,0 +1,101 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
******************************************************************************/
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using Spine;
|
||||
|
||||
[CustomEditor(typeof(SkeletonDataAsset))]
|
||||
public class SkeletonDataAssetInspector : Editor {
|
||||
private SerializedProperty spriteCollection, skeletonJSON, scale, fromAnimation, toAnimation, duration;
|
||||
private bool showAnimationStateData = true;
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
override public void OnInspectorGUI () {
|
||||
serializedObject.Update();
|
||||
SkeletonDataAsset asset = (SkeletonDataAsset)target;
|
||||
|
||||
EditorGUIUtility.LookLikeInspector();
|
||||
|
||||
tk2dSpriteCollection sprites = EditorGUILayout.ObjectField("Sprite Collection", asset.spriteCollection, typeof(tk2dSpriteCollection), false) as tk2dSpriteCollection;
|
||||
if (sprites != null)
|
||||
spriteCollection.objectReferenceValue = sprites.spriteCollection;
|
||||
|
||||
EditorGUILayout.PropertyField(skeletonJSON);
|
||||
EditorGUILayout.PropertyField(scale);
|
||||
|
||||
SkeletonData skeletonData = asset.GetSkeletonData(true);
|
||||
if (skeletonData != null) {
|
||||
showAnimationStateData = EditorGUILayout.Foldout(showAnimationStateData, "Animation State Data");
|
||||
if (showAnimationStateData) {
|
||||
// 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);
|
||||
SerializedProperty durationProp = duration.GetArrayElementAtIndex(i);
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
from.stringValue = animations[EditorGUILayout.Popup(Math.Max(Array.IndexOf(animations, from.stringValue), 0), animations)];
|
||||
to.stringValue = animations[EditorGUILayout.Popup(Math.Max(Array.IndexOf(animations, to.stringValue), 0), animations)];
|
||||
durationProp.floatValue = EditorGUILayout.FloatField(durationProp.floatValue);
|
||||
if (GUILayout.Button("Delete")) {
|
||||
duration.DeleteArrayElementAtIndex(i);
|
||||
toAnimation.DeleteArrayElementAtIndex(i);
|
||||
fromAnimation.DeleteArrayElementAtIndex(i);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.Space();
|
||||
if (GUILayout.Button("Add Mix")) {
|
||||
duration.arraySize++;
|
||||
toAnimation.arraySize++;
|
||||
fromAnimation.arraySize++;
|
||||
}
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
}
|
||||
|
||||
if (!Application.isPlaying) {
|
||||
if (serializedObject.ApplyModifiedProperties() ||
|
||||
(Event.current.type == EventType.ValidateCommand && Event.current.commandName == "UndoRedoPerformed")
|
||||
) {
|
||||
asset.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9b8ea7c2b29e5814eb0b4b692b828869
|
||||
guid: cffb121e3cd80644d84c585b9c7448e8
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
66
spine-tk2d/Assets/Spine/SkeletonAnimation.cs
Normal file
@ -0,0 +1,66 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
******************************************************************************/
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Spine;
|
||||
|
||||
/** Extends SkeletonComponent to apply an animation. */
|
||||
[ExecuteInEditMode, RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
|
||||
public class SkeletonAnimation : SkeletonComponent {
|
||||
public bool useAnimationName;
|
||||
public String animationName;
|
||||
public bool loop;
|
||||
public Spine.AnimationState state;
|
||||
|
||||
override public void Initialize () {
|
||||
base.Initialize(); // Call overridden method to initialize the skeleton.
|
||||
|
||||
state = new Spine.AnimationState(skeletonDataAsset.GetAnimationStateData());
|
||||
}
|
||||
|
||||
override public void UpdateSkeleton () {
|
||||
if (useAnimationName) {
|
||||
// Keep AnimationState in sync with animationName and loop fields.
|
||||
if (animationName == null || animationName.Length == 0) {
|
||||
if (state.Animation != null)
|
||||
state.ClearAnimation();
|
||||
} else if (state.Animation == null || animationName != state.Animation.Name) {
|
||||
Spine.Animation animation = skeleton.Data.FindAnimation(animationName);
|
||||
if (animation != null)
|
||||
state.SetAnimation(animation, loop);
|
||||
}
|
||||
state.Loop = loop;
|
||||
}
|
||||
|
||||
// Apply the animation.
|
||||
state.Update(Time.deltaTime * timeScale);
|
||||
state.Apply(skeleton);
|
||||
|
||||
// Call overridden method to call skeleton Update and UpdateWorldTransform.
|
||||
base.UpdateSkeleton();
|
||||
}
|
||||
}
|
||||
8
spine-tk2d/Assets/Spine/SkeletonAnimation.cs.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 41133952e6d5fe04ca82a24ed4c02990
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
252
spine-tk2d/Assets/Spine/SkeletonComponent.cs
Normal file
@ -0,0 +1,252 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
******************************************************************************/
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Spine;
|
||||
|
||||
/** Renders a skeleton. Extend to apply animations, get bones and manipulate them, etc. */
|
||||
[ExecuteInEditMode, RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
|
||||
public class SkeletonComponent : MonoBehaviour {
|
||||
public SkeletonDataAsset skeletonDataAsset;
|
||||
public Skeleton skeleton;
|
||||
public String initialSkinName;
|
||||
public float timeScale = 1;
|
||||
private Mesh mesh;
|
||||
private int lastVertexCount;
|
||||
private Vector3[] vertices;
|
||||
private Color32[] colors;
|
||||
private Vector2[] uvs;
|
||||
private float[] vertexPositions = new float[8];
|
||||
private List<Material> submeshMaterials = new List<Material>();
|
||||
private List<int[]> submeshIndexes = new List<int[]>();
|
||||
private Material[] sharedMaterials = new Material[0];
|
||||
|
||||
public virtual void Clear () {
|
||||
GetComponent<MeshFilter>().mesh = null;
|
||||
DestroyImmediate(mesh);
|
||||
mesh = null;
|
||||
renderer.sharedMaterial = null;
|
||||
skeleton = null;
|
||||
}
|
||||
|
||||
public virtual void Initialize () {
|
||||
mesh = new Mesh();
|
||||
GetComponent<MeshFilter>().mesh = mesh;
|
||||
mesh.name = "Skeleton Mesh";
|
||||
mesh.hideFlags = HideFlags.HideAndDontSave;
|
||||
mesh.MarkDynamic();
|
||||
|
||||
// BOZO
|
||||
//renderer.sharedMaterial = skeletonDataAsset.atlasAsset.material;
|
||||
|
||||
vertices = new Vector3[0];
|
||||
|
||||
skeleton = new Skeleton(skeletonDataAsset.GetSkeletonData(false));
|
||||
|
||||
if (initialSkinName != null && initialSkinName.Length > 0) {
|
||||
skeleton.SetSkin(initialSkinName);
|
||||
skeleton.SetSlotsToSetupPose();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void UpdateSkeleton () {
|
||||
skeleton.Update(Time.deltaTime * timeScale);
|
||||
skeleton.UpdateWorldTransform();
|
||||
}
|
||||
|
||||
public virtual void Update () {
|
||||
SkeletonData skeletonData = skeletonDataAsset.GetSkeletonData(false);
|
||||
// Clear fields if missing information to render.
|
||||
if (skeletonDataAsset == null || skeletonData == null) {
|
||||
Clear();
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize fields.
|
||||
if (skeleton == null || skeleton.Data != skeletonData)
|
||||
Initialize();
|
||||
|
||||
UpdateSkeleton();
|
||||
|
||||
// Count quads and submeshes.
|
||||
int quadCount = 0, submeshQuadCount = 0;
|
||||
Material lastMaterial = null;
|
||||
submeshMaterials.Clear();
|
||||
List<Slot> drawOrder = skeleton.DrawOrder;
|
||||
for (int i = 0, n = drawOrder.Count; i < n; i++) {
|
||||
RegionAttachment regionAttachment = drawOrder[i].Attachment as RegionAttachment;
|
||||
if (regionAttachment == null)
|
||||
continue;
|
||||
|
||||
// Add submesh when material changes.
|
||||
Material material = (Material)regionAttachment.RendererObject;
|
||||
if (lastMaterial != material && lastMaterial != null) {
|
||||
addSubmesh(lastMaterial, quadCount, submeshQuadCount, false);
|
||||
submeshQuadCount = 0;
|
||||
}
|
||||
lastMaterial = material;
|
||||
|
||||
quadCount++;
|
||||
submeshQuadCount++;
|
||||
}
|
||||
addSubmesh(lastMaterial, quadCount, submeshQuadCount, false);
|
||||
|
||||
// Set materials.
|
||||
if (submeshMaterials.Count == sharedMaterials.Length)
|
||||
submeshMaterials.CopyTo(sharedMaterials);
|
||||
else
|
||||
sharedMaterials = submeshMaterials.ToArray();
|
||||
renderer.sharedMaterials = sharedMaterials;
|
||||
|
||||
// Ensure mesh data is the right size.
|
||||
Mesh mesh = this.mesh;
|
||||
Vector3[] vertices = this.vertices;
|
||||
int vertexCount = quadCount * 4;
|
||||
bool newTriangles = vertexCount > vertices.Length;
|
||||
if (newTriangles) {
|
||||
// Not enough vertices, increase size.
|
||||
this.vertices = vertices = new Vector3[vertexCount];
|
||||
this.colors = new Color32[vertexCount];
|
||||
this.uvs = new Vector2[vertexCount];
|
||||
mesh.Clear();
|
||||
} else {
|
||||
// Too many vertices, zero the extra.
|
||||
Vector3 zero = new Vector3(0, 0, 0);
|
||||
for (int i = vertexCount, n = lastVertexCount; i < n; i++)
|
||||
vertices[i] = zero;
|
||||
}
|
||||
lastVertexCount = vertexCount;
|
||||
|
||||
// Setup mesh.
|
||||
float[] vertexPositions = this.vertexPositions;
|
||||
Vector2[] uvs = this.uvs;
|
||||
Color32[] colors = this.colors;
|
||||
int vertexIndex = 0;
|
||||
Color32 color = new Color32();
|
||||
for (int i = 0, n = drawOrder.Count; i < n; i++) {
|
||||
Slot slot = drawOrder[i];
|
||||
RegionAttachment regionAttachment = slot.Attachment as RegionAttachment;
|
||||
if (regionAttachment == null)
|
||||
continue;
|
||||
|
||||
regionAttachment.ComputeVertices(skeleton.X, skeleton.Y, slot.Bone, vertexPositions);
|
||||
|
||||
vertices[vertexIndex] = new Vector3(vertexPositions[RegionAttachment.X1], vertexPositions[RegionAttachment.Y1], 0);
|
||||
vertices[vertexIndex + 1] = new Vector3(vertexPositions[RegionAttachment.X4], vertexPositions[RegionAttachment.Y4], 0);
|
||||
vertices[vertexIndex + 2] = new Vector3(vertexPositions[RegionAttachment.X2], vertexPositions[RegionAttachment.Y2], 0);
|
||||
vertices[vertexIndex + 3] = new Vector3(vertexPositions[RegionAttachment.X3], vertexPositions[RegionAttachment.Y3], 0);
|
||||
|
||||
color.a = (byte)(skeleton.A * slot.A * 255);
|
||||
color.r = (byte)(skeleton.R * slot.R * color.a);
|
||||
color.g = (byte)(skeleton.G * slot.G * color.a);
|
||||
color.b = (byte)(skeleton.B * slot.B * color.a);
|
||||
colors[vertexIndex] = color;
|
||||
colors[vertexIndex + 1] = color;
|
||||
colors[vertexIndex + 2] = color;
|
||||
colors[vertexIndex + 3] = color;
|
||||
|
||||
float[] regionUVs = regionAttachment.UVs;
|
||||
uvs[vertexIndex] = new Vector2(regionUVs[RegionAttachment.X1], regionUVs[RegionAttachment.Y1]);
|
||||
uvs[vertexIndex + 1] = new Vector2(regionUVs[RegionAttachment.X4], regionUVs[RegionAttachment.Y4]);
|
||||
uvs[vertexIndex + 2] = new Vector2(regionUVs[RegionAttachment.X2], regionUVs[RegionAttachment.Y2]);
|
||||
uvs[vertexIndex + 3] = new Vector2(regionUVs[RegionAttachment.X3], regionUVs[RegionAttachment.Y3]);
|
||||
|
||||
vertexIndex += 4;
|
||||
}
|
||||
mesh.vertices = vertices;
|
||||
mesh.colors32 = colors;
|
||||
mesh.uv = uvs;
|
||||
mesh.subMeshCount = submeshMaterials.Count;
|
||||
for (int i = 0; i < mesh.subMeshCount; ++i)
|
||||
mesh.SetTriangles(submeshIndexes[i], i);
|
||||
}
|
||||
|
||||
/** Adds a material. Adds submesh indexes if existing indexes aren't sufficient. */
|
||||
private void addSubmesh (Material material, int endQuadCount, int submeshQuadCount, bool exact) {
|
||||
int submeshIndex = submeshMaterials.Count;
|
||||
submeshMaterials.Add(material);
|
||||
|
||||
// Return if the existing submesh is big enough.
|
||||
int indexCount = submeshQuadCount * 6;
|
||||
if (submeshIndexes.Count > submeshIndex) {
|
||||
if (exact) {
|
||||
if (submeshIndexes[submeshIndex].Length == indexCount)
|
||||
return;
|
||||
} else {
|
||||
if (submeshIndexes[submeshIndex].Length >= indexCount)
|
||||
return;
|
||||
}
|
||||
} else
|
||||
submeshIndexes.Add(null);
|
||||
|
||||
int vertexIndex = (endQuadCount - submeshQuadCount) * 4;
|
||||
int[] indexes = new int[indexCount];
|
||||
for (int i = 0; i < indexCount; i += 6, vertexIndex += 4) {
|
||||
indexes[i] = vertexIndex;
|
||||
indexes[i + 1] = vertexIndex + 2;
|
||||
indexes[i + 2] = vertexIndex + 1;
|
||||
indexes[i + 3] = vertexIndex + 2;
|
||||
indexes[i + 4] = vertexIndex + 3;
|
||||
indexes[i + 5] = vertexIndex + 1;
|
||||
}
|
||||
submeshIndexes[submeshIndex] = indexes;
|
||||
}
|
||||
|
||||
public virtual void OnEnable () {
|
||||
Update();
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
public virtual void OnDisable () {
|
||||
Clear();
|
||||
}
|
||||
#endif
|
||||
|
||||
public virtual void Reset () {
|
||||
Update();
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
void OnDrawGizmos() {
|
||||
Vector3 gizmosCenter = new Vector3();
|
||||
Vector3 gizmosSize = new Vector3();
|
||||
Vector3 min = new Vector3(float.MaxValue, float.MaxValue, 0f);
|
||||
Vector3 max = new Vector3(float.MinValue, float.MinValue, 0f);
|
||||
foreach (Vector3 vert in vertices) {
|
||||
min = Vector3.Min (min, vert);
|
||||
max = Vector3.Max (max, vert);
|
||||
}
|
||||
float width = max.x - min.x;
|
||||
float height = max.y - min.y;
|
||||
gizmosCenter = new Vector3(min.x + (width / 2f), min.y + (height / 2f), 0f);
|
||||
gizmosSize = new Vector3(width, height, 1f);
|
||||
Gizmos.color = Color.clear;
|
||||
Gizmos.matrix = transform.localToWorldMatrix;
|
||||
Gizmos.DrawCube(gizmosCenter, gizmosSize);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
8
spine-tk2d/Assets/Spine/SkeletonComponent.cs.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9da572b571dc33444bd6622951ef62ba
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
90
spine-tk2d/Assets/Spine/SkeletonDataAsset.cs
Normal file
@ -0,0 +1,90 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
******************************************************************************/
|
||||
using System;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
using Spine;
|
||||
|
||||
public class SkeletonDataAsset : ScriptableObject {
|
||||
public tk2dSpriteCollectionData spriteCollection;
|
||||
public TextAsset skeletonJSON;
|
||||
public float scale = 1;
|
||||
public String[] fromAnimation;
|
||||
public String[] toAnimation;
|
||||
public float[] duration;
|
||||
private SkeletonData skeletonData;
|
||||
private AnimationStateData stateData;
|
||||
|
||||
public void Clear () {
|
||||
skeletonData = null;
|
||||
stateData = null;
|
||||
}
|
||||
|
||||
public SkeletonData GetSkeletonData (bool quiet) {
|
||||
if (spriteCollection == null) {
|
||||
if (!quiet)
|
||||
Debug.LogWarning("Sprite collection not set for skeleton data asset: " + name, this);
|
||||
Clear();
|
||||
return null;
|
||||
}
|
||||
|
||||
if (skeletonJSON == null) {
|
||||
if (!quiet)
|
||||
Debug.LogWarning("Skeleton JSON file not set for skeleton data asset: " + name, this);
|
||||
Clear();
|
||||
return null;
|
||||
}
|
||||
|
||||
if (skeletonData != null)
|
||||
return skeletonData;
|
||||
|
||||
SkeletonJson json = new SkeletonJson(new SpriteCollectionAttachmentLoader(spriteCollection));
|
||||
json.Scale = 1.0f / (spriteCollection.invOrthoSize * spriteCollection.halfTargetHeight) * scale;
|
||||
|
||||
try {
|
||||
skeletonData = json.ReadSkeletonData(new StringReader(skeletonJSON.text));
|
||||
} catch (Exception ex) {
|
||||
Debug.Log("Error reading skeleton JSON file for skeleton data asset: " + name + "\n" +
|
||||
ex.Message + "\n" + ex.StackTrace, this);
|
||||
return null;
|
||||
}
|
||||
|
||||
stateData = new AnimationStateData(skeletonData);
|
||||
for (int i = 0, n = fromAnimation.Length; i < n; i++) {
|
||||
if (fromAnimation[i].Length == 0 || toAnimation[i].Length == 0)
|
||||
continue;
|
||||
stateData.SetMix(fromAnimation[i], toAnimation[i], duration[i]);
|
||||
}
|
||||
|
||||
return skeletonData;
|
||||
}
|
||||
|
||||
public AnimationStateData GetAnimationStateData () {
|
||||
if (stateData != null)
|
||||
return stateData;
|
||||
GetSkeletonData(false);
|
||||
return stateData;
|
||||
}
|
||||
}
|
||||
8
spine-tk2d/Assets/Spine/SkeletonDataAsset.cs.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1bdfe79e336474848808de1467defd7f
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@ -4,26 +4,32 @@ using Spine;
|
||||
|
||||
// TODO: handle TPackerCW flip mode (probably not swap uv horizontaly)
|
||||
|
||||
public class tk2dSpineAttachmentLoader : AttachmentLoader {
|
||||
public class SpriteCollectionAttachmentLoader : AttachmentLoader {
|
||||
private tk2dSpriteCollectionData sprites;
|
||||
|
||||
public tk2dSpineAttachmentLoader(tk2dSpriteCollectionData sprites) {
|
||||
if (sprites == null) throw new ArgumentNullException("sprites cannot be null.");
|
||||
public SpriteCollectionAttachmentLoader (tk2dSpriteCollectionData sprites) {
|
||||
if (sprites == null)
|
||||
throw new ArgumentNullException("sprites cannot be null.");
|
||||
this.sprites = sprites;
|
||||
}
|
||||
|
||||
public Attachment NewAttachment(Skin skin, AttachmentType type, String name) {
|
||||
if (type != AttachmentType.region) throw new Exception("Unknown attachment type: " + type);
|
||||
public Attachment NewAttachment (Skin skin, AttachmentType type, String name) {
|
||||
if (type != AttachmentType.region)
|
||||
throw new Exception("Unknown attachment type: " + type);
|
||||
|
||||
// Strip folder names.
|
||||
int index = name.LastIndexOfAny(new char[] {'/', '\\'});
|
||||
if (index != -1) name = name.Substring(index + 1);
|
||||
if (index != -1)
|
||||
name = name.Substring(index + 1);
|
||||
|
||||
tk2dSpriteDefinition def = sprites.GetSpriteDefinition(name);
|
||||
|
||||
if (def == null) throw new Exception("Sprite not found in atlas: " + name + " (" + type + ")");
|
||||
if (def.complexGeometry) throw new NotImplementedException("Complex geometry is not supported: " + name + " (" + type + ")");
|
||||
if (def.flipped == tk2dSpriteDefinition.FlipMode.TPackerCW) throw new NotImplementedException("Only 2D Toolkit atlases are supported: " + name + " (" + type + ")");
|
||||
if (def == null)
|
||||
throw new Exception("Sprite not found in atlas: " + name + " (" + type + ")");
|
||||
if (def.complexGeometry)
|
||||
throw new NotImplementedException("Complex geometry is not supported: " + name + " (" + type + ")");
|
||||
if (def.flipped == tk2dSpriteDefinition.FlipMode.TPackerCW)
|
||||
throw new NotImplementedException("Only 2D Toolkit atlases are supported: " + name + " (" + type + ")");
|
||||
|
||||
RegionAttachment attachment = new RegionAttachment(name);
|
||||
|
||||
@ -62,6 +68,8 @@ public class tk2dSpineAttachmentLoader : AttachmentLoader {
|
||||
float y1 = def.boundsData[0].y - def.boundsData[1].y / 2;
|
||||
attachment.RegionOffsetY = (int)((y1 - y0) / def.texelSize.y);
|
||||
|
||||
attachment.RendererObject = def.material;
|
||||
|
||||
return attachment;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2ad5a031e905ab0469fe2e19ff1b94ee
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
5
spine-tk2d/Assets/Spine/spine-csharp.meta
Normal file
@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: afc6035066a4eb4478f706aa211ca644
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
5
spine-tk2d/Assets/examples.meta
Normal file
@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ddc30294e8bdeb0469c854ccf66824fc
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
5
spine-tk2d/Assets/examples/spineboy.meta
Normal file
@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aafe437f17003ec449c178c2c329d221
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
@ -1,13 +1,11 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
|
||||
/*
|
||||
*/
|
||||
public class tk2dSpineboy : MonoBehaviour {
|
||||
private tk2dSpineAnimation skeleton;
|
||||
public class Spineboy : MonoBehaviour {
|
||||
private SkeletonAnimation skeleton;
|
||||
|
||||
void Start() {
|
||||
skeleton = GetComponent<tk2dSpineAnimation>();
|
||||
skeleton = GetComponent<SkeletonAnimation>();
|
||||
}
|
||||
|
||||
void LateUpdate() {
|
||||
@ -1,4 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ecf18700fc84ae94ca3cfa6d301b50c0
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
@ -1,4 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 75ba18a107160134091f702a9e446567
|
||||
guid: 4cd6560d5de81b240b7e7d9beaa3e2f0
|
||||
NativeFormatImporter:
|
||||
userData:
|
||||
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
@ -30,6 +30,7 @@ TextureImporter:
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
alphaIsTransparency: 0
|
||||
textureType: -1
|
||||
buildTargetSettings: []
|
||||
userData:
|
||||
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
@ -30,6 +30,7 @@ TextureImporter:
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
alphaIsTransparency: 0
|
||||
textureType: -1
|
||||
buildTargetSettings: []
|
||||
userData:
|
||||
|
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 6.8 KiB |
@ -30,6 +30,7 @@ TextureImporter:
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
alphaIsTransparency: 0
|
||||
textureType: -1
|
||||
buildTargetSettings: []
|
||||
userData:
|
||||
BIN
spine-tk2d/Assets/examples/spineboy/SpineboyAtlas.prefab
Normal file
5
spine-tk2d/Assets/examples/spineboy/images.meta
Normal file
@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 59b6b8248068c5c48a322d8b794e27ba
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
@ -30,6 +30,7 @@ TextureImporter:
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
alphaIsTransparency: 0
|
||||
textureType: 5
|
||||
buildTargetSettings: []
|
||||
userData:
|
||||
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
@ -30,6 +30,7 @@ TextureImporter:
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
alphaIsTransparency: 0
|
||||
textureType: 5
|
||||
buildTargetSettings: []
|
||||
userData:
|
||||
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
@ -30,6 +30,7 @@ TextureImporter:
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
alphaIsTransparency: 0
|
||||
textureType: 5
|
||||
buildTargetSettings: []
|
||||
userData:
|
||||
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
@ -30,6 +30,7 @@ TextureImporter:
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
alphaIsTransparency: 0
|
||||
textureType: 5
|
||||
buildTargetSettings: []
|
||||
userData:
|
||||
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
@ -30,6 +30,7 @@ TextureImporter:
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
alphaIsTransparency: 0
|
||||
textureType: 5
|
||||
buildTargetSettings: []
|
||||
userData:
|
||||
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
@ -30,6 +30,7 @@ TextureImporter:
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
alphaIsTransparency: 0
|
||||
textureType: 5
|
||||
buildTargetSettings: []
|
||||
userData:
|
||||
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.7 KiB |
@ -30,6 +30,7 @@ TextureImporter:
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
alphaIsTransparency: 0
|
||||
textureType: 5
|
||||
buildTargetSettings: []
|
||||
userData:
|
||||
|
Before Width: | Height: | Size: 6.0 KiB After Width: | Height: | Size: 6.0 KiB |
@ -30,6 +30,7 @@ TextureImporter:
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
alphaIsTransparency: 0
|
||||
textureType: 5
|
||||
buildTargetSettings: []
|
||||
userData:
|
||||
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
@ -30,6 +30,7 @@ TextureImporter:
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
alphaIsTransparency: 0
|
||||
textureType: 5
|
||||
buildTargetSettings: []
|
||||
userData:
|
||||
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
@ -30,6 +30,7 @@ TextureImporter:
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
alphaIsTransparency: 0
|
||||
textureType: 5
|
||||
buildTargetSettings: []
|
||||
userData:
|
||||
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.4 KiB |
@ -30,6 +30,7 @@ TextureImporter:
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
alphaIsTransparency: 0
|
||||
textureType: 5
|
||||
buildTargetSettings: []
|
||||
userData:
|
||||
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
@ -30,6 +30,7 @@ TextureImporter:
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
alphaIsTransparency: 0
|
||||
textureType: 5
|
||||
buildTargetSettings: []
|
||||
userData:
|
||||
|
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 5.7 KiB |
@ -30,6 +30,7 @@ TextureImporter:
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
alphaIsTransparency: 0
|
||||
textureType: 5
|
||||
buildTargetSettings: []
|
||||
userData:
|
||||
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
@ -30,6 +30,7 @@ TextureImporter:
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
alphaIsTransparency: 0
|
||||
textureType: 5
|
||||
buildTargetSettings: []
|
||||
userData:
|
||||
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
@ -30,6 +30,7 @@ TextureImporter:
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
alphaIsTransparency: 0
|
||||
textureType: 5
|
||||
buildTargetSettings: []
|
||||
userData:
|
||||
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.4 KiB |
@ -30,6 +30,7 @@ TextureImporter:
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
alphaIsTransparency: 0
|
||||
textureType: 5
|
||||
buildTargetSettings: []
|
||||
userData:
|
||||
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.3 KiB |
@ -30,6 +30,7 @@ TextureImporter:
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
alphaIsTransparency: 0
|
||||
textureType: 5
|
||||
buildTargetSettings: []
|
||||
userData:
|
||||
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
@ -30,6 +30,7 @@ TextureImporter:
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
alphaIsTransparency: 0
|
||||
textureType: 5
|
||||
buildTargetSettings: []
|
||||
userData:
|
||||
|
Before Width: | Height: | Size: 6.0 KiB After Width: | Height: | Size: 6.0 KiB |
@ -30,6 +30,7 @@ TextureImporter:
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
alphaIsTransparency: 0
|
||||
textureType: 5
|
||||
buildTargetSettings: []
|
||||
userData:
|
||||
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
@ -30,6 +30,7 @@ TextureImporter:
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
alphaIsTransparency: 0
|
||||
textureType: 5
|
||||
buildTargetSettings: []
|
||||
userData:
|
||||
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.7 KiB |
@ -30,6 +30,7 @@ TextureImporter:
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
alphaIsTransparency: 0
|
||||
textureType: 5
|
||||
buildTargetSettings: []
|
||||
userData:
|
||||
|
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
@ -30,6 +30,7 @@ TextureImporter:
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
alphaIsTransparency: 0
|
||||
textureType: 5
|
||||
buildTargetSettings: []
|
||||
userData:
|
||||
|
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 8.8 KiB |
@ -30,6 +30,7 @@ TextureImporter:
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
alphaIsTransparency: 0
|
||||
textureType: 5
|
||||
buildTargetSettings: []
|
||||
userData:
|
||||
@ -1,4 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a6669a1e8d1cb5c45b165fe92714942b
|
||||
guid: 3e1554ca46e91194fb8d9ead0b21f6f7
|
||||
DefaultImporter:
|
||||
userData:
|
||||
@ -1,44 +0,0 @@
|
||||
using UnityEngine;
|
||||
using Spine;
|
||||
|
||||
// TODO: add events in animation component
|
||||
|
||||
[RequireComponent(typeof(tk2dSpineSkeleton))]
|
||||
public class tk2dSpineAnimation : MonoBehaviour {
|
||||
|
||||
public string animationName;
|
||||
public bool loop;
|
||||
public float animationSpeed = 1;
|
||||
public Spine.AnimationState state;
|
||||
|
||||
private tk2dSpineSkeleton cachedSpineSkeleton;
|
||||
|
||||
void Start () {
|
||||
cachedSpineSkeleton = GetComponent<tk2dSpineSkeleton>();
|
||||
state = new Spine.AnimationState(cachedSpineSkeleton.skeletonDataAsset.GetAnimationStateData());
|
||||
}
|
||||
|
||||
void Update () {
|
||||
UpdateAnimation();
|
||||
}
|
||||
|
||||
private void UpdateAnimation() {
|
||||
// Check if we need to stop current animation
|
||||
if (state.Animation != null && animationName == null) {
|
||||
state.ClearAnimation();
|
||||
}
|
||||
|
||||
// Check for different animation name or animation end
|
||||
else if (state.Animation == null || animationName != state.Animation.Name) {
|
||||
Spine.Animation animation = cachedSpineSkeleton.skeleton.Data.FindAnimation(animationName);
|
||||
if (animation != null) state.SetAnimation(animation,loop);
|
||||
}
|
||||
|
||||
state.Loop = loop;
|
||||
|
||||
// Update animation
|
||||
cachedSpineSkeleton.skeleton.Update(Time.deltaTime * animationSpeed);
|
||||
state.Update(Time.deltaTime * animationSpeed);
|
||||
state.Apply(cachedSpineSkeleton.skeleton);
|
||||
}
|
||||
}
|
||||
@ -1,237 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Spine;
|
||||
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(MeshFilter))]
|
||||
[RequireComponent(typeof(MeshRenderer))]
|
||||
public class tk2dSpineSkeleton : MonoBehaviour, tk2dRuntime.ISpriteCollectionForceBuild {
|
||||
public tk2dSpineSkeletonDataAsset skeletonDataAsset;
|
||||
public Skeleton skeleton;
|
||||
|
||||
private Mesh mesh;
|
||||
private Vector3[] vertices;
|
||||
private Color32[] colors;
|
||||
private Vector2[] uvs;
|
||||
private int cachedQuadCount;
|
||||
private float[] vertexPositions;
|
||||
private List<Material> submeshMaterials = new List<Material>();
|
||||
private List<int[]> submeshIndices = new List<int[]>();
|
||||
|
||||
void Awake() {
|
||||
vertexPositions = new float[8];
|
||||
submeshMaterials = new List<Material>();
|
||||
submeshIndices = new List<int[]>();
|
||||
}
|
||||
|
||||
void Start () {
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void Update () {
|
||||
SkeletonData skeletonData = skeletonDataAsset == null ? null : skeletonDataAsset.GetSkeletonData();
|
||||
if (skeletonData == null) {
|
||||
Clear();
|
||||
return;
|
||||
}
|
||||
|
||||
if (skeleton == null || skeleton.Data != skeletonData) Initialize();
|
||||
|
||||
skeleton.UpdateWorldTransform();
|
||||
|
||||
UpdateCache();
|
||||
UpdateMesh();
|
||||
}
|
||||
|
||||
private void Clear() {
|
||||
GetComponent<MeshFilter>().mesh = null;
|
||||
DestroyImmediate(mesh);
|
||||
mesh = null;
|
||||
|
||||
skeleton = null;
|
||||
}
|
||||
|
||||
private void Initialize() {
|
||||
mesh = new Mesh();
|
||||
GetComponent<MeshFilter>().mesh = mesh;
|
||||
mesh.name = "tk2dSkeleton Mesh";
|
||||
mesh.hideFlags = HideFlags.HideAndDontSave;
|
||||
|
||||
if(skeletonDataAsset != null) {
|
||||
skeleton = new Skeleton(skeletonDataAsset.GetSkeletonData());
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateMesh() {
|
||||
int quadIndex = 0;
|
||||
int drawCount = skeleton.DrawOrder.Count;
|
||||
|
||||
Color32 color = new Color32();
|
||||
for (int i = 0; i < drawCount; i++) {
|
||||
Slot slot = skeleton.DrawOrder[i];
|
||||
Attachment attachment = slot.Attachment;
|
||||
|
||||
if (attachment is RegionAttachment) {
|
||||
RegionAttachment regionAttachment = attachment as RegionAttachment;
|
||||
regionAttachment.ComputeVertices(skeleton.X, skeleton.Y, slot.Bone, vertexPositions);
|
||||
|
||||
int vertexIndex = quadIndex * 4;
|
||||
vertices[vertexIndex + 0] = new Vector3(vertexPositions[RegionAttachment.X1],vertexPositions[RegionAttachment.Y1],0);
|
||||
vertices[vertexIndex + 1] = new Vector3(vertexPositions[RegionAttachment.X4],vertexPositions[RegionAttachment.Y4],0);
|
||||
vertices[vertexIndex + 2] = new Vector3(vertexPositions[RegionAttachment.X2],vertexPositions[RegionAttachment.Y2],0);
|
||||
vertices[vertexIndex + 3] = new Vector3(vertexPositions[RegionAttachment.X3],vertexPositions[RegionAttachment.Y3],0);
|
||||
|
||||
float[] regionUVs = regionAttachment.UVs;
|
||||
uvs[vertexIndex + 0] = new Vector2(regionUVs[RegionAttachment.X1],regionUVs[RegionAttachment.Y1]);
|
||||
uvs[vertexIndex + 1] = new Vector2(regionUVs[RegionAttachment.X4],regionUVs[RegionAttachment.Y4]);
|
||||
uvs[vertexIndex + 2] = new Vector2(regionUVs[RegionAttachment.X2],regionUVs[RegionAttachment.Y2]);
|
||||
uvs[vertexIndex + 3] = new Vector2(regionUVs[RegionAttachment.X3],regionUVs[RegionAttachment.Y3]);
|
||||
|
||||
color.a = (byte)(skeleton.A * slot.A * 255);
|
||||
color.r = (byte)(skeleton.R * slot.R * color.a);
|
||||
color.g = (byte)(skeleton.G * slot.G * color.a);
|
||||
color.b = (byte)(skeleton.B * slot.B * color.a);
|
||||
|
||||
colors[vertexIndex] = color;
|
||||
colors[vertexIndex + 1] = color;
|
||||
colors[vertexIndex + 2] = color;
|
||||
colors[vertexIndex + 3] = color;
|
||||
|
||||
quadIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
mesh.vertices = vertices;
|
||||
mesh.colors32 = colors;
|
||||
mesh.uv = uvs;
|
||||
|
||||
if (skeletonDataAsset.normalGenerationMode != tk2dSpriteCollection.NormalGenerationMode.None) {
|
||||
mesh.RecalculateNormals();
|
||||
|
||||
if (skeletonDataAsset.normalGenerationMode == tk2dSpriteCollection.NormalGenerationMode.NormalsAndTangents) {
|
||||
Vector4[] tangents = new Vector4[mesh.normals.Length];
|
||||
for (int i = 0; i < tangents.Length; i++) {
|
||||
tangents[i] = new Vector4(1, 0, 0, 1);
|
||||
}
|
||||
mesh.tangents = tangents;
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
UpdateEditorGizmo();
|
||||
#endif
|
||||
}
|
||||
|
||||
private void UpdateCache() {
|
||||
int quadCount = 0;
|
||||
int drawCount = skeleton.DrawOrder.Count;
|
||||
|
||||
for (int i = 0; i < drawCount; i++) {
|
||||
Attachment attachment = skeleton.DrawOrder[i].Attachment;
|
||||
if (attachment is RegionAttachment) quadCount++;
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
if (mesh.subMeshCount == submeshIndices.Count)
|
||||
#endif
|
||||
if (quadCount == cachedQuadCount) return;
|
||||
|
||||
cachedQuadCount = quadCount;
|
||||
vertices = new Vector3[quadCount * 4];
|
||||
uvs = new Vector2[quadCount * 4];
|
||||
colors = new Color32[quadCount * 4];
|
||||
|
||||
UpdateSubmeshCache();
|
||||
|
||||
mesh.Clear();
|
||||
mesh.vertices = vertices;
|
||||
mesh.colors32 = colors;
|
||||
mesh.uv = uvs;
|
||||
|
||||
mesh.subMeshCount = submeshIndices.Count;
|
||||
for(int i = 0; i < mesh.subMeshCount; ++i) {
|
||||
mesh.SetTriangles(submeshIndices[i],i);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateSubmeshCache() {
|
||||
submeshIndices.Clear();
|
||||
submeshMaterials.Clear();
|
||||
|
||||
Material oldMaterial = null;
|
||||
List<int> currentSubmesh = new List<int>();
|
||||
int quadIndex = 0;
|
||||
|
||||
int drawCount = skeleton.DrawOrder.Count;
|
||||
for (int i = 0; i < drawCount; i++) {
|
||||
Attachment attachment = skeleton.DrawOrder[i].Attachment;
|
||||
if (!(attachment is RegionAttachment)) continue;
|
||||
Material currentMaterial = skeletonDataAsset.spritesData.GetSpriteDefinition(attachment.Name).material;
|
||||
|
||||
if (oldMaterial == null) oldMaterial = currentMaterial;
|
||||
|
||||
if (oldMaterial != currentMaterial) {
|
||||
submeshIndices.Add(currentSubmesh.ToArray());
|
||||
submeshMaterials.Add(oldMaterial);
|
||||
currentSubmesh.Clear();
|
||||
}
|
||||
|
||||
int vertexIndex = quadIndex * 4;
|
||||
|
||||
currentSubmesh.Add(vertexIndex);
|
||||
currentSubmesh.Add(vertexIndex + 2);
|
||||
currentSubmesh.Add(vertexIndex + 1);
|
||||
currentSubmesh.Add(vertexIndex + 2);
|
||||
currentSubmesh.Add(vertexIndex + 3);
|
||||
currentSubmesh.Add(vertexIndex + 1);
|
||||
|
||||
quadIndex++;
|
||||
|
||||
oldMaterial = currentMaterial;
|
||||
}
|
||||
|
||||
submeshIndices.Add(currentSubmesh.ToArray());
|
||||
submeshMaterials.Add(oldMaterial);
|
||||
|
||||
renderer.sharedMaterials = submeshMaterials.ToArray();
|
||||
}
|
||||
|
||||
|
||||
public bool UsesSpriteCollection(tk2dSpriteCollectionData spriteCollection) {
|
||||
return skeletonDataAsset.spritesData == spriteCollection;
|
||||
}
|
||||
|
||||
public void ForceBuild() {
|
||||
skeletonDataAsset.ForceUpdate();
|
||||
skeleton = new Skeleton(skeletonDataAsset.GetSkeletonData());
|
||||
|
||||
UpdateSubmeshCache();
|
||||
UpdateMesh();
|
||||
}
|
||||
|
||||
#region Unity Editor
|
||||
#if UNITY_EDITOR
|
||||
Vector3 gizmosCenter = new Vector3();
|
||||
Vector3 gizmosSize = new Vector3();
|
||||
Vector3 min = new Vector3(float.MaxValue, float.MaxValue, 0f);
|
||||
Vector3 max = new Vector3(float.MinValue, float.MinValue, 0f);
|
||||
|
||||
void UpdateEditorGizmo() {
|
||||
//determine the minimums and maximums
|
||||
foreach (Vector3 vert in vertices) {
|
||||
min = Vector3.Min(min, vert);
|
||||
max = Vector3.Max(max, vert);
|
||||
}
|
||||
float width = max.x - min.x;
|
||||
float height = max.y - min.y;
|
||||
gizmosCenter = new Vector3(min.x + (width / 2f), min.y + (height / 2f), 0f);
|
||||
gizmosSize = new Vector3(width, height, 1f);
|
||||
}
|
||||
void OnDrawGizmos() {
|
||||
Gizmos.color = Color.clear;
|
||||
Gizmos.matrix = transform.localToWorldMatrix;
|
||||
Gizmos.DrawCube(gizmosCenter, gizmosSize);
|
||||
}
|
||||
#endif
|
||||
#endregion
|
||||
}
|
||||
@ -1,64 +0,0 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
using Spine;
|
||||
|
||||
public class tk2dSpineSkeletonDataAsset : ScriptableObject {
|
||||
public tk2dSpriteCollectionData spritesData;
|
||||
public tk2dSpriteCollection.NormalGenerationMode normalGenerationMode = tk2dSpriteCollection.NormalGenerationMode.None;
|
||||
|
||||
public TextAsset skeletonJSON;
|
||||
|
||||
public string[] fromAnimation;
|
||||
public string[] toAnimation;
|
||||
public float[] duration;
|
||||
|
||||
private SkeletonData skeletonData;
|
||||
private AnimationStateData stateData;
|
||||
|
||||
public SkeletonData GetSkeletonData() {
|
||||
if (skeletonData != null) return skeletonData;
|
||||
|
||||
MakeSkeletonAndAnimationData();
|
||||
return skeletonData;
|
||||
}
|
||||
|
||||
public AnimationStateData GetAnimationStateData () {
|
||||
if (stateData != null) return stateData;
|
||||
|
||||
MakeSkeletonAndAnimationData();
|
||||
return stateData;
|
||||
}
|
||||
|
||||
private void MakeSkeletonAndAnimationData() {
|
||||
if (spritesData == null) {
|
||||
Debug.LogWarning("Sprite collection not set for skeleton data asset: " + name,this);
|
||||
return;
|
||||
}
|
||||
|
||||
if (skeletonJSON == null) {
|
||||
Debug.LogWarning("Skeleton JSON file not set for skeleton data asset: " + name,this);
|
||||
return;
|
||||
}
|
||||
|
||||
SkeletonJson json = new SkeletonJson(new tk2dSpineAttachmentLoader(spritesData));
|
||||
json.Scale = 1.0f / (spritesData.invOrthoSize * spritesData.halfTargetHeight);
|
||||
|
||||
try {
|
||||
skeletonData = json.ReadSkeletonData(new StringReader(skeletonJSON.text));
|
||||
} catch (Exception ex) {
|
||||
Debug.Log("Error reading skeleton JSON file for skeleton data asset: " + name + "\n" + ex.Message + "\n" + ex.StackTrace,this);
|
||||
return;
|
||||
}
|
||||
|
||||
stateData = new AnimationStateData(skeletonData);
|
||||
for (int i = 0, n = fromAnimation.Length; i < n; i++) {
|
||||
if (fromAnimation[i].Length == 0 || toAnimation[i].Length == 0) continue;
|
||||
stateData.SetMix(fromAnimation[i], toAnimation[i], duration[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public void ForceUpdate() {
|
||||
MakeSkeletonAndAnimationData();
|
||||
}
|
||||
}
|
||||
@ -1,74 +0,0 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using Spine;
|
||||
|
||||
/*
|
||||
*/
|
||||
public class tk2dSpineMenus {
|
||||
|
||||
/*
|
||||
*/
|
||||
[MenuItem("Assets/Create/tk2d/Spine Skeleton Data")]
|
||||
static public void CreateSkeletonData() {
|
||||
string path = "";
|
||||
try {
|
||||
path = Path.GetDirectoryName(AssetDatabase.GetAssetPath(Selection.activeObject)) + "/";
|
||||
} catch (Exception) {
|
||||
path = "Assets/";
|
||||
}
|
||||
|
||||
ScriptableObject asset = ScriptableObject.CreateInstance<tk2dSpineSkeletonDataAsset>();
|
||||
AssetDatabase.CreateAsset(asset,path + "New Spine Skeleton Data.asset");
|
||||
AssetDatabase.SaveAssets();
|
||||
EditorUtility.FocusProjectWindow();
|
||||
Selection.activeObject = asset;
|
||||
}
|
||||
|
||||
/*
|
||||
*/
|
||||
[MenuItem("GameObject/Create Other/tk2d/Spine Skeleton")]
|
||||
static public void CreateSkeletonGameObject() {
|
||||
GameObject gameObject = new GameObject("New tk2d Spine Skeleton",typeof(tk2dSpineSkeleton));
|
||||
EditorUtility.FocusProjectWindow();
|
||||
Selection.activeObject = gameObject;
|
||||
}
|
||||
|
||||
/*
|
||||
*/
|
||||
[MenuItem("GameObject/Create Other/tk2d/Spine Animated Skeleton")]
|
||||
static public void CreateAnimatedSkeletonGameObject() {
|
||||
GameObject gameObject = new GameObject("New tk2d Spine Animated Skeleton",typeof(tk2dSpineAnimation));
|
||||
EditorUtility.FocusProjectWindow();
|
||||
Selection.activeObject = gameObject;
|
||||
}
|
||||
|
||||
/*
|
||||
*/
|
||||
[MenuItem("Component/2D Toolkit/Spine Skeleton")]
|
||||
static public void CreateSkeletonComponent() {
|
||||
Selection.activeGameObject.AddComponent(typeof(tk2dSpineSkeleton));
|
||||
}
|
||||
|
||||
/*
|
||||
*/
|
||||
[MenuItem("Component/2d Toolkit/Spine Skeleton",true)]
|
||||
static public bool ValidateCreateSkeletonComponent() {
|
||||
return Selection.activeGameObject != null && Selection.activeGameObject.GetComponent(typeof(tk2dSpineSkeleton)) == null;
|
||||
}
|
||||
|
||||
/*
|
||||
*/
|
||||
[MenuItem("Component/2D Toolkit/Spine Animation")]
|
||||
static public void CreateAnimationComponent() {
|
||||
Selection.activeGameObject.AddComponent(typeof(tk2dSpineAnimation));
|
||||
}
|
||||
|
||||
/*
|
||||
*/
|
||||
[MenuItem("Component/2d Toolkit/Spine Animation",true)]
|
||||
static public bool ValidateCreateAnimationComponent() {
|
||||
return Selection.activeGameObject != null && Selection.activeGameObject.GetComponent(typeof(tk2dSpineAnimation)) == null;
|
||||
}
|
||||
}
|
||||
@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5673189c5c1030b4783c8945f5a5f52e
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@ -1,113 +0,0 @@
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using Spine;
|
||||
|
||||
/*
|
||||
*/
|
||||
[CustomEditor(typeof(tk2dSpineSkeletonDataAsset))]
|
||||
public class tk2dSpineSkeletonDataAssetInspector : Editor {
|
||||
|
||||
/*
|
||||
*/
|
||||
private SerializedProperty skeletonJSON;
|
||||
private SerializedProperty fromAnimation;
|
||||
private SerializedProperty toAnimation;
|
||||
private SerializedProperty duration;
|
||||
private bool showAnimationStateData = true;
|
||||
|
||||
private tk2dSpriteCollection sprites;
|
||||
|
||||
/*
|
||||
*/
|
||||
void OnEnable () {
|
||||
|
||||
tk2dSpineSkeletonDataAsset skeletonDataAsset = target as tk2dSpineSkeletonDataAsset;
|
||||
|
||||
if (skeletonDataAsset != null) {
|
||||
tk2dSpriteCollectionData spritesData = skeletonDataAsset.spritesData;
|
||||
|
||||
if (spritesData != null) {
|
||||
sprites = AssetDatabase.LoadAssetAtPath( AssetDatabase.GUIDToAssetPath(spritesData.spriteCollectionGUID), typeof(tk2dSpriteCollection) ) as tk2dSpriteCollection;
|
||||
}
|
||||
}
|
||||
|
||||
skeletonJSON = serializedObject.FindProperty("skeletonJSON");
|
||||
fromAnimation = serializedObject.FindProperty("fromAnimation");
|
||||
toAnimation = serializedObject.FindProperty("toAnimation");
|
||||
duration = serializedObject.FindProperty("duration");
|
||||
}
|
||||
|
||||
/*
|
||||
*/
|
||||
public override void OnInspectorGUI () {
|
||||
serializedObject.Update();
|
||||
|
||||
tk2dSpineSkeletonDataAsset asset = target as tk2dSpineSkeletonDataAsset;
|
||||
|
||||
EditorGUIUtility.LookLikeInspector();
|
||||
sprites = EditorGUILayout.ObjectField("Sprites", sprites, typeof(tk2dSpriteCollection), false) as tk2dSpriteCollection;
|
||||
|
||||
if (sprites != null) {
|
||||
SerializedProperty spritesData = serializedObject.FindProperty("spritesData");
|
||||
spritesData.objectReferenceValue = sprites.spriteCollection;
|
||||
|
||||
SerializedProperty normalGenerationMode = serializedObject.FindProperty("normalGenerationMode");
|
||||
normalGenerationMode.enumValueIndex = (int)sprites.normalGenerationMode;
|
||||
} else {
|
||||
SerializedProperty spritesData = serializedObject.FindProperty("spritesData");
|
||||
spritesData.objectReferenceValue = null;
|
||||
|
||||
SerializedProperty normalGenerationMode = serializedObject.FindProperty("normalGenerationMode");
|
||||
normalGenerationMode.enumValueIndex = (int)tk2dSpriteCollection.NormalGenerationMode.None;
|
||||
}
|
||||
|
||||
EditorGUILayout.PropertyField(skeletonJSON);
|
||||
|
||||
SkeletonData skeletonData = asset.GetSkeletonData();
|
||||
if(skeletonData != null) {
|
||||
showAnimationStateData = EditorGUILayout.Foldout(showAnimationStateData,"Animation State Data");
|
||||
if(showAnimationStateData) {
|
||||
|
||||
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);
|
||||
SerializedProperty durationProp = duration.GetArrayElementAtIndex(i);
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
|
||||
from.stringValue = animations[EditorGUILayout.Popup(Math.Max(Array.IndexOf(animations,from.stringValue),0),animations)];
|
||||
to.stringValue = animations[EditorGUILayout.Popup(Math.Max(Array.IndexOf(animations,to.stringValue),0),animations)];
|
||||
durationProp.floatValue = EditorGUILayout.FloatField(durationProp.floatValue);
|
||||
|
||||
if(GUILayout.Button("Delete")) {
|
||||
duration.DeleteArrayElementAtIndex(i);
|
||||
toAnimation.DeleteArrayElementAtIndex(i);
|
||||
fromAnimation.DeleteArrayElementAtIndex(i);
|
||||
}
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.Space();
|
||||
|
||||
if(GUILayout.Button("Add Mix")) {
|
||||
duration.arraySize++;
|
||||
toAnimation.arraySize++;
|
||||
fromAnimation.arraySize++;
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||