|
@@ -35,6 +35,7 @@
|
|
|
* Spine Editor Utilities created by Mitch Thompson
|
|
|
* Full irrevocable rights and permissions granted to Esoteric Software
|
|
|
*****************************************************************************/
|
|
|
+#define SPINE_SKELETONANIMATOR
|
|
|
using UnityEngine;
|
|
|
using UnityEditor;
|
|
|
using System.Collections;
|
|
@@ -45,253 +46,257 @@ using System.Linq;
|
|
|
using System.Reflection;
|
|
|
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 slotRoot;
|
|
|
- public static Texture2D skinPlaceholder;
|
|
|
- public static Texture2D image;
|
|
|
- public static Texture2D boundingBox;
|
|
|
- public static Texture2D mesh;
|
|
|
- public static Texture2D weights;
|
|
|
- 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 Texture2D unityIcon;
|
|
|
- public static Texture2D controllerIcon;
|
|
|
-
|
|
|
- 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();
|
|
|
- }
|
|
|
+namespace Spine.Unity.Editor {
|
|
|
+
|
|
|
+ [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 slotRoot;
|
|
|
+ public static Texture2D skinPlaceholder;
|
|
|
+ public static Texture2D image;
|
|
|
+ public static Texture2D boundingBox;
|
|
|
+ public static Texture2D mesh;
|
|
|
+ public static Texture2D weights;
|
|
|
+ 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 Texture2D unityIcon;
|
|
|
+ public static Texture2D controllerIcon;
|
|
|
+
|
|
|
+ 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;
|
|
|
+ return _boneMesh;
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- internal static Mesh _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
|
|
|
|
|
|
- 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;
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- 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");
|
|
|
+ slotRoot = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-slotRoot.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");
|
|
|
+ weights = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-weights.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");
|
|
|
+
|
|
|
+ unityIcon = EditorGUIUtility.FindTexture("SceneAsset Icon");
|
|
|
+
|
|
|
+ controllerIcon = EditorGUIUtility.FindTexture("AnimatorController Icon");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- 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");
|
|
|
- slotRoot = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-slotRoot.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");
|
|
|
- weights = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-weights.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");
|
|
|
-
|
|
|
- unityIcon = EditorGUIUtility.FindTexture("SceneAsset Icon");
|
|
|
-
|
|
|
- controllerIcon = EditorGUIUtility.FindTexture("AnimatorController Icon");
|
|
|
- }
|
|
|
- }
|
|
|
+ public static string editorPath = "";
|
|
|
+ public static string editorGUIPath = "";
|
|
|
+ static HashSet<string> assetsImportedInWrongState;
|
|
|
+ static Dictionary<int, GameObject> skeletonRendererTable;
|
|
|
+ static Dictionary<int, SkeletonUtilityBone> skeletonUtilityBoneTable;
|
|
|
+ static Dictionary<int, BoundingBoxFollower> boundingBoxFollowerTable;
|
|
|
+ public static float defaultScale = 0.01f;
|
|
|
+ public static float defaultMix = 0.2f;
|
|
|
+ public static string defaultShader = "Spine/Skeleton";
|
|
|
+ public static bool initialized;
|
|
|
|
|
|
- public static string editorPath = "";
|
|
|
- public static string editorGUIPath = "";
|
|
|
- static HashSet<string> assetsImportedInWrongState;
|
|
|
- static Dictionary<int, GameObject> skeletonRendererTable;
|
|
|
- static Dictionary<int, SkeletonUtilityBone> skeletonUtilityBoneTable;
|
|
|
- static Dictionary<int, BoundingBoxFollower> boundingBoxFollowerTable;
|
|
|
- public static float defaultScale = 0.01f;
|
|
|
- public static float defaultMix = 0.2f;
|
|
|
- public static string defaultShader = "Spine/Skeleton";
|
|
|
- public static bool initialized;
|
|
|
-
|
|
|
- const string DEFAULT_MIX_KEY = "SPINE_DEFAULT_MIX";
|
|
|
-
|
|
|
- static SpineEditorUtilities () {
|
|
|
- Initialize();
|
|
|
- }
|
|
|
+ const string DEFAULT_MIX_KEY = "SPINE_DEFAULT_MIX";
|
|
|
|
|
|
- static void Initialize () {
|
|
|
- defaultMix = EditorPrefs.GetFloat(DEFAULT_MIX_KEY, 0.2f);
|
|
|
+ static SpineEditorUtilities () {
|
|
|
+ Initialize();
|
|
|
+ }
|
|
|
|
|
|
- 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";
|
|
|
+ static void Initialize () {
|
|
|
+ defaultMix = EditorPrefs.GetFloat(DEFAULT_MIX_KEY, 0.2f);
|
|
|
|
|
|
- Icons.Initialize();
|
|
|
+ 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";
|
|
|
|
|
|
- assetsImportedInWrongState = new HashSet<string>();
|
|
|
- skeletonRendererTable = new Dictionary<int, GameObject>();
|
|
|
- skeletonUtilityBoneTable = new Dictionary<int, SkeletonUtilityBone>();
|
|
|
- boundingBoxFollowerTable = new Dictionary<int, BoundingBoxFollower>();
|
|
|
+ Icons.Initialize();
|
|
|
|
|
|
- EditorApplication.hierarchyWindowChanged += HierarchyWindowChanged;
|
|
|
- EditorApplication.hierarchyWindowItemOnGUI += HierarchyWindowItemOnGUI;
|
|
|
+ assetsImportedInWrongState = new HashSet<string>();
|
|
|
+ skeletonRendererTable = new Dictionary<int, GameObject>();
|
|
|
+ skeletonUtilityBoneTable = new Dictionary<int, SkeletonUtilityBone>();
|
|
|
+ boundingBoxFollowerTable = new Dictionary<int, BoundingBoxFollower>();
|
|
|
|
|
|
- HierarchyWindowChanged();
|
|
|
- initialized = true;
|
|
|
- }
|
|
|
+ EditorApplication.hierarchyWindowChanged += HierarchyWindowChanged;
|
|
|
+ EditorApplication.hierarchyWindowItemOnGUI += HierarchyWindowItemOnGUI;
|
|
|
|
|
|
- public static void ConfirmInitialization () {
|
|
|
- if (!initialized || Icons.skeleton == null)
|
|
|
- Initialize();
|
|
|
- }
|
|
|
+ HierarchyWindowChanged();
|
|
|
+ initialized = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void ConfirmInitialization () {
|
|
|
+ if (!initialized || Icons.skeleton == null)
|
|
|
+ Initialize();
|
|
|
+ }
|
|
|
|
|
|
- static void HierarchyWindowChanged () {
|
|
|
- skeletonRendererTable.Clear();
|
|
|
- skeletonUtilityBoneTable.Clear();
|
|
|
- boundingBoxFollowerTable.Clear();
|
|
|
+ #region Hierarchy Icon
|
|
|
+ static void HierarchyWindowChanged () {
|
|
|
+ skeletonRendererTable.Clear();
|
|
|
+ skeletonUtilityBoneTable.Clear();
|
|
|
+ boundingBoxFollowerTable.Clear();
|
|
|
|
|
|
- SkeletonRenderer[] arr = Object.FindObjectsOfType<SkeletonRenderer>();
|
|
|
- foreach (SkeletonRenderer r in arr)
|
|
|
- skeletonRendererTable.Add(r.gameObject.GetInstanceID(), r.gameObject);
|
|
|
+ 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);
|
|
|
+ SkeletonUtilityBone[] boneArr = Object.FindObjectsOfType<SkeletonUtilityBone>();
|
|
|
+ foreach (SkeletonUtilityBone b in boneArr)
|
|
|
+ skeletonUtilityBoneTable.Add(b.gameObject.GetInstanceID(), b);
|
|
|
|
|
|
- BoundingBoxFollower[] bbfArr = Object.FindObjectsOfType<BoundingBoxFollower>();
|
|
|
- foreach (BoundingBoxFollower bbf in bbfArr)
|
|
|
- boundingBoxFollowerTable.Add(bbf.gameObject.GetInstanceID(), bbf);
|
|
|
- }
|
|
|
+ BoundingBoxFollower[] bbfArr = Object.FindObjectsOfType<BoundingBoxFollower>();
|
|
|
+ foreach (BoundingBoxFollower bbf in bbfArr)
|
|
|
+ boundingBoxFollowerTable.Add(bbf.gameObject.GetInstanceID(), bbf);
|
|
|
+ }
|
|
|
|
|
|
- static void HierarchyWindowItemOnGUI (int instanceId, Rect selectionRect) {
|
|
|
- if (skeletonRendererTable.ContainsKey(instanceId)) {
|
|
|
- Rect r = new Rect(selectionRect);
|
|
|
- r.x = r.width - 15;
|
|
|
- r.width = 15;
|
|
|
+ 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;
|
|
|
+ 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;
|
|
|
+ if (skeletonUtilityBoneTable[instanceId] != null) {
|
|
|
+ if (skeletonUtilityBoneTable[instanceId].transform.childCount == 0)
|
|
|
+ r.x += 13;
|
|
|
|
|
|
- r.y += 2;
|
|
|
+ r.y += 2;
|
|
|
|
|
|
- r.width = 13;
|
|
|
- r.height = 13;
|
|
|
+ r.width = 13;
|
|
|
+ r.height = 13;
|
|
|
|
|
|
- if (skeletonUtilityBoneTable[instanceId].mode == SkeletonUtilityBone.Mode.Follow) {
|
|
|
- GUI.DrawTexture(r, Icons.bone);
|
|
|
- } else {
|
|
|
- GUI.DrawTexture(r, Icons.poseBones);
|
|
|
+ if (skeletonUtilityBoneTable[instanceId].mode == SkeletonUtilityBone.Mode.Follow) {
|
|
|
+ GUI.DrawTexture(r, Icons.bone);
|
|
|
+ } else {
|
|
|
+ GUI.DrawTexture(r, Icons.poseBones);
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- } else if (boundingBoxFollowerTable.ContainsKey(instanceId)) {
|
|
|
- Rect r = new Rect(selectionRect);
|
|
|
- r.x -= 26;
|
|
|
+ } else if (boundingBoxFollowerTable.ContainsKey(instanceId)) {
|
|
|
+ Rect r = new Rect(selectionRect);
|
|
|
+ r.x -= 26;
|
|
|
|
|
|
- if (boundingBoxFollowerTable[instanceId] != null) {
|
|
|
- if (boundingBoxFollowerTable[instanceId].transform.childCount == 0)
|
|
|
- r.x += 13;
|
|
|
+ if (boundingBoxFollowerTable[instanceId] != null) {
|
|
|
+ if (boundingBoxFollowerTable[instanceId].transform.childCount == 0)
|
|
|
+ r.x += 13;
|
|
|
|
|
|
- r.y += 2;
|
|
|
+ r.y += 2;
|
|
|
|
|
|
- r.width = 13;
|
|
|
- r.height = 13;
|
|
|
+ r.width = 13;
|
|
|
+ r.height = 13;
|
|
|
|
|
|
- GUI.DrawTexture(r, Icons.boundingBox);
|
|
|
+ GUI.DrawTexture(r, Icons.boundingBox);
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- }
|
|
|
-
|
|
|
- static void OnPostprocessAllAssets (string[] imported, string[] deleted, string[] moved, string[] movedFromAssetPaths) {
|
|
|
- if (imported.Length == 0)
|
|
|
- return;
|
|
|
-
|
|
|
- // In case user used "Assets -> Reimport All", during the import process,
|
|
|
- // asset database is not initialized until some point. During that period,
|
|
|
- // all attempts to load any assets using API (i.e. AssetDatabase.LoadAssetAtPath)
|
|
|
- // will return null, and as result, assets won't be loaded even if they actually exists,
|
|
|
- // which may lead to numerous importing errors.
|
|
|
- // This situation also happens if Library folder is deleted from the project, which is a pretty
|
|
|
- // common case, since when using version control systems, the Library folder must be excluded.
|
|
|
- //
|
|
|
- // So to avoid this, in case asset database is not available, we delay loading the assets
|
|
|
- // until next time.
|
|
|
- //
|
|
|
- // Unity *always* reimports some internal assets after the process is done, so this method
|
|
|
- // is always called once again in a state when asset database is available.
|
|
|
- //
|
|
|
- // Checking whether AssetDatabase is initialized is done by attempting to load
|
|
|
- // a known "marker" asset that should always be available. Failing to load this asset
|
|
|
- // means that AssetDatabase is not initialized.
|
|
|
- assetsImportedInWrongState.UnionWith(imported);
|
|
|
- if (AssetDatabaseAvailabilityDetector.IsAssetDatabaseAvailable()) {
|
|
|
- string[] combinedAssets = assetsImportedInWrongState.ToArray();
|
|
|
- assetsImportedInWrongState.Clear();
|
|
|
- ImportSpineContent(combinedAssets);
|
|
|
}
|
|
|
- }
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ static void OnPostprocessAllAssets (string[] imported, string[] deleted, string[] moved, string[] movedFromAssetPaths) {
|
|
|
+ if (imported.Length == 0)
|
|
|
+ return;
|
|
|
+
|
|
|
+ // In case user used "Assets -> Reimport All", during the import process,
|
|
|
+ // asset database is not initialized until some point. During that period,
|
|
|
+ // all attempts to load any assets using API (i.e. AssetDatabase.LoadAssetAtPath)
|
|
|
+ // will return null, and as result, assets won't be loaded even if they actually exists,
|
|
|
+ // which may lead to numerous importing errors.
|
|
|
+ // This situation also happens if Library folder is deleted from the project, which is a pretty
|
|
|
+ // common case, since when using version control systems, the Library folder must be excluded.
|
|
|
+ //
|
|
|
+ // So to avoid this, in case asset database is not available, we delay loading the assets
|
|
|
+ // until next time.
|
|
|
+ //
|
|
|
+ // Unity *always* reimports some internal assets after the process is done, so this method
|
|
|
+ // is always called once again in a state when asset database is available.
|
|
|
+ //
|
|
|
+ // Checking whether AssetDatabase is initialized is done by attempting to load
|
|
|
+ // a known "marker" asset that should always be available. Failing to load this asset
|
|
|
+ // means that AssetDatabase is not initialized.
|
|
|
+ assetsImportedInWrongState.UnionWith(imported);
|
|
|
+ if (AssetDatabaseAvailabilityDetector.IsAssetDatabaseAvailable()) {
|
|
|
+ string[] combinedAssets = assetsImportedInWrongState.ToArray();
|
|
|
+ assetsImportedInWrongState.Clear();
|
|
|
+ ImportSpineContent(combinedAssets);
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- public static void ImportSpineContent (string[] imported, bool reimport = false) {
|
|
|
- List<string> atlasPaths = new List<string>();
|
|
|
- List<string> imagePaths = new List<string>();
|
|
|
- List<string> skeletonPaths = new List<string>();
|
|
|
+ public static void ImportSpineContent (string[] imported, bool reimport = false) {
|
|
|
+ List<string> atlasPaths = new List<string>();
|
|
|
+ List<string> imagePaths = new List<string>();
|
|
|
+ List<string> skeletonPaths = new List<string>();
|
|
|
|
|
|
- foreach (string str in imported) {
|
|
|
- string extension = Path.GetExtension(str).ToLower();
|
|
|
- switch (extension) {
|
|
|
+ foreach (string str in imported) {
|
|
|
+ string extension = Path.GetExtension(str).ToLower();
|
|
|
+ switch (extension) {
|
|
|
case ".txt":
|
|
|
if (str.EndsWith(".atlas.txt")) {
|
|
|
atlasPaths.Add(str);
|
|
@@ -311,44 +316,44 @@ public class SpineEditorUtilities : AssetPostprocessor {
|
|
|
skeletonPaths.Add(str);
|
|
|
}
|
|
|
break;
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
|
|
|
- List<AtlasAsset> atlases = new List<AtlasAsset>();
|
|
|
+ List<AtlasAsset> atlases = new List<AtlasAsset>();
|
|
|
|
|
|
- //import atlases first
|
|
|
- foreach (string ap in atlasPaths) {
|
|
|
- if (!reimport && CheckForValidAtlas(ap))
|
|
|
- continue;
|
|
|
+ //import atlases first
|
|
|
+ foreach (string ap in atlasPaths) {
|
|
|
+ if (!reimport && CheckForValidAtlas(ap))
|
|
|
+ continue;
|
|
|
|
|
|
- TextAsset atlasText = (TextAsset)AssetDatabase.LoadAssetAtPath(ap, typeof(TextAsset));
|
|
|
- AtlasAsset atlas = IngestSpineAtlas(atlasText);
|
|
|
- atlases.Add(atlas);
|
|
|
- }
|
|
|
-
|
|
|
- //import skeletons and match them with atlases
|
|
|
- bool abortSkeletonImport = false;
|
|
|
- foreach (string sp in skeletonPaths) {
|
|
|
- if (!reimport && CheckForValidSkeletonData(sp)) {
|
|
|
- ResetExistingSkeletonData(sp);
|
|
|
- continue;
|
|
|
+ TextAsset atlasText = (TextAsset)AssetDatabase.LoadAssetAtPath(ap, typeof(TextAsset));
|
|
|
+ AtlasAsset atlas = IngestSpineAtlas(atlasText);
|
|
|
+ atlases.Add(atlas);
|
|
|
}
|
|
|
|
|
|
+ //import skeletons and match them with atlases
|
|
|
+ bool abortSkeletonImport = false;
|
|
|
+ foreach (string sp in skeletonPaths) {
|
|
|
+ if (!reimport && CheckForValidSkeletonData(sp)) {
|
|
|
+ ResetExistingSkeletonData(sp);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
|
|
|
- string dir = Path.GetDirectoryName(sp);
|
|
|
|
|
|
- var localAtlases = FindAtlasesAtPath(dir);
|
|
|
- var requiredPaths = GetRequiredAtlasRegions(sp);
|
|
|
- var atlasMatch = GetMatchingAtlas(requiredPaths, localAtlases);
|
|
|
+ string dir = Path.GetDirectoryName(sp);
|
|
|
|
|
|
- if (atlasMatch != null) {
|
|
|
- IngestSpineProject(AssetDatabase.LoadAssetAtPath(sp, typeof(TextAsset)) as TextAsset, atlasMatch);
|
|
|
- } else {
|
|
|
- bool resolved = false;
|
|
|
- while (!resolved) {
|
|
|
- int result = EditorUtility.DisplayDialogComplex("Skeleton JSON Import Error!", "Could not find matching AtlasAsset for " + Path.GetFileNameWithoutExtension(sp), "Select", "Skip", "Abort");
|
|
|
- switch (result) {
|
|
|
+ var localAtlases = FindAtlasesAtPath(dir);
|
|
|
+ var requiredPaths = GetRequiredAtlasRegions(sp);
|
|
|
+ var atlasMatch = GetMatchingAtlas(requiredPaths, localAtlases);
|
|
|
+
|
|
|
+ if (atlasMatch != null) {
|
|
|
+ IngestSpineProject(AssetDatabase.LoadAssetAtPath(sp, typeof(TextAsset)) as TextAsset, atlasMatch);
|
|
|
+ } else {
|
|
|
+ bool resolved = false;
|
|
|
+ while (!resolved) {
|
|
|
+ int result = EditorUtility.DisplayDialogComplex("Skeleton JSON Import Error!", "Could not find matching AtlasAsset for " + Path.GetFileNameWithoutExtension(sp), "Select", "Skip", "Abort");
|
|
|
+ switch (result) {
|
|
|
case -1:
|
|
|
Debug.Log("Select Atlas");
|
|
|
AtlasAsset selectedAtlas = GetAtlasDialog(Path.GetDirectoryName(sp));
|
|
@@ -383,104 +388,96 @@ public class SpineEditorUtilities : AssetPostprocessor {
|
|
|
abortSkeletonImport = true;
|
|
|
resolved = true;
|
|
|
break;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ if (abortSkeletonImport)
|
|
|
+ break;
|
|
|
}
|
|
|
|
|
|
- if (abortSkeletonImport)
|
|
|
- break;
|
|
|
+ //TODO: any post processing of images
|
|
|
}
|
|
|
|
|
|
- //TODO: any post processing of images
|
|
|
- }
|
|
|
-
|
|
|
- static bool CheckForValidSkeletonData (string skeletonJSONPath) {
|
|
|
+ static bool CheckForValidSkeletonData (string skeletonJSONPath) {
|
|
|
|
|
|
- string dir = Path.GetDirectoryName(skeletonJSONPath);
|
|
|
- TextAsset textAsset = (TextAsset)AssetDatabase.LoadAssetAtPath(skeletonJSONPath, typeof(TextAsset));
|
|
|
- DirectoryInfo dirInfo = new DirectoryInfo(dir);
|
|
|
+ string dir = Path.GetDirectoryName(skeletonJSONPath);
|
|
|
+ TextAsset textAsset = (TextAsset)AssetDatabase.LoadAssetAtPath(skeletonJSONPath, typeof(TextAsset));
|
|
|
+ DirectoryInfo dirInfo = new DirectoryInfo(dir);
|
|
|
|
|
|
- FileInfo[] files = dirInfo.GetFiles("*.asset");
|
|
|
+ FileInfo[] files = dirInfo.GetFiles("*.asset");
|
|
|
|
|
|
- foreach (var f in files) {
|
|
|
- string localPath = dir + "/" + f.Name;
|
|
|
- var obj = AssetDatabase.LoadAssetAtPath(localPath, typeof(Object));
|
|
|
- if (obj is SkeletonDataAsset) {
|
|
|
- var skeletonDataAsset = (SkeletonDataAsset)obj;
|
|
|
- if (skeletonDataAsset.skeletonJSON == textAsset)
|
|
|
- return true;
|
|
|
+ foreach (var f in files) {
|
|
|
+ string localPath = dir + "/" + f.Name;
|
|
|
+ var obj = AssetDatabase.LoadAssetAtPath(localPath, typeof(Object));
|
|
|
+ if (obj is SkeletonDataAsset) {
|
|
|
+ var skeletonDataAsset = (SkeletonDataAsset)obj;
|
|
|
+ if (skeletonDataAsset.skeletonJSON == textAsset)
|
|
|
+ return true;
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
- return false;
|
|
|
- }
|
|
|
+ static void ResetExistingSkeletonData (string skeletonJSONPath) {
|
|
|
|
|
|
- static void ResetExistingSkeletonData (string skeletonJSONPath) {
|
|
|
+ string dir = Path.GetDirectoryName(skeletonJSONPath);
|
|
|
+ TextAsset textAsset = (TextAsset)AssetDatabase.LoadAssetAtPath(skeletonJSONPath, typeof(TextAsset));
|
|
|
+ DirectoryInfo dirInfo = new DirectoryInfo(dir);
|
|
|
|
|
|
- string dir = Path.GetDirectoryName(skeletonJSONPath);
|
|
|
- TextAsset textAsset = (TextAsset)AssetDatabase.LoadAssetAtPath(skeletonJSONPath, typeof(TextAsset));
|
|
|
- DirectoryInfo dirInfo = new DirectoryInfo(dir);
|
|
|
+ FileInfo[] files = dirInfo.GetFiles("*.asset");
|
|
|
|
|
|
- FileInfo[] files = dirInfo.GetFiles("*.asset");
|
|
|
+ foreach (var f in files) {
|
|
|
+ string localPath = dir + "/" + f.Name;
|
|
|
+ var obj = AssetDatabase.LoadAssetAtPath(localPath, typeof(Object));
|
|
|
+ if (obj is SkeletonDataAsset) {
|
|
|
+ var skeletonDataAsset = (SkeletonDataAsset)obj;
|
|
|
|
|
|
- foreach (var f in files) {
|
|
|
- string localPath = dir + "/" + f.Name;
|
|
|
- var obj = AssetDatabase.LoadAssetAtPath(localPath, typeof(Object));
|
|
|
- if (obj is SkeletonDataAsset) {
|
|
|
- var skeletonDataAsset = (SkeletonDataAsset)obj;
|
|
|
+ if (skeletonDataAsset.skeletonJSON == textAsset) {
|
|
|
+ if (Selection.activeObject == skeletonDataAsset)
|
|
|
+ Selection.activeObject = null;
|
|
|
|
|
|
- if (skeletonDataAsset.skeletonJSON == textAsset) {
|
|
|
- if (Selection.activeObject == skeletonDataAsset)
|
|
|
- Selection.activeObject = null;
|
|
|
+ skeletonDataAsset.Reset();
|
|
|
|
|
|
- skeletonDataAsset.Reset();
|
|
|
+ string guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(skeletonDataAsset));
|
|
|
+ string lastHash = EditorPrefs.GetString(guid + "_hash");
|
|
|
|
|
|
- string guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(skeletonDataAsset));
|
|
|
- string lastHash = EditorPrefs.GetString(guid + "_hash");
|
|
|
-
|
|
|
- // For some weird reason sometimes Unity loses the internal Object pointer,
|
|
|
- // and as a result, all comparisons with null returns true.
|
|
|
- // But the C# wrapper is still alive, so we can "restore" the object
|
|
|
- // by reloading it from its Instance ID.
|
|
|
- AtlasAsset[] skeletonDataAtlasAssets = skeletonDataAsset.atlasAssets;
|
|
|
- if (skeletonDataAtlasAssets != null) {
|
|
|
- for (int i = 0; i < skeletonDataAtlasAssets.Length; i++) {
|
|
|
- if (!ReferenceEquals(null, skeletonDataAtlasAssets[i]) &&
|
|
|
- skeletonDataAtlasAssets[i].Equals(null) &&
|
|
|
- skeletonDataAtlasAssets[i].GetInstanceID() != 0
|
|
|
+ // For some weird reason sometimes Unity loses the internal Object pointer,
|
|
|
+ // and as a result, all comparisons with null returns true.
|
|
|
+ // But the C# wrapper is still alive, so we can "restore" the object
|
|
|
+ // by reloading it from its Instance ID.
|
|
|
+ AtlasAsset[] skeletonDataAtlasAssets = skeletonDataAsset.atlasAssets;
|
|
|
+ if (skeletonDataAtlasAssets != null) {
|
|
|
+ for (int i = 0; i < skeletonDataAtlasAssets.Length; i++) {
|
|
|
+ if (!ReferenceEquals(null, skeletonDataAtlasAssets[i]) &&
|
|
|
+ skeletonDataAtlasAssets[i].Equals(null) &&
|
|
|
+ skeletonDataAtlasAssets[i].GetInstanceID() != 0
|
|
|
) {
|
|
|
- skeletonDataAtlasAssets[i] = EditorUtility.InstanceIDToObject(skeletonDataAtlasAssets[i].GetInstanceID()) as AtlasAsset;
|
|
|
+ skeletonDataAtlasAssets[i] = EditorUtility.InstanceIDToObject(skeletonDataAtlasAssets[i].GetInstanceID()) as AtlasAsset;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- SkeletonData skeletonData = skeletonDataAsset.GetSkeletonData(true);
|
|
|
- string currentHash = skeletonData != null ? skeletonData.Hash : null;
|
|
|
- if (currentHash == null || lastHash != currentHash) {
|
|
|
- //do any upkeep on synchronized assets
|
|
|
- UpdateMecanimClips(skeletonDataAsset);
|
|
|
- }
|
|
|
+ SkeletonData skeletonData = skeletonDataAsset.GetSkeletonData(true);
|
|
|
+ string currentHash = skeletonData != null ? skeletonData.Hash : null;
|
|
|
+ if (currentHash == null || lastHash != currentHash) {
|
|
|
+ //do any upkeep on synchronized assets
|
|
|
+ UpdateMecanimClips(skeletonDataAsset);
|
|
|
+ }
|
|
|
|
|
|
- if (currentHash != null) {
|
|
|
- EditorPrefs.SetString(guid + "_hash", currentHash);
|
|
|
+ if (currentHash != null) {
|
|
|
+ EditorPrefs.SetString(guid + "_hash", currentHash);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- static void UpdateMecanimClips (SkeletonDataAsset skeletonDataAsset) {
|
|
|
- if (skeletonDataAsset.controller == null)
|
|
|
- return;
|
|
|
-
|
|
|
- SkeletonBaker.GenerateMecanimAnimationClips(skeletonDataAsset);
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- static bool CheckForValidAtlas (string atlasPath) {
|
|
|
- return false;
|
|
|
- //////////////DEPRECATED - always check for new atlas data now
|
|
|
- /*
|
|
|
+ static bool CheckForValidAtlas (string atlasPath) {
|
|
|
+ return false;
|
|
|
+ //////////////DEPRECATED - always check for new atlas data now
|
|
|
+ /*
|
|
|
string dir = Path.GetDirectoryName(atlasPath);
|
|
|
TextAsset textAsset = (TextAsset)AssetDatabase.LoadAssetAtPath(atlasPath, typeof(TextAsset));
|
|
|
DirectoryInfo dirInfo = new DirectoryInfo(dir);
|
|
@@ -523,51 +520,51 @@ public class SpineEditorUtilities : AssetPostprocessor {
|
|
|
return false;
|
|
|
|
|
|
*/
|
|
|
- }
|
|
|
+ }
|
|
|
|
|
|
- static List<AtlasAsset> MultiAtlasDialog (List<string> requiredPaths, string initialDirectory, string header = "") {
|
|
|
+ static List<AtlasAsset> MultiAtlasDialog (List<string> requiredPaths, string initialDirectory, string header = "") {
|
|
|
|
|
|
- List<AtlasAsset> atlasAssets = new List<AtlasAsset>();
|
|
|
+ List<AtlasAsset> atlasAssets = new List<AtlasAsset>();
|
|
|
|
|
|
- bool resolved = false;
|
|
|
- string lastAtlasPath = initialDirectory;
|
|
|
- while (!resolved) {
|
|
|
- StringBuilder sb = new StringBuilder();
|
|
|
- sb.AppendLine(header);
|
|
|
- sb.AppendLine("Atlases:");
|
|
|
- if (atlasAssets.Count == 0) {
|
|
|
- sb.AppendLine("\t--none--");
|
|
|
- }
|
|
|
- for (int i = 0; i < atlasAssets.Count; i++) {
|
|
|
- sb.AppendLine("\t" + atlasAssets[i].name);
|
|
|
- }
|
|
|
+ bool resolved = false;
|
|
|
+ string lastAtlasPath = initialDirectory;
|
|
|
+ while (!resolved) {
|
|
|
+ StringBuilder sb = new StringBuilder();
|
|
|
+ sb.AppendLine(header);
|
|
|
+ sb.AppendLine("Atlases:");
|
|
|
+ if (atlasAssets.Count == 0) {
|
|
|
+ sb.AppendLine("\t--none--");
|
|
|
+ }
|
|
|
+ for (int i = 0; i < atlasAssets.Count; i++) {
|
|
|
+ sb.AppendLine("\t" + atlasAssets[i].name);
|
|
|
+ }
|
|
|
|
|
|
- sb.AppendLine();
|
|
|
- sb.AppendLine("Missing Regions:");
|
|
|
+ sb.AppendLine();
|
|
|
+ sb.AppendLine("Missing Regions:");
|
|
|
|
|
|
- List<string> missingRegions = new List<string>(requiredPaths);
|
|
|
+ List<string> missingRegions = new List<string>(requiredPaths);
|
|
|
|
|
|
- foreach (var atlasAsset in atlasAssets) {
|
|
|
- var atlas = atlasAsset.GetAtlas();
|
|
|
- for (int i = 0; i < missingRegions.Count; i++) {
|
|
|
- if (atlas.FindRegion(missingRegions[i]) != null) {
|
|
|
- missingRegions.RemoveAt(i);
|
|
|
- i--;
|
|
|
+ foreach (var atlasAsset in atlasAssets) {
|
|
|
+ var atlas = atlasAsset.GetAtlas();
|
|
|
+ for (int i = 0; i < missingRegions.Count; i++) {
|
|
|
+ if (atlas.FindRegion(missingRegions[i]) != null) {
|
|
|
+ missingRegions.RemoveAt(i);
|
|
|
+ i--;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- if (missingRegions.Count == 0) {
|
|
|
- break;
|
|
|
- }
|
|
|
+ if (missingRegions.Count == 0) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
|
|
|
- for (int i = 0; i < missingRegions.Count; i++) {
|
|
|
- sb.AppendLine("\t" + missingRegions[i]);
|
|
|
- }
|
|
|
+ for (int i = 0; i < missingRegions.Count; i++) {
|
|
|
+ sb.AppendLine("\t" + missingRegions[i]);
|
|
|
+ }
|
|
|
|
|
|
- int result = EditorUtility.DisplayDialogComplex("Atlas Selection", sb.ToString(), "Select", "Finish", "Abort");
|
|
|
+ int result = EditorUtility.DisplayDialogComplex("Atlas Selection", sb.ToString(), "Select", "Finish", "Abort");
|
|
|
|
|
|
- switch (result) {
|
|
|
+ switch (result) {
|
|
|
case 0:
|
|
|
AtlasAsset selectedAtlasAsset = GetAtlasDialog(lastAtlasPath);
|
|
|
if (selectedAtlasAsset != null) {
|
|
@@ -592,618 +589,635 @@ public class SpineEditorUtilities : AssetPostprocessor {
|
|
|
atlasAssets = null;
|
|
|
resolved = true;
|
|
|
break;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
}
|
|
|
|
|
|
|
|
|
+ return atlasAssets;
|
|
|
}
|
|
|
|
|
|
+ static AtlasAsset GetAtlasDialog (string dirPath) {
|
|
|
+ string path = EditorUtility.OpenFilePanel("Select AtlasAsset...", dirPath, "asset");
|
|
|
+ if (path == "")
|
|
|
+ return null;
|
|
|
|
|
|
- return atlasAssets;
|
|
|
- }
|
|
|
+ int subLen = Application.dataPath.Length - 6;
|
|
|
+ string assetRelativePath = path.Substring(subLen, path.Length - subLen).Replace("\\", "/");
|
|
|
|
|
|
- static AtlasAsset GetAtlasDialog (string dirPath) {
|
|
|
- string path = EditorUtility.OpenFilePanel("Select AtlasAsset...", dirPath, "asset");
|
|
|
- if (path == "")
|
|
|
- return null;
|
|
|
+ Object obj = AssetDatabase.LoadAssetAtPath(assetRelativePath, typeof(AtlasAsset));
|
|
|
|
|
|
- int subLen = Application.dataPath.Length - 6;
|
|
|
- string assetRelativePath = path.Substring(subLen, path.Length - subLen).Replace("\\", "/");
|
|
|
+ if (obj == null || obj.GetType() != typeof(AtlasAsset))
|
|
|
+ return null;
|
|
|
|
|
|
- Object obj = AssetDatabase.LoadAssetAtPath(assetRelativePath, typeof(AtlasAsset));
|
|
|
+ return (AtlasAsset)obj;
|
|
|
+ }
|
|
|
|
|
|
- if (obj == null || obj.GetType() != typeof(AtlasAsset))
|
|
|
- return null;
|
|
|
+ static void AddRequiredAtlasRegionsFromBinary (string skeletonDataPath, List<string> requiredPaths) {
|
|
|
+ SkeletonBinary binary = new SkeletonBinary(new AtlasRequirementLoader(requiredPaths));
|
|
|
+ TextAsset data = (TextAsset)AssetDatabase.LoadAssetAtPath(skeletonDataPath, typeof(TextAsset));
|
|
|
+ MemoryStream input = new MemoryStream(data.bytes);
|
|
|
+ binary.ReadSkeletonData(input);
|
|
|
+ binary = null;
|
|
|
+ }
|
|
|
|
|
|
- return (AtlasAsset)obj;
|
|
|
- }
|
|
|
+ public static List<string> GetRequiredAtlasRegions (string skeletonDataPath) {
|
|
|
+ List<string> requiredPaths = new List<string>();
|
|
|
|
|
|
- static void AddRequiredAtlasRegionsFromBinary (string skeletonDataPath, List<string> requiredPaths) {
|
|
|
- SkeletonBinary binary = new SkeletonBinary(new AtlasRequirementLoader(requiredPaths));
|
|
|
- TextAsset data = (TextAsset)AssetDatabase.LoadAssetAtPath(skeletonDataPath, typeof(TextAsset));
|
|
|
- MemoryStream input = new MemoryStream(data.bytes);
|
|
|
- binary.ReadSkeletonData(input);
|
|
|
- binary = null;
|
|
|
- }
|
|
|
-
|
|
|
- public static List<string> GetRequiredAtlasRegions (string skeletonDataPath) {
|
|
|
- List<string> requiredPaths = new List<string>();
|
|
|
+ if (skeletonDataPath.Contains(".skel")) {
|
|
|
+ AddRequiredAtlasRegionsFromBinary(skeletonDataPath, requiredPaths);
|
|
|
+ return requiredPaths;
|
|
|
+ }
|
|
|
|
|
|
- if (skeletonDataPath.Contains(".skel")) {
|
|
|
- AddRequiredAtlasRegionsFromBinary(skeletonDataPath, requiredPaths);
|
|
|
- return requiredPaths;
|
|
|
- }
|
|
|
+ TextAsset spineJson = (TextAsset)AssetDatabase.LoadAssetAtPath(skeletonDataPath, typeof(TextAsset));
|
|
|
|
|
|
- TextAsset spineJson = (TextAsset)AssetDatabase.LoadAssetAtPath(skeletonDataPath, typeof(TextAsset));
|
|
|
+ StringReader reader = new StringReader(spineJson.text);
|
|
|
+ var root = Json.Deserialize(reader) as Dictionary<string, object>;
|
|
|
|
|
|
- StringReader reader = new StringReader(spineJson.text);
|
|
|
- var root = Json.Deserialize(reader) as Dictionary<string, object>;
|
|
|
+ foreach (KeyValuePair<string, object> entry in (Dictionary<string, object>)root["skins"]) {
|
|
|
+ foreach (KeyValuePair<string, object> slotEntry in (Dictionary<string, object>)entry.Value) {
|
|
|
|
|
|
- foreach (KeyValuePair<string, object> entry in (Dictionary<string, object>)root["skins"]) {
|
|
|
- foreach (KeyValuePair<string, object> slotEntry in (Dictionary<string, object>)entry.Value) {
|
|
|
+ foreach (KeyValuePair<string, object> attachmentEntry in ((Dictionary<string, object>)slotEntry.Value)) {
|
|
|
+ var data = ((Dictionary<string, object>)attachmentEntry.Value);
|
|
|
+ if (data.ContainsKey("type")) {
|
|
|
+ if ((string)data["type"] == "boundingbox") {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
|
|
|
- foreach (KeyValuePair<string, object> attachmentEntry in ((Dictionary<string, object>)slotEntry.Value)) {
|
|
|
- var data = ((Dictionary<string, object>)attachmentEntry.Value);
|
|
|
- if (data.ContainsKey("type")) {
|
|
|
- if ((string)data["type"] == "boundingbox") {
|
|
|
- continue;
|
|
|
}
|
|
|
-
|
|
|
+ if (data.ContainsKey("path"))
|
|
|
+ requiredPaths.Add((string)data["path"]);
|
|
|
+ else if (data.ContainsKey("name"))
|
|
|
+ requiredPaths.Add((string)data["name"]);
|
|
|
+ else
|
|
|
+ requiredPaths.Add(attachmentEntry.Key);
|
|
|
+ //requiredPaths.Add((string)sdf["path"]);
|
|
|
}
|
|
|
- if (data.ContainsKey("path"))
|
|
|
- requiredPaths.Add((string)data["path"]);
|
|
|
- else if (data.ContainsKey("name"))
|
|
|
- requiredPaths.Add((string)data["name"]);
|
|
|
- else
|
|
|
- requiredPaths.Add(attachmentEntry.Key);
|
|
|
- //requiredPaths.Add((string)sdf["path"]);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ return requiredPaths;
|
|
|
}
|
|
|
+ static AtlasAsset GetMatchingAtlas (List<string> requiredPaths, List<AtlasAsset> atlasAssets) {
|
|
|
+ AtlasAsset atlasAssetMatch = null;
|
|
|
+
|
|
|
+ foreach (AtlasAsset a in atlasAssets) {
|
|
|
+ Atlas atlas = a.GetAtlas();
|
|
|
+ bool failed = false;
|
|
|
+ foreach (string regionPath in requiredPaths) {
|
|
|
+ if (atlas.FindRegion(regionPath) == null) {
|
|
|
+ failed = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- return requiredPaths;
|
|
|
- }
|
|
|
- static AtlasAsset GetMatchingAtlas (List<string> requiredPaths, List<AtlasAsset> atlasAssets) {
|
|
|
- AtlasAsset atlasAssetMatch = null;
|
|
|
-
|
|
|
- foreach (AtlasAsset a in atlasAssets) {
|
|
|
- Atlas atlas = a.GetAtlas();
|
|
|
- bool failed = false;
|
|
|
- foreach (string regionPath in requiredPaths) {
|
|
|
- if (atlas.FindRegion(regionPath) == null) {
|
|
|
- failed = true;
|
|
|
+ if (!failed) {
|
|
|
+ atlasAssetMatch = a;
|
|
|
break;
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- if (!failed) {
|
|
|
- atlasAssetMatch = a;
|
|
|
- break;
|
|
|
}
|
|
|
|
|
|
+ return atlasAssetMatch;
|
|
|
}
|
|
|
|
|
|
- return atlasAssetMatch;
|
|
|
- }
|
|
|
+ static List<AtlasAsset> FindAtlasesAtPath (string path) {
|
|
|
+ List<AtlasAsset> arr = new List<AtlasAsset>();
|
|
|
|
|
|
- static List<AtlasAsset> FindAtlasesAtPath (string path) {
|
|
|
- List<AtlasAsset> arr = new List<AtlasAsset>();
|
|
|
+ DirectoryInfo dir = new DirectoryInfo(path);
|
|
|
+ FileInfo[] assetInfoArr = dir.GetFiles("*.asset");
|
|
|
|
|
|
- DirectoryInfo dir = new DirectoryInfo(path);
|
|
|
- FileInfo[] assetInfoArr = dir.GetFiles("*.asset");
|
|
|
+ int subLen = Application.dataPath.Length - 6;
|
|
|
|
|
|
- int subLen = Application.dataPath.Length - 6;
|
|
|
+ foreach (var f in assetInfoArr) {
|
|
|
+ string assetRelativePath = f.FullName.Substring(subLen, f.FullName.Length - subLen).Replace("\\", "/");
|
|
|
|
|
|
- foreach (var f in assetInfoArr) {
|
|
|
- string assetRelativePath = f.FullName.Substring(subLen, f.FullName.Length - subLen).Replace("\\", "/");
|
|
|
+ Object obj = AssetDatabase.LoadAssetAtPath(assetRelativePath, typeof(AtlasAsset));
|
|
|
+ if (obj != null) {
|
|
|
+ arr.Add(obj as AtlasAsset);
|
|
|
+ }
|
|
|
|
|
|
- Object obj = AssetDatabase.LoadAssetAtPath(assetRelativePath, typeof(AtlasAsset));
|
|
|
- if (obj != null) {
|
|
|
- arr.Add(obj as AtlasAsset);
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ return arr;
|
|
|
}
|
|
|
|
|
|
+ public static bool IsValidSpineData (TextAsset asset) {
|
|
|
+ if (asset.name.Contains(".skel")) return true;
|
|
|
|
|
|
- return arr;
|
|
|
- }
|
|
|
+ object obj = null;
|
|
|
+ try {
|
|
|
+ obj = Json.Deserialize(new StringReader(asset.text));
|
|
|
+ } catch (System.Exception) {
|
|
|
+ }
|
|
|
+ if (obj == null) {
|
|
|
+ Debug.LogError("Is not valid JSON");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
|
|
|
- public static bool IsValidSpineData (TextAsset asset) {
|
|
|
- if (asset.name.Contains(".skel")) return true;
|
|
|
+ Dictionary<string, object> root = (Dictionary<string, object>)obj;
|
|
|
|
|
|
- object obj = null;
|
|
|
- try {
|
|
|
- obj = Json.Deserialize(new StringReader(asset.text));
|
|
|
- } catch (System.Exception) {
|
|
|
- }
|
|
|
- if (obj == null) {
|
|
|
- Debug.LogError("Is not valid JSON");
|
|
|
- return false;
|
|
|
- }
|
|
|
+ if (!root.ContainsKey("skeleton"))
|
|
|
+ return false;
|
|
|
|
|
|
- Dictionary<string, object> root = (Dictionary<string, object>)obj;
|
|
|
+ Dictionary<string, object> skeletonInfo = (Dictionary<string, object>)root["skeleton"];
|
|
|
|
|
|
- if (!root.ContainsKey("skeleton"))
|
|
|
- return false;
|
|
|
+ string spineVersion = (string)skeletonInfo["spine"];
|
|
|
+ //TODO: reject old versions
|
|
|
|
|
|
- Dictionary<string, object> skeletonInfo = (Dictionary<string, object>)root["skeleton"];
|
|
|
+ return true;
|
|
|
+ }
|
|
|
|
|
|
- string spineVersion = (string)skeletonInfo["spine"];
|
|
|
- //TODO: reject old versions
|
|
|
+ static AtlasAsset IngestSpineAtlas (TextAsset atlasText) {
|
|
|
+ if (atlasText == null) {
|
|
|
+ Debug.LogWarning("Atlas source cannot be null!");
|
|
|
+ return null;
|
|
|
+ }
|
|
|
|
|
|
- return true;
|
|
|
- }
|
|
|
+ string primaryName = Path.GetFileNameWithoutExtension(atlasText.name).Replace(".atlas", "");
|
|
|
+ string assetPath = Path.GetDirectoryName(AssetDatabase.GetAssetPath(atlasText));
|
|
|
|
|
|
- static AtlasAsset IngestSpineAtlas (TextAsset atlasText) {
|
|
|
- if (atlasText == null) {
|
|
|
- Debug.LogWarning("Atlas source cannot be null!");
|
|
|
- return null;
|
|
|
- }
|
|
|
+ string atlasPath = assetPath + "/" + primaryName + "_Atlas.asset";
|
|
|
|
|
|
- string primaryName = Path.GetFileNameWithoutExtension(atlasText.name).Replace(".atlas", "");
|
|
|
- string assetPath = Path.GetDirectoryName(AssetDatabase.GetAssetPath(atlasText));
|
|
|
+ AtlasAsset atlasAsset = (AtlasAsset)AssetDatabase.LoadAssetAtPath(atlasPath, typeof(AtlasAsset));
|
|
|
|
|
|
- string atlasPath = assetPath + "/" + primaryName + "_Atlas.asset";
|
|
|
+ List<Material> vestigialMaterials = new List<Material>();
|
|
|
|
|
|
- AtlasAsset atlasAsset = (AtlasAsset)AssetDatabase.LoadAssetAtPath(atlasPath, typeof(AtlasAsset));
|
|
|
+ if (atlasAsset == null)
|
|
|
+ atlasAsset = AtlasAsset.CreateInstance<AtlasAsset>();
|
|
|
+ else {
|
|
|
+ foreach (Material m in atlasAsset.materials)
|
|
|
+ vestigialMaterials.Add(m);
|
|
|
+ }
|
|
|
|
|
|
- List<Material> vestigialMaterials = new List<Material>();
|
|
|
+ atlasAsset.atlasFile = atlasText;
|
|
|
|
|
|
- if (atlasAsset == null)
|
|
|
- atlasAsset = AtlasAsset.CreateInstance<AtlasAsset>();
|
|
|
- else {
|
|
|
- foreach (Material m in atlasAsset.materials)
|
|
|
- vestigialMaterials.Add(m);
|
|
|
- }
|
|
|
+ //strip CR
|
|
|
+ string atlasStr = atlasText.text;
|
|
|
+ atlasStr = atlasStr.Replace("\r", "");
|
|
|
|
|
|
- atlasAsset.atlasFile = atlasText;
|
|
|
+ string[] atlasLines = atlasStr.Split('\n');
|
|
|
+ List<string> pageFiles = new List<string>();
|
|
|
+ for (int i = 0; i < atlasLines.Length - 1; i++) {
|
|
|
+ if (atlasLines[i].Trim().Length == 0)
|
|
|
+ pageFiles.Add(atlasLines[i + 1].Trim());
|
|
|
+ }
|
|
|
|
|
|
- //strip CR
|
|
|
- string atlasStr = atlasText.text;
|
|
|
- atlasStr = atlasStr.Replace("\r", "");
|
|
|
+ atlasAsset.materials = new Material[pageFiles.Count];
|
|
|
|
|
|
- string[] atlasLines = atlasStr.Split('\n');
|
|
|
- List<string> pageFiles = new List<string>();
|
|
|
- for (int i = 0; i < atlasLines.Length - 1; i++) {
|
|
|
- if (atlasLines[i].Trim().Length == 0)
|
|
|
- pageFiles.Add(atlasLines[i + 1].Trim());
|
|
|
- }
|
|
|
+ for (int i = 0; i < pageFiles.Count; i++) {
|
|
|
+ string texturePath = assetPath + "/" + pageFiles[i];
|
|
|
+ Texture2D texture = (Texture2D)AssetDatabase.LoadAssetAtPath(texturePath, typeof(Texture2D));
|
|
|
|
|
|
- atlasAsset.materials = new Material[pageFiles.Count];
|
|
|
+ TextureImporter texImporter = (TextureImporter)TextureImporter.GetAtPath(texturePath);
|
|
|
+ texImporter.textureType = TextureImporterType.Advanced;
|
|
|
+ texImporter.textureFormat = TextureImporterFormat.AutomaticTruecolor;
|
|
|
+ texImporter.mipmapEnabled = false;
|
|
|
+ texImporter.alphaIsTransparency = false;
|
|
|
+ texImporter.maxTextureSize = 2048;
|
|
|
|
|
|
- for (int i = 0; i < pageFiles.Count; i++) {
|
|
|
- string texturePath = assetPath + "/" + pageFiles[i];
|
|
|
- Texture2D texture = (Texture2D)AssetDatabase.LoadAssetAtPath(texturePath, typeof(Texture2D));
|
|
|
+ EditorUtility.SetDirty(texImporter);
|
|
|
+ AssetDatabase.ImportAsset(texturePath);
|
|
|
+ AssetDatabase.SaveAssets();
|
|
|
|
|
|
- TextureImporter texImporter = (TextureImporter)TextureImporter.GetAtPath(texturePath);
|
|
|
- texImporter.textureType = TextureImporterType.Advanced;
|
|
|
- texImporter.textureFormat = TextureImporterFormat.AutomaticTruecolor;
|
|
|
- texImporter.mipmapEnabled = false;
|
|
|
- texImporter.alphaIsTransparency = false;
|
|
|
- texImporter.maxTextureSize = 2048;
|
|
|
+ string pageName = Path.GetFileNameWithoutExtension(pageFiles[i]);
|
|
|
|
|
|
- EditorUtility.SetDirty(texImporter);
|
|
|
- AssetDatabase.ImportAsset(texturePath);
|
|
|
- AssetDatabase.SaveAssets();
|
|
|
+ //because this looks silly
|
|
|
+ if (pageName == primaryName && pageFiles.Count == 1)
|
|
|
+ pageName = "Material";
|
|
|
+
|
|
|
+ string materialPath = assetPath + "/" + primaryName + "_" + pageName + ".mat";
|
|
|
+ Material mat = (Material)AssetDatabase.LoadAssetAtPath(materialPath, typeof(Material));
|
|
|
|
|
|
- string pageName = Path.GetFileNameWithoutExtension(pageFiles[i]);
|
|
|
+ if (mat == null) {
|
|
|
+ mat = new Material(Shader.Find(defaultShader));
|
|
|
+ AssetDatabase.CreateAsset(mat, materialPath);
|
|
|
+ } else {
|
|
|
+ vestigialMaterials.Remove(mat);
|
|
|
+ }
|
|
|
|
|
|
- //because this looks silly
|
|
|
- if (pageName == primaryName && pageFiles.Count == 1)
|
|
|
- pageName = "Material";
|
|
|
+ mat.mainTexture = texture;
|
|
|
+ EditorUtility.SetDirty(mat);
|
|
|
|
|
|
- string materialPath = assetPath + "/" + primaryName + "_" + pageName + ".mat";
|
|
|
- Material mat = (Material)AssetDatabase.LoadAssetAtPath(materialPath, typeof(Material));
|
|
|
+ AssetDatabase.SaveAssets();
|
|
|
|
|
|
- if (mat == null) {
|
|
|
- mat = new Material(Shader.Find(defaultShader));
|
|
|
- AssetDatabase.CreateAsset(mat, materialPath);
|
|
|
- } else {
|
|
|
- vestigialMaterials.Remove(mat);
|
|
|
+ atlasAsset.materials[i] = mat;
|
|
|
}
|
|
|
|
|
|
- mat.mainTexture = texture;
|
|
|
- EditorUtility.SetDirty(mat);
|
|
|
+ for (int i = 0; i < vestigialMaterials.Count; i++)
|
|
|
+ AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(vestigialMaterials[i]));
|
|
|
+
|
|
|
+ if (AssetDatabase.GetAssetPath(atlasAsset) == "")
|
|
|
+ AssetDatabase.CreateAsset(atlasAsset, atlasPath);
|
|
|
+ else
|
|
|
+ atlasAsset.Reset();
|
|
|
+
|
|
|
+ EditorUtility.SetDirty(atlasAsset);
|
|
|
|
|
|
AssetDatabase.SaveAssets();
|
|
|
|
|
|
- atlasAsset.materials[i] = mat;
|
|
|
- }
|
|
|
|
|
|
- for (int i = 0; i < vestigialMaterials.Count; i++)
|
|
|
- AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(vestigialMaterials[i]));
|
|
|
+ //iterate regions and bake marked
|
|
|
+ Atlas atlas = atlasAsset.GetAtlas();
|
|
|
+ FieldInfo field = typeof(Atlas).GetField("regions", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.NonPublic);
|
|
|
+ List<AtlasRegion> regions = (List<AtlasRegion>)field.GetValue(atlas);
|
|
|
+ string atlasAssetPath = AssetDatabase.GetAssetPath(atlasAsset);
|
|
|
+ string atlasAssetDirPath = Path.GetDirectoryName(atlasAssetPath);
|
|
|
+ string bakedDirPath = Path.Combine(atlasAssetDirPath, atlasAsset.name);
|
|
|
|
|
|
- if (AssetDatabase.GetAssetPath(atlasAsset) == "")
|
|
|
- AssetDatabase.CreateAsset(atlasAsset, atlasPath);
|
|
|
- else
|
|
|
- atlasAsset.Reset();
|
|
|
+ bool hasBakedRegions = false;
|
|
|
+ for (int i = 0; i < regions.Count; i++) {
|
|
|
+ AtlasRegion region = regions[i];
|
|
|
+ string bakedPrefabPath = Path.Combine(bakedDirPath, SpineEditorUtilities.GetPathSafeRegionName(region) + ".prefab").Replace("\\", "/");
|
|
|
+ GameObject prefab = (GameObject)AssetDatabase.LoadAssetAtPath(bakedPrefabPath, typeof(GameObject));
|
|
|
|
|
|
- EditorUtility.SetDirty(atlasAsset);
|
|
|
+ if (prefab != null) {
|
|
|
+ BakeRegion(atlasAsset, region, false);
|
|
|
+ hasBakedRegions = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- AssetDatabase.SaveAssets();
|
|
|
+ if (hasBakedRegions) {
|
|
|
+ AssetDatabase.SaveAssets();
|
|
|
+ AssetDatabase.Refresh();
|
|
|
+ }
|
|
|
|
|
|
+ return (AtlasAsset)AssetDatabase.LoadAssetAtPath(atlasPath, typeof(AtlasAsset));
|
|
|
+ }
|
|
|
|
|
|
- //iterate regions and bake marked
|
|
|
- Atlas atlas = atlasAsset.GetAtlas();
|
|
|
- FieldInfo field = typeof(Atlas).GetField("regions", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.NonPublic);
|
|
|
- List<AtlasRegion> regions = (List<AtlasRegion>)field.GetValue(atlas);
|
|
|
- string atlasAssetPath = AssetDatabase.GetAssetPath(atlasAsset);
|
|
|
- string atlasAssetDirPath = Path.GetDirectoryName(atlasAssetPath);
|
|
|
- string bakedDirPath = Path.Combine(atlasAssetDirPath, atlasAsset.name);
|
|
|
+ public static GameObject BakeRegion (AtlasAsset atlasAsset, AtlasRegion region, bool autoSave = true) {
|
|
|
+ Atlas atlas = atlasAsset.GetAtlas();
|
|
|
+ string atlasAssetPath = AssetDatabase.GetAssetPath(atlasAsset);
|
|
|
+ string atlasAssetDirPath = Path.GetDirectoryName(atlasAssetPath);
|
|
|
+ string bakedDirPath = Path.Combine(atlasAssetDirPath, atlasAsset.name);
|
|
|
+ string bakedPrefabPath = Path.Combine(bakedDirPath, GetPathSafeRegionName(region) + ".prefab").Replace("\\", "/");
|
|
|
|
|
|
- bool hasBakedRegions = false;
|
|
|
- for (int i = 0; i < regions.Count; i++) {
|
|
|
- AtlasRegion region = regions[i];
|
|
|
- string bakedPrefabPath = Path.Combine(bakedDirPath, SpineEditorUtilities.GetPathSafeRegionName(region) + ".prefab").Replace("\\", "/");
|
|
|
GameObject prefab = (GameObject)AssetDatabase.LoadAssetAtPath(bakedPrefabPath, typeof(GameObject));
|
|
|
-
|
|
|
- if (prefab != null) {
|
|
|
- BakeRegion(atlasAsset, region, false);
|
|
|
- hasBakedRegions = true;
|
|
|
+ GameObject root;
|
|
|
+ Mesh mesh;
|
|
|
+ bool isNewPrefab = false;
|
|
|
+
|
|
|
+ if (!Directory.Exists(bakedDirPath))
|
|
|
+ Directory.CreateDirectory(bakedDirPath);
|
|
|
+
|
|
|
+ if (prefab == null) {
|
|
|
+ root = new GameObject("temp", typeof(MeshFilter), typeof(MeshRenderer));
|
|
|
+ prefab = (GameObject)PrefabUtility.CreatePrefab(bakedPrefabPath, root);
|
|
|
+ isNewPrefab = true;
|
|
|
+ Object.DestroyImmediate(root);
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- if (hasBakedRegions) {
|
|
|
- AssetDatabase.SaveAssets();
|
|
|
- AssetDatabase.Refresh();
|
|
|
- }
|
|
|
+ mesh = (Mesh)AssetDatabase.LoadAssetAtPath(bakedPrefabPath, typeof(Mesh));
|
|
|
|
|
|
- return (AtlasAsset)AssetDatabase.LoadAssetAtPath(atlasPath, typeof(AtlasAsset));
|
|
|
- }
|
|
|
+ Material mat = null;
|
|
|
+ mesh = atlasAsset.GenerateMesh(region.name, mesh, out mat);
|
|
|
+ if (isNewPrefab) {
|
|
|
+ AssetDatabase.AddObjectToAsset(mesh, prefab);
|
|
|
+ prefab.GetComponent<MeshFilter>().sharedMesh = mesh;
|
|
|
+ }
|
|
|
|
|
|
- public static GameObject BakeRegion (AtlasAsset atlasAsset, AtlasRegion region, bool autoSave = true) {
|
|
|
- Atlas atlas = atlasAsset.GetAtlas();
|
|
|
- string atlasAssetPath = AssetDatabase.GetAssetPath(atlasAsset);
|
|
|
- string atlasAssetDirPath = Path.GetDirectoryName(atlasAssetPath);
|
|
|
- string bakedDirPath = Path.Combine(atlasAssetDirPath, atlasAsset.name);
|
|
|
- string bakedPrefabPath = Path.Combine(bakedDirPath, GetPathSafeRegionName(region) + ".prefab").Replace("\\", "/");
|
|
|
-
|
|
|
- GameObject prefab = (GameObject)AssetDatabase.LoadAssetAtPath(bakedPrefabPath, typeof(GameObject));
|
|
|
- GameObject root;
|
|
|
- Mesh mesh;
|
|
|
- bool isNewPrefab = false;
|
|
|
-
|
|
|
- if (!Directory.Exists(bakedDirPath))
|
|
|
- Directory.CreateDirectory(bakedDirPath);
|
|
|
-
|
|
|
- if (prefab == null) {
|
|
|
- root = new GameObject("temp", typeof(MeshFilter), typeof(MeshRenderer));
|
|
|
- prefab = (GameObject)PrefabUtility.CreatePrefab(bakedPrefabPath, root);
|
|
|
- isNewPrefab = true;
|
|
|
- Object.DestroyImmediate(root);
|
|
|
- }
|
|
|
+ EditorUtility.SetDirty(mesh);
|
|
|
+ EditorUtility.SetDirty(prefab);
|
|
|
|
|
|
- mesh = (Mesh)AssetDatabase.LoadAssetAtPath(bakedPrefabPath, typeof(Mesh));
|
|
|
+ if (autoSave) {
|
|
|
+ AssetDatabase.SaveAssets();
|
|
|
+ AssetDatabase.Refresh();
|
|
|
+ }
|
|
|
|
|
|
- Material mat = null;
|
|
|
- mesh = atlasAsset.GenerateMesh(region.name, mesh, out mat);
|
|
|
- if (isNewPrefab) {
|
|
|
- AssetDatabase.AddObjectToAsset(mesh, prefab);
|
|
|
- prefab.GetComponent<MeshFilter>().sharedMesh = mesh;
|
|
|
- }
|
|
|
|
|
|
- EditorUtility.SetDirty(mesh);
|
|
|
- EditorUtility.SetDirty(prefab);
|
|
|
+ prefab.GetComponent<MeshRenderer>().sharedMaterial = mat;
|
|
|
|
|
|
- if (autoSave) {
|
|
|
- AssetDatabase.SaveAssets();
|
|
|
- AssetDatabase.Refresh();
|
|
|
+ return prefab;
|
|
|
}
|
|
|
|
|
|
+ public static string GetPathSafeRegionName (AtlasRegion region) {
|
|
|
+ return region.name.Replace("/", "_");
|
|
|
+ }
|
|
|
|
|
|
- prefab.GetComponent<MeshRenderer>().sharedMaterial = mat;
|
|
|
-
|
|
|
- return prefab;
|
|
|
- }
|
|
|
-
|
|
|
- public static string GetPathSafeRegionName (AtlasRegion region) {
|
|
|
- return region.name.Replace("/", "_");
|
|
|
- }
|
|
|
+ static SkeletonDataAsset IngestSpineProject (TextAsset spineJson, params AtlasAsset[] atlasAssets) {
|
|
|
+ string primaryName = Path.GetFileNameWithoutExtension(spineJson.name);
|
|
|
+ string assetPath = Path.GetDirectoryName(AssetDatabase.GetAssetPath(spineJson));
|
|
|
+ string filePath = assetPath + "/" + primaryName + "_SkeletonData.asset";
|
|
|
+
|
|
|
+ if (spineJson != null && atlasAssets != null) {
|
|
|
+
|
|
|
+ SkeletonDataAsset skelDataAsset = (SkeletonDataAsset)AssetDatabase.LoadAssetAtPath(filePath, typeof(SkeletonDataAsset));
|
|
|
+ if (skelDataAsset == null) {
|
|
|
+ skelDataAsset = SkeletonDataAsset.CreateInstance<SkeletonDataAsset>();
|
|
|
+ skelDataAsset.atlasAssets = atlasAssets;
|
|
|
+ skelDataAsset.skeletonJSON = spineJson;
|
|
|
+ skelDataAsset.fromAnimation = new string[0];
|
|
|
+ skelDataAsset.toAnimation = new string[0];
|
|
|
+ skelDataAsset.duration = new float[0];
|
|
|
+ skelDataAsset.defaultMix = defaultMix;
|
|
|
+ skelDataAsset.scale = defaultScale;
|
|
|
+
|
|
|
+ AssetDatabase.CreateAsset(skelDataAsset, filePath);
|
|
|
+ AssetDatabase.SaveAssets();
|
|
|
+ } else {
|
|
|
+ skelDataAsset.atlasAssets = atlasAssets;
|
|
|
+ skelDataAsset.Reset();
|
|
|
+ skelDataAsset.GetSkeletonData(true);
|
|
|
+ }
|
|
|
|
|
|
- static SkeletonDataAsset IngestSpineProject (TextAsset spineJson, params AtlasAsset[] atlasAssets) {
|
|
|
- string primaryName = Path.GetFileNameWithoutExtension(spineJson.name);
|
|
|
- string assetPath = Path.GetDirectoryName(AssetDatabase.GetAssetPath(spineJson));
|
|
|
- string filePath = assetPath + "/" + primaryName + "_SkeletonData.asset";
|
|
|
-
|
|
|
- if (spineJson != null && atlasAssets != null) {
|
|
|
-
|
|
|
- SkeletonDataAsset skelDataAsset = (SkeletonDataAsset)AssetDatabase.LoadAssetAtPath(filePath, typeof(SkeletonDataAsset));
|
|
|
- if (skelDataAsset == null) {
|
|
|
- skelDataAsset = SkeletonDataAsset.CreateInstance<SkeletonDataAsset>();
|
|
|
- skelDataAsset.atlasAssets = atlasAssets;
|
|
|
- skelDataAsset.skeletonJSON = spineJson;
|
|
|
- skelDataAsset.fromAnimation = new string[0];
|
|
|
- skelDataAsset.toAnimation = new string[0];
|
|
|
- skelDataAsset.duration = new float[0];
|
|
|
- skelDataAsset.defaultMix = defaultMix;
|
|
|
- skelDataAsset.scale = defaultScale;
|
|
|
-
|
|
|
- AssetDatabase.CreateAsset(skelDataAsset, filePath);
|
|
|
- AssetDatabase.SaveAssets();
|
|
|
+ return skelDataAsset;
|
|
|
} else {
|
|
|
- skelDataAsset.atlasAssets = atlasAssets;
|
|
|
- skelDataAsset.Reset();
|
|
|
- skelDataAsset.GetSkeletonData(true);
|
|
|
+ EditorUtility.DisplayDialog("Error!", "Must specify both Spine JSON and AtlasAsset array", "OK");
|
|
|
+ return null;
|
|
|
}
|
|
|
-
|
|
|
- return skelDataAsset;
|
|
|
- } else {
|
|
|
- EditorUtility.DisplayDialog("Error!", "Must specify both Spine JSON and AtlasAsset array", "OK");
|
|
|
- return null;
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- [MenuItem("Assets/Spine/Instantiate (SkeletonAnimation)")]
|
|
|
- static void InstantiateSkeletonAnimation () {
|
|
|
- Object[] arr = Selection.objects;
|
|
|
- foreach (Object o in arr) {
|
|
|
- string guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(o));
|
|
|
- string skinName = EditorPrefs.GetString(guid + "_lastSkin", "");
|
|
|
+ #region SkeletonAnimation Menu
|
|
|
+ [MenuItem("Assets/Spine/Instantiate (SkeletonAnimation)", false, 10)]
|
|
|
+ static void InstantiateSkeletonAnimation () {
|
|
|
+ Object[] arr = Selection.objects;
|
|
|
+ foreach (Object o in arr) {
|
|
|
+ string guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(o));
|
|
|
+ string skinName = EditorPrefs.GetString(guid + "_lastSkin", "");
|
|
|
|
|
|
- InstantiateSkeletonAnimation((SkeletonDataAsset)o, skinName);
|
|
|
- SceneView.RepaintAll();
|
|
|
+ InstantiateSkeletonAnimation((SkeletonDataAsset)o, skinName);
|
|
|
+ SceneView.RepaintAll();
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
-
|
|
|
- [MenuItem("Assets/Spine/Instantiate (SkeletonAnimation)", true)]
|
|
|
- static bool ValidateInstantiateSkeletonAnimation () {
|
|
|
- Object[] arr = Selection.objects;
|
|
|
|
|
|
- if (arr.Length == 0)
|
|
|
- return false;
|
|
|
+ [MenuItem("Assets/Spine/Instantiate (SkeletonAnimation)", true, 10)]
|
|
|
+ static bool ValidateInstantiateSkeletonAnimation () {
|
|
|
+ Object[] arr = Selection.objects;
|
|
|
|
|
|
- foreach (Object o in arr) {
|
|
|
- if (o.GetType() != typeof(SkeletonDataAsset))
|
|
|
+ if (arr.Length == 0)
|
|
|
return false;
|
|
|
- }
|
|
|
|
|
|
- return true;
|
|
|
- }
|
|
|
+ foreach (Object o in arr) {
|
|
|
+ if (o.GetType() != typeof(SkeletonDataAsset))
|
|
|
+ return false;
|
|
|
+ }
|
|
|
|
|
|
- public static SkeletonAnimation InstantiateSkeletonAnimation (SkeletonDataAsset skeletonDataAsset, string skinName) {
|
|
|
- return InstantiateSkeletonAnimation(skeletonDataAsset, skeletonDataAsset.GetSkeletonData(true).FindSkin(skinName));
|
|
|
- }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
|
|
|
- public static SkeletonAnimation InstantiateSkeletonAnimation (SkeletonDataAsset skeletonDataAsset, Skin skin = null) {
|
|
|
- string spineGameObjectName = string.Format("Spine GameObject ({0})", skeletonDataAsset.name.Replace("_SkeletonData", ""));
|
|
|
- GameObject go = new GameObject(spineGameObjectName, typeof(MeshFilter), typeof(MeshRenderer), typeof(SkeletonAnimation));
|
|
|
- SkeletonAnimation anim = go.GetComponent<SkeletonAnimation>();
|
|
|
- anim.skeletonDataAsset = skeletonDataAsset;
|
|
|
+ public static SkeletonAnimation InstantiateSkeletonAnimation (SkeletonDataAsset skeletonDataAsset, string skinName) {
|
|
|
+ return InstantiateSkeletonAnimation(skeletonDataAsset, skeletonDataAsset.GetSkeletonData(true).FindSkin(skinName));
|
|
|
+ }
|
|
|
|
|
|
- bool requiresNormals = false;
|
|
|
+ public static SkeletonAnimation InstantiateSkeletonAnimation (SkeletonDataAsset skeletonDataAsset, Skin skin = null) {
|
|
|
+ string spineGameObjectName = string.Format("Spine GameObject ({0})", skeletonDataAsset.name.Replace("_SkeletonData", ""));
|
|
|
+ GameObject go = new GameObject(spineGameObjectName, typeof(MeshFilter), typeof(MeshRenderer), typeof(SkeletonAnimation));
|
|
|
+ SkeletonAnimation anim = go.GetComponent<SkeletonAnimation>();
|
|
|
+ anim.skeletonDataAsset = skeletonDataAsset;
|
|
|
|
|
|
- foreach (AtlasAsset atlasAsset in anim.skeletonDataAsset.atlasAssets) {
|
|
|
- foreach (Material m in atlasAsset.materials) {
|
|
|
- if (m.shader.name.Contains("Lit")) {
|
|
|
- requiresNormals = true;
|
|
|
- break;
|
|
|
+ bool requiresNormals = false;
|
|
|
+
|
|
|
+ foreach (AtlasAsset atlasAsset in anim.skeletonDataAsset.atlasAssets) {
|
|
|
+ foreach (Material m in atlasAsset.materials) {
|
|
|
+ if (m.shader.name.Contains("Lit")) {
|
|
|
+ requiresNormals = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
|
|
- anim.calculateNormals = requiresNormals;
|
|
|
+ anim.calculateNormals = requiresNormals;
|
|
|
|
|
|
- SkeletonData data = skeletonDataAsset.GetSkeletonData(true);
|
|
|
+ SkeletonData data = skeletonDataAsset.GetSkeletonData(true);
|
|
|
|
|
|
- if (data == null) {
|
|
|
- for (int i = 0; i < skeletonDataAsset.atlasAssets.Length; i++) {
|
|
|
- string reloadAtlasPath = AssetDatabase.GetAssetPath(skeletonDataAsset.atlasAssets[i]);
|
|
|
- skeletonDataAsset.atlasAssets[i] = (AtlasAsset)AssetDatabase.LoadAssetAtPath(reloadAtlasPath, typeof(AtlasAsset));
|
|
|
- }
|
|
|
+ if (data == null) {
|
|
|
+ for (int i = 0; i < skeletonDataAsset.atlasAssets.Length; i++) {
|
|
|
+ string reloadAtlasPath = AssetDatabase.GetAssetPath(skeletonDataAsset.atlasAssets[i]);
|
|
|
+ skeletonDataAsset.atlasAssets[i] = (AtlasAsset)AssetDatabase.LoadAssetAtPath(reloadAtlasPath, typeof(AtlasAsset));
|
|
|
+ }
|
|
|
|
|
|
- data = skeletonDataAsset.GetSkeletonData(true);
|
|
|
- }
|
|
|
+ data = skeletonDataAsset.GetSkeletonData(true);
|
|
|
+ }
|
|
|
|
|
|
- if (skin == null)
|
|
|
- skin = data.DefaultSkin;
|
|
|
+ if (skin == null)
|
|
|
+ skin = data.DefaultSkin;
|
|
|
|
|
|
- if (skin == null)
|
|
|
- skin = data.Skins.Items[0];
|
|
|
+ if (skin == null)
|
|
|
+ skin = data.Skins.Items[0];
|
|
|
|
|
|
- anim.Initialize(false);
|
|
|
+ anim.Initialize(false);
|
|
|
|
|
|
- anim.skeleton.SetSkin(skin);
|
|
|
- anim.initialSkinName = skin.Name;
|
|
|
+ anim.skeleton.SetSkin(skin);
|
|
|
+ anim.initialSkinName = skin.Name;
|
|
|
|
|
|
- anim.skeleton.Update(1);
|
|
|
- anim.state.Update(1);
|
|
|
- anim.state.Apply(anim.skeleton);
|
|
|
- anim.skeleton.UpdateWorldTransform();
|
|
|
+ anim.skeleton.Update(1);
|
|
|
+ anim.state.Update(1);
|
|
|
+ anim.state.Apply(anim.skeleton);
|
|
|
+ anim.skeleton.UpdateWorldTransform();
|
|
|
|
|
|
- return anim;
|
|
|
- }
|
|
|
+ return anim;
|
|
|
+ }
|
|
|
+ #endregion
|
|
|
|
|
|
- [MenuItem("Assets/Spine/Instantiate (Mecanim)")]
|
|
|
- static void InstantiateSkeletonAnimator () {
|
|
|
- Object[] arr = Selection.objects;
|
|
|
- foreach (Object o in arr) {
|
|
|
- string guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(o));
|
|
|
- string skinName = EditorPrefs.GetString(guid + "_lastSkin", "");
|
|
|
+ #region SkeletonAnimator
|
|
|
+ #if SPINE_SKELETONANIMATOR
|
|
|
+ static void UpdateMecanimClips (SkeletonDataAsset skeletonDataAsset) {
|
|
|
+ if (skeletonDataAsset.controller == null)
|
|
|
+ return;
|
|
|
|
|
|
- InstantiateSkeletonAnimator((SkeletonDataAsset)o, skinName);
|
|
|
- SceneView.RepaintAll();
|
|
|
+ SkeletonBaker.GenerateMecanimAnimationClips(skeletonDataAsset);
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- [MenuItem("Assets/Spine/Instantiate (SkeletonAnimation)", true)]
|
|
|
- static bool ValidateInstantiateSkeletonAnimator () {
|
|
|
- Object[] arr = Selection.objects;
|
|
|
-
|
|
|
- if (arr.Length == 0)
|
|
|
- return false;
|
|
|
+ [MenuItem("Assets/Spine/Instantiate (Mecanim)", false, 100)]
|
|
|
+ static void InstantiateSkeletonAnimator () {
|
|
|
+ Object[] arr = Selection.objects;
|
|
|
+ foreach (Object o in arr) {
|
|
|
+ string guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(o));
|
|
|
+ string skinName = EditorPrefs.GetString(guid + "_lastSkin", "");
|
|
|
|
|
|
- foreach (Object o in arr) {
|
|
|
- if (o.GetType() != typeof(SkeletonDataAsset))
|
|
|
- return false;
|
|
|
+ InstantiateSkeletonAnimator((SkeletonDataAsset)o, skinName);
|
|
|
+ SceneView.RepaintAll();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- return true;
|
|
|
- }
|
|
|
+ [MenuItem("Assets/Spine/Instantiate (Mecanim)", true, 100)]
|
|
|
+ static bool ValidateInstantiateSkeletonAnimator () {
|
|
|
+ Object[] arr = Selection.objects;
|
|
|
|
|
|
- public static SkeletonAnimator InstantiateSkeletonAnimator (SkeletonDataAsset skeletonDataAsset, string skinName) {
|
|
|
- return InstantiateSkeletonAnimator(skeletonDataAsset, skeletonDataAsset.GetSkeletonData(true).FindSkin(skinName));
|
|
|
- }
|
|
|
+ if (arr.Length == 0)
|
|
|
+ return false;
|
|
|
|
|
|
- public static SkeletonAnimator InstantiateSkeletonAnimator (SkeletonDataAsset skeletonDataAsset, Skin skin = null) {
|
|
|
- string spineGameObjectName = string.Format("Spine Mecanim GameObject ({0})", skeletonDataAsset.name.Replace("_SkeletonData", ""));
|
|
|
- GameObject go = new GameObject(spineGameObjectName, typeof(MeshFilter), typeof(MeshRenderer), typeof(Animator), typeof(SkeletonAnimator));
|
|
|
+ foreach (Object o in arr) {
|
|
|
+ if (o.GetType() != typeof(SkeletonDataAsset))
|
|
|
+ return false;
|
|
|
+ }
|
|
|
|
|
|
- if (skeletonDataAsset.controller == null) {
|
|
|
- SkeletonBaker.GenerateMecanimAnimationClips(skeletonDataAsset);
|
|
|
+ return true;
|
|
|
}
|
|
|
|
|
|
- go.GetComponent<Animator>().runtimeAnimatorController = skeletonDataAsset.controller;
|
|
|
-
|
|
|
- SkeletonAnimator anim = go.GetComponent<SkeletonAnimator>();
|
|
|
- anim.skeletonDataAsset = skeletonDataAsset;
|
|
|
+ public static SkeletonAnimator InstantiateSkeletonAnimator (SkeletonDataAsset skeletonDataAsset, string skinName) {
|
|
|
+ return InstantiateSkeletonAnimator(skeletonDataAsset, skeletonDataAsset.GetSkeletonData(true).FindSkin(skinName));
|
|
|
+ }
|
|
|
|
|
|
- bool requiresNormals = false;
|
|
|
+ public static SkeletonAnimator InstantiateSkeletonAnimator (SkeletonDataAsset skeletonDataAsset, Skin skin = null) {
|
|
|
+ string spineGameObjectName = string.Format("Spine Mecanim GameObject ({0})", skeletonDataAsset.name.Replace("_SkeletonData", ""));
|
|
|
+ GameObject go = new GameObject(spineGameObjectName, typeof(MeshFilter), typeof(MeshRenderer), typeof(Animator), typeof(SkeletonAnimator));
|
|
|
|
|
|
- foreach (AtlasAsset atlasAsset in anim.skeletonDataAsset.atlasAssets) {
|
|
|
- foreach (Material m in atlasAsset.materials) {
|
|
|
- if (m.shader.name.Contains("Lit")) {
|
|
|
- requiresNormals = true;
|
|
|
- break;
|
|
|
- }
|
|
|
+ if (skeletonDataAsset.controller == null) {
|
|
|
+ SkeletonBaker.GenerateMecanimAnimationClips(skeletonDataAsset);
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- anim.calculateNormals = requiresNormals;
|
|
|
+ go.GetComponent<Animator>().runtimeAnimatorController = skeletonDataAsset.controller;
|
|
|
+
|
|
|
+ SkeletonAnimator anim = go.GetComponent<SkeletonAnimator>();
|
|
|
+ anim.skeletonDataAsset = skeletonDataAsset;
|
|
|
|
|
|
- SkeletonData data = skeletonDataAsset.GetSkeletonData(true);
|
|
|
+ bool requiresNormals = false;
|
|
|
|
|
|
- if (data == null) {
|
|
|
- for (int i = 0; i < skeletonDataAsset.atlasAssets.Length; i++) {
|
|
|
- string reloadAtlasPath = AssetDatabase.GetAssetPath(skeletonDataAsset.atlasAssets[i]);
|
|
|
- skeletonDataAsset.atlasAssets[i] = (AtlasAsset)AssetDatabase.LoadAssetAtPath(reloadAtlasPath, typeof(AtlasAsset));
|
|
|
+ foreach (AtlasAsset atlasAsset in anim.skeletonDataAsset.atlasAssets) {
|
|
|
+ foreach (Material m in atlasAsset.materials) {
|
|
|
+ if (m.shader.name.Contains("Lit")) {
|
|
|
+ requiresNormals = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- data = skeletonDataAsset.GetSkeletonData(true);
|
|
|
- }
|
|
|
+ anim.calculateNormals = requiresNormals;
|
|
|
+
|
|
|
+ SkeletonData data = skeletonDataAsset.GetSkeletonData(true);
|
|
|
|
|
|
- if (skin == null)
|
|
|
- skin = data.DefaultSkin;
|
|
|
+ if (data == null) {
|
|
|
+ for (int i = 0; i < skeletonDataAsset.atlasAssets.Length; i++) {
|
|
|
+ string reloadAtlasPath = AssetDatabase.GetAssetPath(skeletonDataAsset.atlasAssets[i]);
|
|
|
+ skeletonDataAsset.atlasAssets[i] = (AtlasAsset)AssetDatabase.LoadAssetAtPath(reloadAtlasPath, typeof(AtlasAsset));
|
|
|
+ }
|
|
|
|
|
|
- if (skin == null)
|
|
|
- skin = data.Skins.Items[0];
|
|
|
+ data = skeletonDataAsset.GetSkeletonData(true);
|
|
|
+ }
|
|
|
|
|
|
- anim.Initialize(false);
|
|
|
+ if (skin == null)
|
|
|
+ skin = data.DefaultSkin;
|
|
|
|
|
|
- anim.skeleton.SetSkin(skin);
|
|
|
- anim.initialSkinName = skin.Name;
|
|
|
+ if (skin == null)
|
|
|
+ skin = data.Skins.Items[0];
|
|
|
|
|
|
- anim.skeleton.Update(1);
|
|
|
- anim.skeleton.UpdateWorldTransform();
|
|
|
- anim.LateUpdate();
|
|
|
+ anim.Initialize(false);
|
|
|
|
|
|
- return anim;
|
|
|
- }
|
|
|
+ anim.skeleton.SetSkin(skin);
|
|
|
+ anim.initialSkinName = skin.Name;
|
|
|
|
|
|
- static bool preferencesLoaded = false;
|
|
|
+ anim.skeleton.Update(1);
|
|
|
+ anim.skeleton.UpdateWorldTransform();
|
|
|
+ anim.LateUpdate();
|
|
|
|
|
|
- [PreferenceItem("Spine")]
|
|
|
- static void PreferencesGUI () {
|
|
|
- if (!preferencesLoaded) {
|
|
|
- preferencesLoaded = true;
|
|
|
- defaultMix = EditorPrefs.GetFloat(DEFAULT_MIX_KEY, 0.2f);
|
|
|
+ return anim;
|
|
|
}
|
|
|
+ #endif
|
|
|
+ #endregion
|
|
|
|
|
|
+ #region Spine Preferences
|
|
|
+ static bool preferencesLoaded = false;
|
|
|
|
|
|
- EditorGUILayout.LabelField("Auto-Import Settings", EditorStyles.boldLabel);
|
|
|
- EditorGUI.BeginChangeCheck();
|
|
|
- defaultMix = EditorGUILayout.FloatField("Default Mix", defaultMix);
|
|
|
- if (EditorGUI.EndChangeCheck())
|
|
|
- EditorPrefs.SetFloat(DEFAULT_MIX_KEY, defaultMix);
|
|
|
+ [PreferenceItem("Spine")]
|
|
|
+ static void PreferencesGUI () {
|
|
|
+ if (!preferencesLoaded) {
|
|
|
+ preferencesLoaded = true;
|
|
|
+ defaultMix = EditorPrefs.GetFloat(DEFAULT_MIX_KEY, 0.2f);
|
|
|
+ }
|
|
|
|
|
|
- GUILayout.Space(20);
|
|
|
- EditorGUILayout.LabelField("3rd Party Settings", EditorStyles.boldLabel);
|
|
|
- GUILayout.BeginHorizontal();
|
|
|
- EditorGUILayout.PrefixLabel("TK2D");
|
|
|
|
|
|
- if (GUILayout.Button("Enable", GUILayout.Width(64)))
|
|
|
- EnableTK2D();
|
|
|
- if (GUILayout.Button("Disable", GUILayout.Width(64)))
|
|
|
- DisableTK2D();
|
|
|
- GUILayout.EndHorizontal();
|
|
|
- }
|
|
|
+ EditorGUILayout.LabelField("Auto-Import Settings", EditorStyles.boldLabel);
|
|
|
+ EditorGUI.BeginChangeCheck();
|
|
|
+ defaultMix = EditorGUILayout.FloatField("Default Mix", defaultMix);
|
|
|
+ if (EditorGUI.EndChangeCheck())
|
|
|
+ EditorPrefs.SetFloat(DEFAULT_MIX_KEY, defaultMix);
|
|
|
|
|
|
+ GUILayout.Space(20);
|
|
|
+ EditorGUILayout.LabelField("3rd Party Settings", EditorStyles.boldLabel);
|
|
|
+ GUILayout.BeginHorizontal();
|
|
|
+ EditorGUILayout.PrefixLabel("TK2D");
|
|
|
|
|
|
- //TK2D Support
|
|
|
- const string SPINE_TK2D_DEFINE = "SPINE_TK2D";
|
|
|
-
|
|
|
- static void EnableTK2D () {
|
|
|
- bool added = false;
|
|
|
- foreach (BuildTargetGroup group in System.Enum.GetValues(typeof(BuildTargetGroup))) {
|
|
|
- if (group == BuildTargetGroup.Unknown)
|
|
|
- continue;
|
|
|
-
|
|
|
- string defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(group);
|
|
|
- if (!defines.Contains(SPINE_TK2D_DEFINE)) {
|
|
|
- added = true;
|
|
|
- if (defines.EndsWith(";", System.StringComparison.Ordinal))
|
|
|
- defines = defines + SPINE_TK2D_DEFINE;
|
|
|
- else
|
|
|
- defines = defines + ";" + SPINE_TK2D_DEFINE;
|
|
|
-
|
|
|
- PlayerSettings.SetScriptingDefineSymbolsForGroup(group, defines);
|
|
|
- }
|
|
|
+ if (GUILayout.Button("Enable", GUILayout.Width(64)))
|
|
|
+ EnableTK2D();
|
|
|
+ if (GUILayout.Button("Disable", GUILayout.Width(64)))
|
|
|
+ DisableTK2D();
|
|
|
+ GUILayout.EndHorizontal();
|
|
|
}
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ //TK2D Support
|
|
|
+ const string SPINE_TK2D_DEFINE = "SPINE_TK2D";
|
|
|
+
|
|
|
+ static void EnableTK2D () {
|
|
|
+ bool added = false;
|
|
|
+ foreach (BuildTargetGroup group in System.Enum.GetValues(typeof(BuildTargetGroup))) {
|
|
|
+ if (group == BuildTargetGroup.Unknown)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ string defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(group);
|
|
|
+ if (!defines.Contains(SPINE_TK2D_DEFINE)) {
|
|
|
+ added = true;
|
|
|
+ if (defines.EndsWith(";", System.StringComparison.Ordinal))
|
|
|
+ defines = defines + SPINE_TK2D_DEFINE;
|
|
|
+ else
|
|
|
+ defines = defines + ";" + SPINE_TK2D_DEFINE;
|
|
|
|
|
|
- if (added) {
|
|
|
- Debug.LogWarning("Setting Scripting Define Symbol " + SPINE_TK2D_DEFINE);
|
|
|
- } else {
|
|
|
- Debug.LogWarning("Already Set Scripting Define Symbol " + SPINE_TK2D_DEFINE);
|
|
|
+ PlayerSettings.SetScriptingDefineSymbolsForGroup(group, defines);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (added) {
|
|
|
+ Debug.LogWarning("Setting Scripting Define Symbol " + SPINE_TK2D_DEFINE);
|
|
|
+ } else {
|
|
|
+ Debug.LogWarning("Already Set Scripting Define Symbol " + SPINE_TK2D_DEFINE);
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
|
|
|
- static void DisableTK2D () {
|
|
|
- bool removed = false;
|
|
|
- foreach (BuildTargetGroup group in System.Enum.GetValues(typeof(BuildTargetGroup))) {
|
|
|
- string defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(group);
|
|
|
- if (defines.Contains(SPINE_TK2D_DEFINE)) {
|
|
|
- removed = true;
|
|
|
- if (defines.Contains(SPINE_TK2D_DEFINE + ";"))
|
|
|
- defines = defines.Replace(SPINE_TK2D_DEFINE + ";", "");
|
|
|
- else
|
|
|
- defines = defines.Replace(SPINE_TK2D_DEFINE, "");
|
|
|
+ static void DisableTK2D () {
|
|
|
+ bool removed = false;
|
|
|
+ foreach (BuildTargetGroup group in System.Enum.GetValues(typeof(BuildTargetGroup))) {
|
|
|
+ string defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(group);
|
|
|
+ if (defines.Contains(SPINE_TK2D_DEFINE)) {
|
|
|
+ removed = true;
|
|
|
+ if (defines.Contains(SPINE_TK2D_DEFINE + ";"))
|
|
|
+ defines = defines.Replace(SPINE_TK2D_DEFINE + ";", "");
|
|
|
+ else
|
|
|
+ defines = defines.Replace(SPINE_TK2D_DEFINE, "");
|
|
|
|
|
|
- PlayerSettings.SetScriptingDefineSymbolsForGroup(group, defines);
|
|
|
+ PlayerSettings.SetScriptingDefineSymbolsForGroup(group, defines);
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- if (removed) {
|
|
|
- Debug.LogWarning("Removing Scripting Define Symbol " + SPINE_TK2D_DEFINE);
|
|
|
- } else {
|
|
|
- Debug.LogWarning("Already Removed Scripting Define Symbol " + SPINE_TK2D_DEFINE);
|
|
|
+ if (removed) {
|
|
|
+ Debug.LogWarning("Removing Scripting Define Symbol " + SPINE_TK2D_DEFINE);
|
|
|
+ } else {
|
|
|
+ Debug.LogWarning("Already Removed Scripting Define Symbol " + SPINE_TK2D_DEFINE);
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- public class AtlasRequirementLoader : AttachmentLoader {
|
|
|
+ public class AtlasRequirementLoader : AttachmentLoader {
|
|
|
|
|
|
- List<string> requirementList;
|
|
|
- public AtlasRequirementLoader (List<string> requirementList) {
|
|
|
- this.requirementList = requirementList;
|
|
|
- }
|
|
|
+ List<string> requirementList;
|
|
|
+ public AtlasRequirementLoader (List<string> requirementList) {
|
|
|
+ this.requirementList = requirementList;
|
|
|
+ }
|
|
|
|
|
|
- public RegionAttachment NewRegionAttachment (Skin skin, string name, string path) {
|
|
|
- requirementList.Add(path);
|
|
|
- return new RegionAttachment(name);
|
|
|
- }
|
|
|
+ public RegionAttachment NewRegionAttachment (Skin skin, string name, string path) {
|
|
|
+ requirementList.Add(path);
|
|
|
+ return new RegionAttachment(name);
|
|
|
+ }
|
|
|
|
|
|
- public MeshAttachment NewMeshAttachment (Skin skin, string name, string path) {
|
|
|
- requirementList.Add(path);
|
|
|
- return new MeshAttachment(name);
|
|
|
- }
|
|
|
+ public MeshAttachment NewMeshAttachment (Skin skin, string name, string path) {
|
|
|
+ requirementList.Add(path);
|
|
|
+ return new MeshAttachment(name);
|
|
|
+ }
|
|
|
|
|
|
- public WeightedMeshAttachment NewWeightedMeshAttachment(Skin skin, string name, string path) {
|
|
|
- requirementList.Add(path);
|
|
|
- return new WeightedMeshAttachment(name);
|
|
|
- }
|
|
|
+ public WeightedMeshAttachment NewWeightedMeshAttachment(Skin skin, string name, string path) {
|
|
|
+ requirementList.Add(path);
|
|
|
+ return new WeightedMeshAttachment(name);
|
|
|
+ }
|
|
|
|
|
|
- public BoundingBoxAttachment NewBoundingBoxAttachment (Skin skin, string name) {
|
|
|
- return new BoundingBoxAttachment(name);
|
|
|
+ public BoundingBoxAttachment NewBoundingBoxAttachment (Skin skin, string name) {
|
|
|
+ return new BoundingBoxAttachment(name);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
}
|
|
|
+
|