mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2025-12-21 17:56:04 +08:00
Merge pull request #312 from Fenrisul/master
[Unity TK2D] Workflow improvements and bugfixes
This commit is contained in:
commit
54499dd7a0
@ -56,6 +56,7 @@ public class SkeletonDataAssetInspector : Editor {
|
|||||||
private bool m_initialized = false;
|
private bool m_initialized = false;
|
||||||
private SkeletonDataAsset m_skeletonDataAsset;
|
private SkeletonDataAsset m_skeletonDataAsset;
|
||||||
private string m_skeletonDataAssetGUID;
|
private string m_skeletonDataAssetGUID;
|
||||||
|
bool failedSkeletonDataLatch = false;
|
||||||
|
|
||||||
void OnEnable () {
|
void OnEnable () {
|
||||||
try {
|
try {
|
||||||
@ -98,10 +99,23 @@ public class SkeletonDataAssetInspector : Editor {
|
|||||||
EditorGUILayout.PropertyField(skeletonJSON);
|
EditorGUILayout.PropertyField(skeletonJSON);
|
||||||
EditorGUILayout.PropertyField(scale);
|
EditorGUILayout.PropertyField(scale);
|
||||||
if (EditorGUI.EndChangeCheck()) {
|
if (EditorGUI.EndChangeCheck()) {
|
||||||
|
|
||||||
|
if(failedSkeletonDataLatch){
|
||||||
|
failedSkeletonDataLatch = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_previewUtility != null) {
|
if (m_previewUtility != null) {
|
||||||
m_previewUtility.Cleanup();
|
m_previewUtility.Cleanup();
|
||||||
m_previewUtility = null;
|
m_previewUtility = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
serializedObject.ApplyModifiedProperties();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(failedSkeletonDataLatch){
|
||||||
|
GUI.color = Color.red;
|
||||||
|
GUILayout.Label("WARNING: Skeleton JSON and Sprite Collection Mismatch");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SkeletonData skeletonData = asset.GetSkeletonData(asset.spriteCollection == null || asset.skeletonJSON == null);
|
SkeletonData skeletonData = asset.GetSkeletonData(asset.spriteCollection == null || asset.skeletonJSON == null);
|
||||||
@ -238,7 +252,7 @@ public class SkeletonDataAssetInspector : Editor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void InitPreview () {
|
private void InitPreview () {
|
||||||
if (this.m_previewUtility == null) {
|
if (this.m_previewUtility == null && m_skeletonDataAsset.spriteCollection != null && !failedSkeletonDataLatch) {
|
||||||
this.m_lastTime = Time.realtimeSinceStartup;
|
this.m_lastTime = Time.realtimeSinceStartup;
|
||||||
this.m_previewUtility = new PreviewRenderUtility(true);
|
this.m_previewUtility = new PreviewRenderUtility(true);
|
||||||
this.m_previewUtility.m_Camera.isOrthoGraphic = true;
|
this.m_previewUtility.m_Camera.isOrthoGraphic = true;
|
||||||
@ -252,8 +266,14 @@ public class SkeletonDataAssetInspector : Editor {
|
|||||||
this.DestroyPreviewInstances();
|
this.DestroyPreviewInstances();
|
||||||
if (this.m_previewInstance == null) {
|
if (this.m_previewInstance == null) {
|
||||||
string skinName = EditorPrefs.GetString(m_skeletonDataAssetGUID + "_lastSkin", "");
|
string skinName = EditorPrefs.GetString(m_skeletonDataAssetGUID + "_lastSkin", "");
|
||||||
|
SkeletonAnimation skelAnim = SpineEditorUtilities.SpawnAnimatedSkeleton((SkeletonDataAsset)target, skinName);
|
||||||
|
if(skelAnim == null){
|
||||||
|
failedSkeletonDataLatch = true;
|
||||||
|
//EditorUtility.DisplayDialog("Skeleton / SpriteCollection Mismatch", "GetSkeletonData failed, make sure JSON and SpriteCollection match.\nSprite Collection must contain all attachments referenced in SkeletonJSON", "OK");
|
||||||
|
return; //failed
|
||||||
|
}
|
||||||
|
|
||||||
m_previewInstance = SpineEditorUtilities.SpawnAnimatedSkeleton((SkeletonDataAsset)target, skinName).gameObject;
|
m_previewInstance = skelAnim.gameObject;
|
||||||
//m_previewInstance.transform.localScale = Vector3.one * 0.01f;
|
//m_previewInstance.transform.localScale = Vector3.one * 0.01f;
|
||||||
m_previewInstance.hideFlags = HideFlags.HideAndDontSave;
|
m_previewInstance.hideFlags = HideFlags.HideAndDontSave;
|
||||||
m_previewInstance.layer = 0x1f;
|
m_previewInstance.layer = 0x1f;
|
||||||
@ -281,12 +301,16 @@ public class SkeletonDataAssetInspector : Editor {
|
|||||||
|
|
||||||
public override bool HasPreviewGUI () {
|
public override bool HasPreviewGUI () {
|
||||||
//TODO: validate json data
|
//TODO: validate json data
|
||||||
return skeletonJSON.objectReferenceValue != null;
|
|
||||||
|
return skeletonJSON.objectReferenceValue != null && spriteCollection.objectReferenceValue != null && !failedSkeletonDataLatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture m_previewTex = new Texture();
|
Texture m_previewTex = new Texture();
|
||||||
|
|
||||||
public override void OnInteractivePreviewGUI (Rect r, GUIStyle background) {
|
public override void OnInteractivePreviewGUI (Rect r, GUIStyle background) {
|
||||||
|
if(m_skeletonDataAsset.spriteCollection == null)
|
||||||
|
return;
|
||||||
|
|
||||||
this.InitPreview();
|
this.InitPreview();
|
||||||
|
|
||||||
if (UnityEngine.Event.current.type == EventType.Repaint) {
|
if (UnityEngine.Event.current.type == EventType.Repaint) {
|
||||||
@ -355,7 +379,7 @@ public class SkeletonDataAssetInspector : Editor {
|
|||||||
private void DoRenderPreview (bool drawHandles) {
|
private void DoRenderPreview (bool drawHandles) {
|
||||||
GameObject go = this.m_previewInstance;
|
GameObject go = this.m_previewInstance;
|
||||||
|
|
||||||
if (m_requireRefresh) {
|
if (m_requireRefresh && go != null) {
|
||||||
go.renderer.enabled = true;
|
go.renderer.enabled = true;
|
||||||
|
|
||||||
if (EditorApplication.isPlaying) {
|
if (EditorApplication.isPlaying) {
|
||||||
@ -581,6 +605,8 @@ public class SkeletonDataAssetInspector : Editor {
|
|||||||
//TODO: Fix first-import error
|
//TODO: Fix first-import error
|
||||||
//TODO: Update preview without thumbnail
|
//TODO: Update preview without thumbnail
|
||||||
public override Texture2D RenderStaticPreview (string assetPath, UnityEngine.Object[] subAssets, int width, int height) {
|
public override Texture2D RenderStaticPreview (string assetPath, UnityEngine.Object[] subAssets, int width, int height) {
|
||||||
|
if(m_skeletonDataAsset.spriteCollection == null)
|
||||||
|
return null;
|
||||||
Texture2D tex = new Texture2D(width, height, TextureFormat.ARGB32, false);
|
Texture2D tex = new Texture2D(width, height, TextureFormat.ARGB32, false);
|
||||||
|
|
||||||
this.InitPreview();
|
this.InitPreview();
|
||||||
|
|||||||
@ -231,7 +231,11 @@ public class SpineEditorUtilities : AssetPostprocessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static SkeletonAnimation SpawnAnimatedSkeleton (SkeletonDataAsset skeletonDataAsset, string skinName) {
|
public static SkeletonAnimation SpawnAnimatedSkeleton (SkeletonDataAsset skeletonDataAsset, string skinName) {
|
||||||
return SpawnAnimatedSkeleton(skeletonDataAsset, skeletonDataAsset.GetSkeletonData(true).FindSkin(skinName));
|
SkeletonData skelData = skeletonDataAsset.GetSkeletonData(false);
|
||||||
|
if(skelData == null){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return SpawnAnimatedSkeleton(skeletonDataAsset, skelData.FindSkin(skinName));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SkeletonAnimation SpawnAnimatedSkeleton (SkeletonDataAsset skeletonDataAsset, Skin skin = null) {
|
public static SkeletonAnimation SpawnAnimatedSkeleton (SkeletonDataAsset skeletonDataAsset, Skin skin = null) {
|
||||||
@ -241,7 +245,7 @@ public class SpineEditorUtilities : AssetPostprocessor {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
SkeletonData data = skeletonDataAsset.GetSkeletonData(true);
|
SkeletonData data = skeletonDataAsset.GetSkeletonData(false);
|
||||||
|
|
||||||
if (data == null) {
|
if (data == null) {
|
||||||
return null;
|
return null;
|
||||||
@ -265,4 +269,108 @@ public class SpineEditorUtilities : AssetPostprocessor {
|
|||||||
|
|
||||||
return anim;
|
return anim;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool IsSpineJSON (TextAsset asset) {
|
||||||
|
object obj = Json.Deserialize(new StringReader(asset.text));
|
||||||
|
if (obj == null) {
|
||||||
|
Debug.LogError("Is not valid JSON");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Dictionary<string, object> root = (Dictionary<string, object>)obj;
|
||||||
|
|
||||||
|
if (!root.ContainsKey("skeleton"))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Dictionary<string, object> skeletonInfo = (Dictionary<string, object>)root["skeleton"];
|
||||||
|
|
||||||
|
string spineVersion = (string)skeletonInfo["spine"];
|
||||||
|
//TODO: reject old versions
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TK2D helpers
|
||||||
|
|
||||||
|
[MenuItem("Assets/Create/Spine/SkeletonData From Selection", true)]
|
||||||
|
static bool CreateSkeletonDataFromSelectionValidate(){
|
||||||
|
int spineJsonCount = 0;
|
||||||
|
int collectionCount = 0;
|
||||||
|
|
||||||
|
foreach(Object obj in Selection.objects){
|
||||||
|
if(obj is TextAsset){
|
||||||
|
TextAsset t = obj as TextAsset;
|
||||||
|
if(IsSpineJSON(t))
|
||||||
|
spineJsonCount++;
|
||||||
|
}
|
||||||
|
else if(obj is GameObject){
|
||||||
|
GameObject go = obj as GameObject;
|
||||||
|
var spriteCollection = go.GetComponent<tk2dSpriteCollection>();
|
||||||
|
if(spriteCollection != null){
|
||||||
|
if(spriteCollection.spriteCollection != null){
|
||||||
|
collectionCount++;
|
||||||
|
if(collectionCount > 1){
|
||||||
|
Debug.LogWarning("SkeletonData From Selection only works when 1 Collection is selected.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(spineJsonCount > 0 && collectionCount == 1){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MenuItem("Assets/Create/Spine/SkeletonData From Selection")]
|
||||||
|
static void CreateSkeletonDataFromSelection(){
|
||||||
|
|
||||||
|
List<TextAsset> jsonList = new List<TextAsset>();
|
||||||
|
tk2dSpriteCollectionData collectionData = null;
|
||||||
|
|
||||||
|
foreach(Object obj in Selection.objects){
|
||||||
|
if(obj is TextAsset){
|
||||||
|
TextAsset t = obj as TextAsset;
|
||||||
|
if(IsSpineJSON(t))
|
||||||
|
jsonList.Add(t);
|
||||||
|
}
|
||||||
|
else if(obj is GameObject){
|
||||||
|
GameObject go = obj as GameObject;
|
||||||
|
var spriteCollection = go.GetComponent<tk2dSpriteCollection>();
|
||||||
|
if(spriteCollection != null){
|
||||||
|
if(spriteCollection.spriteCollection != null){
|
||||||
|
collectionData = spriteCollection.spriteCollection;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(collectionData == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
foreach(TextAsset t in jsonList){
|
||||||
|
string path = Path.GetDirectoryName(AssetDatabase.GetAssetPath(t)) + "/" + t.name + "_SkeletonData.asset";
|
||||||
|
|
||||||
|
SkeletonDataAsset skeletonDataAsset = (SkeletonDataAsset)AssetDatabase.LoadAssetAtPath(path, typeof(SkeletonDataAsset));
|
||||||
|
if(skeletonDataAsset == null){
|
||||||
|
skeletonDataAsset = SkeletonDataAsset.CreateInstance<SkeletonDataAsset>();
|
||||||
|
AssetDatabase.CreateAsset(skeletonDataAsset, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
skeletonDataAsset.skeletonJSON = t;
|
||||||
|
skeletonDataAsset.spriteCollection = collectionData;
|
||||||
|
skeletonDataAsset.defaultMix = 0.2f;
|
||||||
|
skeletonDataAsset.fromAnimation = new string[0];
|
||||||
|
skeletonDataAsset.toAnimation = new string[0];
|
||||||
|
skeletonDataAsset.duration = new float[0];
|
||||||
|
|
||||||
|
EditorUtility.SetDirty(skeletonDataAsset);
|
||||||
|
AssetDatabase.SaveAssets();
|
||||||
|
AssetDatabase.Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user