Skip to content

Commit

Permalink
Merge branch 'release/v0.2'
Browse files Browse the repository at this point in the history
  • Loading branch information
nicloay committed Jan 30, 2014
2 parents 6f08142 + b0c30a1 commit a881c3d
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 8 deletions.
32 changes: 30 additions & 2 deletions Assets/UnitySpineImporter/Scripts/Editor/SpineImporterWizard.cs
Expand Up @@ -6,8 +6,15 @@


namespace UnitySpineImporter{
public enum AnimationImportType{
MECANIM,
LEGACY
}

public class SpineImporterWizard :ScriptableWizard {
public int pixelsPerUnit = 100;
public bool buildAvatarMask = true;
public AnimationImportType animationImportType = AnimationImportType.MECANIM;
[HideInInspector]
public string path;

Expand All @@ -32,6 +39,8 @@ public class SpineImporterWizard :ScriptableWizard {
else
errorString ="";
isValid = errorString.Equals("");
if (animationImportType == AnimationImportType.LEGACY && buildAvatarMask)
helpString += "\n buildAvatarMask will be ignored";
}


Expand All @@ -54,8 +63,14 @@ public class SpineImporterWizard :ScriptableWizard {
rootGO.name = name;
SpineUtil.addAllAttahcmentsSlots(spineData, spriteByName, slotByName, pixelsPerUnit, out skins, out attachmentGOByNameBySlot);
SkinController sk = SpineUtil.addSkinController(rootGO, spineData, skins, slotByName);
SpineUtil.addAnimator(rootGO);
SpineUtil.addAnimation(rootGO, directory, spineData, boneGOByName, attachmentGOByNameBySlot, pixelsPerUnit);
if (animationImportType == AnimationImportType.MECANIM){
Animator animator = SpineUtil.addAnimator(rootGO);
if (buildAvatarMask)
SpineUtil.builAvatarMask(rootGO,spineData, animator, directory, name);
}

ModelImporterAnimationType modelImporterAnimationType = getModelImporterAnimationType();
SpineUtil.addAnimation(rootGO, directory, spineData, boneGOByName, attachmentGOByNameBySlot, pixelsPerUnit, modelImporterAnimationType);
sk.showDefaulSlots();

SpineUtil.buildPrefab(rootGO, directory, name);
Expand All @@ -72,6 +87,19 @@ public class SpineImporterWizard :ScriptableWizard {
}
}

ModelImporterAnimationType getModelImporterAnimationType(){
ModelImporterAnimationType result = ModelImporterAnimationType.Generic;
switch(animationImportType){
case AnimationImportType.LEGACY:
result = ModelImporterAnimationType.Legacy;
break;
case AnimationImportType.MECANIM:
result = ModelImporterAnimationType.Generic;
break;
}
return result;
}

static string getAtlasFilePath(string path){
string dir = Path.GetDirectoryName(path);
string fileName = Path.GetFileNameWithoutExtension(path+"ffff");
Expand Down
102 changes: 97 additions & 5 deletions Assets/UnitySpineImporter/Scripts/Editor/Util/SpineUtil.cs
Expand Up @@ -7,6 +7,7 @@
using UnityEditorInternal;
using CurveExtended;
using LitJson;
using System.Reflection;

namespace UnitySpineImporter{
public class AtlasImageNotFoundException: System.Exception{
Expand Down Expand Up @@ -44,16 +45,91 @@ public class SpineUtil {
PrefabUtility.ReplacePrefab(gameObject, oldPrefab, ReplacePrefabOptions.ReplaceNameBased);
}

public static void builAvatarMask(GameObject gameObject, SpineData spineData, Animator animator, string directory, string name){
Avatar avatar = AvatarBuilder.BuildGenericAvatar(gameObject,"");
animator.avatar = avatar;
AvatarMask avatarMask = new AvatarMask();
string[] transofrmPaths = getTransformPaths(gameObject, spineData);
avatarMask.transformCount = transofrmPaths.Length;
for (int i=0; i< transofrmPaths.Length; i++){
avatarMask.SetTransformPath(i, transofrmPaths[i]);
avatarMask.SetTransformActive(i, true);
}
createFolderIfNoExists(directory, ANIMATION_FOLDER);
AssetDatabase.CreateAsset(avatar , directory + "/" + ANIMATION_FOLDER + "/" + name + ".anim.asset");
AssetDatabase.CreateAsset(avatarMask, directory + "/" + ANIMATION_FOLDER + "/" + name + ".mask.asset");
}

public static string[] getTransformPaths(GameObject go, SpineData spineData){
List<String> result = new List<string>();
result.Add("");
foreach(Transform t in go.GetComponentsInChildren<Transform>(true)){
string path = AnimationUtility.CalculateTransformPath(t,go.transform);
if (t.name.StartsWith(SLOT_PREFIX+" [") && t.name.EndsWith("]")){
string slotName = t.name.Remove(t.name.Length -1);
slotName = slotName.Remove(0,(SLOT_PREFIX+" [").Length );
if (spineData.slotPathByName.ContainsKey(slotName) && spineData.slotPathByName[slotName]==path)
result.Add(path);
}else {
if (spineData.bonePathByName.ContainsKey(t.name) && spineData.bonePathByName[t.name]==path)
result.Add(path);
}

}
return result.ToArray();
}

static int[] sizes = new int[]{0, 32, 64, 128, 256, 512, 1024, 2048, 4096};
static string[] platforms = new string[]{"Web", "Standalone", "iPhone", "Android", "FlashPlayer"};
static void fixTextureSize(string imagePath){
TextureImporter importer = TextureImporter.GetAtPath(imagePath) as TextureImporter;
if (importer != null) {
object[] args = new object[2] { 0, 0 };
MethodInfo mi = typeof(TextureImporter).GetMethod("GetWidthAndHeight", BindingFlags.NonPublic | BindingFlags.Instance);
mi.Invoke(importer, args);

int width = (int)args[0];
int height = (int)args[1];

int max = Mathf.Max(width,height);
if (max > 4096){
Debug.LogError("original texture size is to big " + imagePath + " size=" + width + "x" + height);
return;
}

int fitSize = 0;
for (int i = 0,nextI =1; i < max && fitSize==0; i=nextI++ ) {
if (max > sizes[i] && max <= sizes[nextI] )
fitSize = sizes[nextI];
}
if (importer.maxTextureSize!=fitSize){
Debug.LogWarning("change default size to " + fitSize+ " for "+imagePath);
importer.maxTextureSize = fitSize;
}
foreach(string platform in platforms){
int maxTextureSize;
TextureImporterFormat textureFormat;
importer.GetPlatformTextureSettings(platform, out maxTextureSize, out textureFormat);
if (maxTextureSize != fitSize){
Debug.LogWarning("change specific size to " + fitSize + "on " + platform + " for " + imagePath);
importer.SetPlatformTextureSettings(platform, fitSize, textureFormat);
}
}
AssetDatabase.ImportAsset(imagePath, ImportAssetOptions.ForceSynchronousImport);
}
}

public static void updateImporters(SpineMultiatlas multiatlas, string directory, int pixelsPerUnit, out SpritesByName spriteByName){
spriteByName = new SpritesByName();
foreach (SpineAtlas spineAtlas in multiatlas){
string imagePath = directory + "/" + spineAtlas.imageName;
if (!File.Exists(imagePath))
throw new AtlasImageNotFoundException("can't find " + spineAtlas.imageName + " image in " + directory + " folder");
fixTextureSize(imagePath);
Texture2D tex = AssetDatabase.LoadAssetAtPath(imagePath, typeof(Texture2D )) as Texture2D;
Vector2 atlasSize = new Vector2(tex.width, tex.height);
TextureImporter importer = TextureImporter.GetAtPath(imagePath) as TextureImporter;
importer.maxTextureSize = 2048;
importer.spritesheet = getSpriteMetadata(spineAtlas, atlasSize);
importer.textureType = TextureImporterType.Sprite;
importer.spriteImportMode = SpriteImportMode.Multiple;
Expand Down Expand Up @@ -307,14 +383,15 @@ public class SpineUtil {
SpineData spineData,
Dictionary<string, GameObject> boneGOByName,
AttachmentGOByNameBySlot attachmentGOByNameBySlot,
int pixelsPerUnit)
int pixelsPerUnit,
ModelImporterAnimationType modelImporterAnimationType)
{
float ratio = 1.0f / (float)pixelsPerUnit;
foreach(KeyValuePair<string,SpineAnimation> kvp in spineData.animations){
string animationName = kvp.Key;
SpineAnimation spineAnimation = kvp.Value;
AnimationClip animationClip = new AnimationClip();
AnimationUtility.SetAnimationType(animationClip, ModelImporterAnimationType.Generic);
AnimationUtility.SetAnimationType(animationClip, modelImporterAnimationType);
if (spineAnimation.bones!=null)
addBoneAnimationToClip(animationClip,spineAnimation.bones, spineData, boneGOByName, ratio);
if (spineAnimation.slots!=null)
Expand All @@ -324,15 +401,30 @@ public class SpineUtil {

animationClip.frameRate = 30;
string animationFolder = rootDirectory+"/"+ANIMATION_FOLDER;
if (!Directory.Exists(animationFolder))
Directory.CreateDirectory(animationFolder);
createFolderIfNoExists(rootDirectory, ANIMATION_FOLDER);

AssetDatabase.CreateAsset(animationClip, animationFolder + "/" + animationName+".anim");
AssetDatabase.SaveAssets();
AddClipToAnimatorComponent(rootGO,animationClip);
if (modelImporterAnimationType == ModelImporterAnimationType.Generic)
AddClipToAnimatorComponent(rootGO,animationClip);
else
AddClipToLegacyAnimationComponent(rootGO, animationClip);
}
}

static void AddClipToLegacyAnimationComponent(GameObject rootGO, AnimationClip animationClip){
Animation animation = rootGO.GetComponent<Animation>();
if (animation == null)
animation = rootGO.AddComponent<Animation>();
animation.AddClip(animationClip, animationClip.name);
}

static void createFolderIfNoExists(string root, string folderName){
string path = root+"/"+folderName;
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
}

public static void addSlotAnimationToClip(AnimationClip clip,
Dictionary<string, SpineSlotAnimation> slotsAnimation,
SpineData spineData,
Expand Down
Expand Up @@ -18,9 +18,12 @@ public override void OnInspectorGUI ()
names.Add(skin.name);

int newId = EditorGUILayout.Popup(sk.activeSkinId, names.ToArray());
if (newId != sk.activeSkinId)
if (newId != sk.activeSkinId){
sk.setSkin (newId);
EditorUtility.SetDirty(target);
}
}
}

}
}

0 comments on commit a881c3d

Please sign in to comment.