Skip to content

Commit a881c3d

Browse files
committed
Merge branch 'release/v0.2'
2 parents 6f08142 + b0c30a1 commit a881c3d

File tree

3 files changed

+131
-8
lines changed

3 files changed

+131
-8
lines changed

Assets/UnitySpineImporter/Scripts/Editor/SpineImporterWizard.cs

+30-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,15 @@
66

77

88
namespace UnitySpineImporter{
9+
public enum AnimationImportType{
10+
MECANIM,
11+
LEGACY
12+
}
13+
914
public class SpineImporterWizard :ScriptableWizard {
1015
public int pixelsPerUnit = 100;
16+
public bool buildAvatarMask = true;
17+
public AnimationImportType animationImportType = AnimationImportType.MECANIM;
1118
[HideInInspector]
1219
public string path;
1320

@@ -32,6 +39,8 @@ void OnWizardUpdate() {
3239
else
3340
errorString ="";
3441
isValid = errorString.Equals("");
42+
if (animationImportType == AnimationImportType.LEGACY && buildAvatarMask)
43+
helpString += "\n buildAvatarMask will be ignored";
3544
}
3645

3746

@@ -54,8 +63,14 @@ void OnWizardCreate(){
5463
rootGO.name = name;
5564
SpineUtil.addAllAttahcmentsSlots(spineData, spriteByName, slotByName, pixelsPerUnit, out skins, out attachmentGOByNameBySlot);
5665
SkinController sk = SpineUtil.addSkinController(rootGO, spineData, skins, slotByName);
57-
SpineUtil.addAnimator(rootGO);
58-
SpineUtil.addAnimation(rootGO, directory, spineData, boneGOByName, attachmentGOByNameBySlot, pixelsPerUnit);
66+
if (animationImportType == AnimationImportType.MECANIM){
67+
Animator animator = SpineUtil.addAnimator(rootGO);
68+
if (buildAvatarMask)
69+
SpineUtil.builAvatarMask(rootGO,spineData, animator, directory, name);
70+
}
71+
72+
ModelImporterAnimationType modelImporterAnimationType = getModelImporterAnimationType();
73+
SpineUtil.addAnimation(rootGO, directory, spineData, boneGOByName, attachmentGOByNameBySlot, pixelsPerUnit, modelImporterAnimationType);
5974
sk.showDefaulSlots();
6075

6176
SpineUtil.buildPrefab(rootGO, directory, name);
@@ -72,6 +87,19 @@ void OnWizardCreate(){
7287
}
7388
}
7489

90+
ModelImporterAnimationType getModelImporterAnimationType(){
91+
ModelImporterAnimationType result = ModelImporterAnimationType.Generic;
92+
switch(animationImportType){
93+
case AnimationImportType.LEGACY:
94+
result = ModelImporterAnimationType.Legacy;
95+
break;
96+
case AnimationImportType.MECANIM:
97+
result = ModelImporterAnimationType.Generic;
98+
break;
99+
}
100+
return result;
101+
}
102+
75103
static string getAtlasFilePath(string path){
76104
string dir = Path.GetDirectoryName(path);
77105
string fileName = Path.GetFileNameWithoutExtension(path+"ffff");

Assets/UnitySpineImporter/Scripts/Editor/Util/SpineUtil.cs

+97-5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using UnityEditorInternal;
88
using CurveExtended;
99
using LitJson;
10+
using System.Reflection;
1011

1112
namespace UnitySpineImporter{
1213
public class AtlasImageNotFoundException: System.Exception{
@@ -44,16 +45,91 @@ public static void buildPrefab(GameObject gameObject, string directory, string n
4445
PrefabUtility.ReplacePrefab(gameObject, oldPrefab, ReplacePrefabOptions.ReplaceNameBased);
4546
}
4647

48+
public static void builAvatarMask(GameObject gameObject, SpineData spineData, Animator animator, string directory, string name){
49+
Avatar avatar = AvatarBuilder.BuildGenericAvatar(gameObject,"");
50+
animator.avatar = avatar;
51+
AvatarMask avatarMask = new AvatarMask();
52+
string[] transofrmPaths = getTransformPaths(gameObject, spineData);
53+
avatarMask.transformCount = transofrmPaths.Length;
54+
for (int i=0; i< transofrmPaths.Length; i++){
55+
avatarMask.SetTransformPath(i, transofrmPaths[i]);
56+
avatarMask.SetTransformActive(i, true);
57+
}
58+
createFolderIfNoExists(directory, ANIMATION_FOLDER);
59+
AssetDatabase.CreateAsset(avatar , directory + "/" + ANIMATION_FOLDER + "/" + name + ".anim.asset");
60+
AssetDatabase.CreateAsset(avatarMask, directory + "/" + ANIMATION_FOLDER + "/" + name + ".mask.asset");
61+
}
62+
63+
public static string[] getTransformPaths(GameObject go, SpineData spineData){
64+
List<String> result = new List<string>();
65+
result.Add("");
66+
foreach(Transform t in go.GetComponentsInChildren<Transform>(true)){
67+
string path = AnimationUtility.CalculateTransformPath(t,go.transform);
68+
if (t.name.StartsWith(SLOT_PREFIX+" [") && t.name.EndsWith("]")){
69+
string slotName = t.name.Remove(t.name.Length -1);
70+
slotName = slotName.Remove(0,(SLOT_PREFIX+" [").Length );
71+
if (spineData.slotPathByName.ContainsKey(slotName) && spineData.slotPathByName[slotName]==path)
72+
result.Add(path);
73+
}else {
74+
if (spineData.bonePathByName.ContainsKey(t.name) && spineData.bonePathByName[t.name]==path)
75+
result.Add(path);
76+
}
77+
78+
}
79+
return result.ToArray();
80+
}
81+
82+
static int[] sizes = new int[]{0, 32, 64, 128, 256, 512, 1024, 2048, 4096};
83+
static string[] platforms = new string[]{"Web", "Standalone", "iPhone", "Android", "FlashPlayer"};
84+
static void fixTextureSize(string imagePath){
85+
TextureImporter importer = TextureImporter.GetAtPath(imagePath) as TextureImporter;
86+
if (importer != null) {
87+
object[] args = new object[2] { 0, 0 };
88+
MethodInfo mi = typeof(TextureImporter).GetMethod("GetWidthAndHeight", BindingFlags.NonPublic | BindingFlags.Instance);
89+
mi.Invoke(importer, args);
90+
91+
int width = (int)args[0];
92+
int height = (int)args[1];
93+
94+
int max = Mathf.Max(width,height);
95+
if (max > 4096){
96+
Debug.LogError("original texture size is to big " + imagePath + " size=" + width + "x" + height);
97+
return;
98+
}
4799

100+
int fitSize = 0;
101+
for (int i = 0,nextI =1; i < max && fitSize==0; i=nextI++ ) {
102+
if (max > sizes[i] && max <= sizes[nextI] )
103+
fitSize = sizes[nextI];
104+
}
105+
if (importer.maxTextureSize!=fitSize){
106+
Debug.LogWarning("change default size to " + fitSize+ " for "+imagePath);
107+
importer.maxTextureSize = fitSize;
108+
}
109+
foreach(string platform in platforms){
110+
int maxTextureSize;
111+
TextureImporterFormat textureFormat;
112+
importer.GetPlatformTextureSettings(platform, out maxTextureSize, out textureFormat);
113+
if (maxTextureSize != fitSize){
114+
Debug.LogWarning("change specific size to " + fitSize + "on " + platform + " for " + imagePath);
115+
importer.SetPlatformTextureSettings(platform, fitSize, textureFormat);
116+
}
117+
}
118+
AssetDatabase.ImportAsset(imagePath, ImportAssetOptions.ForceSynchronousImport);
119+
}
120+
}
121+
48122
public static void updateImporters(SpineMultiatlas multiatlas, string directory, int pixelsPerUnit, out SpritesByName spriteByName){
49123
spriteByName = new SpritesByName();
50124
foreach (SpineAtlas spineAtlas in multiatlas){
51125
string imagePath = directory + "/" + spineAtlas.imageName;
52126
if (!File.Exists(imagePath))
53127
throw new AtlasImageNotFoundException("can't find " + spineAtlas.imageName + " image in " + directory + " folder");
128+
fixTextureSize(imagePath);
54129
Texture2D tex = AssetDatabase.LoadAssetAtPath(imagePath, typeof(Texture2D )) as Texture2D;
55130
Vector2 atlasSize = new Vector2(tex.width, tex.height);
56131
TextureImporter importer = TextureImporter.GetAtPath(imagePath) as TextureImporter;
132+
importer.maxTextureSize = 2048;
57133
importer.spritesheet = getSpriteMetadata(spineAtlas, atlasSize);
58134
importer.textureType = TextureImporterType.Sprite;
59135
importer.spriteImportMode = SpriteImportMode.Multiple;
@@ -307,14 +383,15 @@ public static void addAnimation(GameObject rootGO,
307383
SpineData spineData,
308384
Dictionary<string, GameObject> boneGOByName,
309385
AttachmentGOByNameBySlot attachmentGOByNameBySlot,
310-
int pixelsPerUnit)
386+
int pixelsPerUnit,
387+
ModelImporterAnimationType modelImporterAnimationType)
311388
{
312389
float ratio = 1.0f / (float)pixelsPerUnit;
313390
foreach(KeyValuePair<string,SpineAnimation> kvp in spineData.animations){
314391
string animationName = kvp.Key;
315392
SpineAnimation spineAnimation = kvp.Value;
316393
AnimationClip animationClip = new AnimationClip();
317-
AnimationUtility.SetAnimationType(animationClip, ModelImporterAnimationType.Generic);
394+
AnimationUtility.SetAnimationType(animationClip, modelImporterAnimationType);
318395
if (spineAnimation.bones!=null)
319396
addBoneAnimationToClip(animationClip,spineAnimation.bones, spineData, boneGOByName, ratio);
320397
if (spineAnimation.slots!=null)
@@ -324,15 +401,30 @@ public static void addAnimation(GameObject rootGO,
324401

325402
animationClip.frameRate = 30;
326403
string animationFolder = rootDirectory+"/"+ANIMATION_FOLDER;
327-
if (!Directory.Exists(animationFolder))
328-
Directory.CreateDirectory(animationFolder);
404+
createFolderIfNoExists(rootDirectory, ANIMATION_FOLDER);
329405

330406
AssetDatabase.CreateAsset(animationClip, animationFolder + "/" + animationName+".anim");
331407
AssetDatabase.SaveAssets();
332-
AddClipToAnimatorComponent(rootGO,animationClip);
408+
if (modelImporterAnimationType == ModelImporterAnimationType.Generic)
409+
AddClipToAnimatorComponent(rootGO,animationClip);
410+
else
411+
AddClipToLegacyAnimationComponent(rootGO, animationClip);
333412
}
334413
}
335414

415+
static void AddClipToLegacyAnimationComponent(GameObject rootGO, AnimationClip animationClip){
416+
Animation animation = rootGO.GetComponent<Animation>();
417+
if (animation == null)
418+
animation = rootGO.AddComponent<Animation>();
419+
animation.AddClip(animationClip, animationClip.name);
420+
}
421+
422+
static void createFolderIfNoExists(string root, string folderName){
423+
string path = root+"/"+folderName;
424+
if (!Directory.Exists(path))
425+
Directory.CreateDirectory(path);
426+
}
427+
336428
public static void addSlotAnimationToClip(AnimationClip clip,
337429
Dictionary<string, SpineSlotAnimation> slotsAnimation,
338430
SpineData spineData,

Assets/UnitySpineImporter/SharedScripts/Editor/SkinControllerEditor.cs

+4-1
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,12 @@ public override void OnInspectorGUI ()
1818
names.Add(skin.name);
1919

2020
int newId = EditorGUILayout.Popup(sk.activeSkinId, names.ToArray());
21-
if (newId != sk.activeSkinId)
21+
if (newId != sk.activeSkinId){
2222
sk.setSkin (newId);
23+
EditorUtility.SetDirty(target);
24+
}
2325
}
2426
}
27+
2528
}
2629
}

0 commit comments

Comments
 (0)