Create spine skeletonmecanim
30 Dec 2020기능
spine을 export하면 나오는 json, text(byte), png 3개의 파일로 skeletonmecanim을 생성한다.
코드
const string k_AtlasExt = ".txt";
const string k_PngExt = ".png";
const string k_JsonExt = ".json .bytes";
public TextAsset m_SkeletonJson; // spine json
public TextAsset m_AtlasText; // spine atlas
public Texture2D[] m_Textures = new Texture2D[1]; // spine png로 생성
void OnSpineData()
{
if(SelectAtlas())
return;
Material material = CreateMaterial();
CreateSpineDataPrefab(material);
}
Material CreateMaterial(string shaderName = "Sprites/Dafault")
{
string currentDir = GetCurrentDirectory();
if (string.IsNullOrEmpty(currentDir) == true)
{
UnityEditor.EditorUtility.DisplayDialog("Error", "Need to Select Folder", "ok");
return null;
}
string folderPath = currentDir + "/Material";
if (AssetDatabase.IsValidFolder(folderPath) == false)
{
string folderGuid = AssetDatabase.CreateFolder(currentDir, "Material");
folderPath = AssetDatabase.GUIDToAssetPath(folderGuid);
}
string assetPrefixName = "/" + new DirectoryInfo(currentDir).Name + "_Material.mat";
Material material = new Material(Shader.Find(shaderName));
material.SetTexture("_MainTex", m_Textures[0]);
AssetDatabase.CreateAsset(material, folderPath + assetPrefixName);
return material;
}
string GetCurrentDirectory()
{
UnityEngine.Object[] selection = Selection.GetFiltered(typeof(UnityEngine.Object), SelectionMode.Assets);
if (selection.Length > 0)
{
UnityEngine.Object selectionAsset = selection[0];
string assetPath = AssetDatabase.GetAssetPath(selectionAsset);
string realPath = Path.GetDirectoryName(assetPath);
if (Path.HasExtension(assetPath) == false)
return realPath + "/" + selectionAsset.name;
return realPath;
}
return null;
}
// 3개의 파일 선택 체크
bool SelectAtlas()
{
UnityEngine.Object[] selection = Selection.GetFiltered(typeof(UnityEngine.Object), SelectionMode.Assets);
int selectionLength = selection.Length;
if (selectionLength != 3)
return false;
string assetPath;
string ext;
for (int i = 0; i < selectionLength; i++)
{
UnityEngine.Object selectionAsset = selection[i];
assetPath = AssetDatabase.GetAssetPath(selectionAsset);
ext = Path.GetExtension(assetPath);
if (string.Equals(ext, k_AtlasExt) == true)
{
m_AtlasText = selectionAsset as TextAsset;
}
else if (k_JsonExt.Contains(ext) == true)
{
m_SkeletonJson = selectionAsset as TextAsset;
}
else if (string.Equals(ext, k_PngExt) == true)
{
m_Textures[0] = selectionAsset as Texture2D;
}
}
if (m_AtlasText == null || m_SkeletonJson == null || m_Textures[0] == null)
{
UnityEditor.EditorUtility.DisplayDialog("Error", "need to select asset png, json OR bytes, text", "ok");
return false;
}
return true;
}
// spine data가 붙어있는 prefab 생성
void CreateSpineDataPrefab(Material material)
{
Material[] tempMaterial = new Material[1];
tempMaterial[0] = material;
m_AtlasAsset = SpineAtlasAsset.CreateRuntimeInstance(m_AtlasText, tempMaterial, true);
m_SkeletonDataAsset = SkeletonDataAsset.CreateRuntimeInstance(m_SkeletonJson, m_AtlasAsset, true);
material.mainTexture = m_Textures[0];
m_SpineName = Path.GetFileNameWithoutExtension(m_SkeletonJson.name);
m_AtlasText = null;
m_Textures[0] = null;
m_SkeletonJson = null;
if (m_AtlasAsset == null || m_SkeletonDataAsset == null)
{
UnityEditor.EditorUtility.DisplayDialog("Error", "생성 실패", "ok");
return;
}
m_AtlasAsset.materials[0] = material;
string currentDir = GetCurrentDirectory();
AssetDatabase.CreateAsset(m_AtlasAsset, currentDir + "/" + m_SpineName + "_AtlasData.asset");
AssetDatabase.CreateAsset(m_SkeletonDataAsset, currentDir + "/" + m_SpineName + "_SkeletonData.asset");
SkeletonBaker.GenerateMecanimAnimationClips(m_SkeletonDataAsset); // spine에 있는 정보로 clip정보를 생성한다.
GameObject rootObject = new GameObject(m_SpineName);
rootObject.tag = 'tag you want to';
rootObject.layer = LayerMask.NameToLayer('layer you want to);
SkeletonMecanim skeletonAnimator = rootObject.AddComponent<SkeletonMecanim>();
skeletonAnimator.skeletonDataAsset = m_SkeletonDataAsset; // <<--- 이 부분이 중요
Animator animator = skeletonAnimator.GetComponent<Animator>();
animator.cullingMode = AnimatorCullingMode.CullCompletely;
int length = skeletonAnimator.skeletonDataAsset.GetSkeletonData(false).Skins.Count;
for (int i = 0; i < length; i++)
{
string skinName = skeletonAnimator.skeletonDataAsset.GetSkeletonData(false).Skins.Items[i].Name;
skeletonAnimator.initialSkinName = skinName;
rootObject.name = skinName.Equals("default") ? m_SpineName : skinName;
CreatePrefab(currentDir, rootObject, true);
}
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
EditorUtility.FocusProjectWindow();
DestroyImmediate(rootObject);
}
void CreatePrefab(string dir, GameObject gameObject, bool isReplace = false)
{
string folderPath = dir + "/Prefabs";
if (AssetDatabase.IsValidFolder(folderPath) == false)
{
string folderGuid = AssetDatabase.CreateFolder(dir, "Prefabs");
folderPath = AssetDatabase.GUIDToAssetPath(folderGuid);
}
var go = PrefabUtility.SaveAsPrefabAsset(gameObject, dir + "/Prefabs/" + gameObject.name + ".prefab");
Selection.activeObject = go;
}