Skip to content

Instantly share code, notes, and snippets.

@whaison
Forked from asus4/ModelAnimationSpliter.cs
Last active August 29, 2015 14:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save whaison/918a5bc311a084c568ea to your computer and use it in GitHub Desktop.
Save whaison/918a5bc311a084c568ea to your computer and use it in GitHub Desktop.
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using System.IO;
/// <summary>
/// Model animation spliter.
/// by Koki Ibukuro @asus4 >Noboru Otsuka
/// </summary>
public class ModelAnimationSpliter : EditorWindow {
TextAsset csvAsset;
GameObject modelAsset;
string CharaName;
string AnimationNameStr;
string AnimationClipEventNameStr;
string CharaDir;
void OnGUI ()
{
GUILayout.Label ("CSV to Split Animtion", EditorStyles.boldLabel);
GUILayout.Space (10f);
csvAsset = EditorGUILayout.ObjectField ("CSV Text", csvAsset, typeof(TextAsset), false) as TextAsset;
if (csvAsset == null) {
GUILayout.Label ("Set CSV Data. Extension need .txt");
}
GUILayout.Space (10f);
modelAsset = EditorGUILayout.ObjectField ("3D Model", modelAsset, typeof(GameObject), false) as GameObject;
if (modelAsset == null) {
GUILayout.Label ("Set FBX or other 3D model object.");
}
GUILayout.Space (20f);
if (GUILayout.Button ("Split with CSV", GUILayout.Width (140f))) {
SplitWithCsv ();
}
}
void SplitWithCsv ()
{
if (Assert (csvAsset != null, "Need to set CSV Text") || Assert (modelAsset != null, "Need to set 3D Model")) {
return;
}
string csv = csvAsset.text;
Debug.Log ("csvAsset=" + csvAsset);
Debug.Log ("modelAsset=" + modelAsset);
/**/
/////////////////////////////////////////////////////////////////////////////
string modelDirStr = AssetDatabase.GetAssetPath (modelAsset);
Debug.Log ("modelDirStr=" + modelDirStr);
string[] modelDirArr;
modelDirArr=modelDirStr.Split("/"[0]);
string buildDir = modelDirArr[0];
for(int i = 1; i < modelDirArr.Length-1; i++)
{
buildDir = buildDir +"/"+ modelDirArr [i];
}
CharaDir = buildDir;
Debug.Log ("CharaDir="+CharaDir);
CharaName = modelDirArr [modelDirArr.Length-1];
Debug.Log ("CharaName="+CharaName);
////////////////////////////////////////////////////////////////////////////////
ModelImporterClipAnimation[] clipAnimations = ParceCSV (csv);
Debug.Log ("SplitWithCsv () clipAnimations= "+clipAnimations);
/*
if (Assert (clipAnimations != null, "can't parse CSV to Animation")) {
Debug.Log (csv);
return;
}
*/
string path = AssetDatabase.GetAssetPath (modelAsset);
ModelImporter importer = AssetImporter.GetAtPath (path) as ModelImporter;
if (Assert (importer != null, "set 3D model, like FBX,etc..")) {
return;
}
//importer.splitAnimations = true; // obsolute in Unity4
importer.clipAnimations = clipAnimations;
AssetDatabase.ImportAsset (path);
DisplayDialog ("Success", "finish split!");
}
bool Assert (bool b, string error)
{
if (!b) {
DisplayDialog ("Warning", error);
return true;
} else {
return false;
}
}
void DisplayDialog (string title, string message)
{
Debug.LogWarning (message);
EditorUtility.DisplayDialog (title, message, "OK");
}
ModelImporterClipAnimation[] ParceCSV (string csv)
{
// split to lines
string[] lines = csv.Split ('\n');
//Debug.Log("[]lines = "+ []lines);
char[] trims = {'\r', ' '};
Debug.Log("trims = "+trims);
List<ModelImporterClipAnimation> clips = new List<ModelImporterClipAnimation> ();
Debug.Log("lines.Length; = "+lines.Length);
for (int i=0; i<lines.Length; i++)
{
string s = lines [i].Trim (trims);
ModelImporterClipAnimation clip = ParseClip (s);
Debug.Log ("ParseClip(c) の戻り値=clip= "+clip);
if (clip != null) {
Debug.Log ("clipsにAdd する clip= "+clip);
clips.Add (clip);
}
}
if (clips.Count == 0) {
Debug.Log ("CSVのクリップスは clips.Count= 0 個ありました");
return null;
} else {
Debug.Log ("CSVのクリップスは clips.Count= " + clips.Count + " 個ありました");
}
return clips.ToArray();
}
ModelImporterClipAnimation ParseClip (string line)
{
string[] arr = line.Split (',');
//Debug.Log("[] arr = "+[] arr);
Debug.Log("arr.Length = "+arr.Length);
if (arr.Length < 4) {
return null;
} else {
Debug.Log ("CSV行の長さは必要なだけあります。");
}
ModelImporterClipAnimation clip = new ModelImporterClipAnimation ();
// name
string name = arr [0];
if (!string.IsNullOrEmpty (name)) {
clip.name = name;
Debug.Log ("clip.name =" + clip.name);
AnimationNameStr = clip.name;
} else {
return null;
}
// first
try {
//clip.firstFrame = int.Parse (arr [1]); // change to float in unity4
clip.firstFrame = float.Parse (arr [1]);
Debug.Log ("clip.firstFrame =" + clip.firstFrame);
} catch {
return null;
}
// last
try {
//clip.lastFrame = int.Parse (arr [2]); // change to float in unity4
clip.lastFrame = float.Parse (arr [2]);
Debug.Log ("clip.lastFrame =" + clip.lastFrame);
} catch {
return null;
}
try {
//clip.lastFrame = int.Parse (arr [2]); // change to float in unity4
bool myLoopTimebool=true;
switch (AnimationNameStr)
{
case "anim_04_block":
myLoopTimebool=false;
break;
case "anim_05_damage":
myLoopTimebool=false;
break;
case "anim_07_death":
myLoopTimebool=false;
break;
case "anim_09_attack":
myLoopTimebool=false;
break;
case "anim_10_skill":
myLoopTimebool=false;
break;
default:
myLoopTimebool=true;
break;
}
clip.loopTime=myLoopTimebool;
Debug.Log ("clip.loopTime =" + clip.loopTime);
} catch {
return null;
}
/////////////////////////////Effect
///
///
List<AnimationEvent> animEventsList1 = new List<AnimationEvent>();
try {
////////////////////////
/// ////////////////////////////
string eventStr1 = arr [3];
// アニメーションイベントの作成
AnimationEvent animEvent1 = new AnimationEvent();
//AnimationEvent[] animEvents;
// 関数名をセット
animEvent1.functionName =eventStr1;
AnimationClipEventNameStr=animEvent1.functionName;
// Int型のパラメーターを格納
animEvent1.intParameter = 0;
//animEvent.time=arr [4];
//animEvent.objectReferenceParameter=objEffect_0_start as UnityEngine.Object ;
// 設定した時間にイベントを送信
animEvent1.time = float.Parse (arr [4]);
// アニメーションイベントの追加
//clip.AddEvent(animEvent);
if(arr [3+1]!=null){
Debug.Log("while loop arr["+3+"+1]="+arr [3+1]+" があるので実行");
//////////////////////////////////////
//AnimationClipRef;
CreateAnimationClip();
Crate();
///////////////////////////////////////
animEvent1.objectReferenceParameter=ScriptableObjectRef as UnityEngine.Object ;
// アニメーションイベントの追加
//clip.AddEvent(animEvent);
animEventsList1.Add(animEvent1);
}
//animEventsList1.Add(animEvent1);
} catch {
//return null;
}
try {
////////////////////////
/// ////////////////////////////
string eventStr2= arr [5];
// アニメーションイベントの作成
AnimationEvent animEvent2 = new AnimationEvent();
//AnimationEvent[] animEvents;
// 関数名をセット
animEvent2.functionName =eventStr2;
AnimationClipEventNameStr=animEvent2.functionName;
// Int型のパラメーターを格納
animEvent2.intParameter = 0;
//animEvent.time=arr [4];
//animEvent.objectReferenceParameter=objEffect_0_start as UnityEngine.Object ;
// 設定した時間にイベントを送信
animEvent2.time = float.Parse (arr [6]);
// アニメーションイベントの追加
//clip.AddEvent(animEvent);
if(arr [5+1]!=null){
Debug.Log("while loop arr["+5+"+1]="+arr [5+1]+" があるので実行");
//////////////////////////////////////
Crate();
///////////////////////////////////////
animEvent2.objectReferenceParameter=ScriptableObjectRef as UnityEngine.Object ;
// アニメーションイベントの追加
//clip.AddEvent(animEvent);
animEventsList1.Add(animEvent2);
}
//animEventsList1.Add(animEvent2);
} catch {
//return null;
}
try{
//for(int i = 7; i < arr.Length; i+2)
//{
int i=7;
while(i < arr.Length)
{
//Debug.Log ("I've washed a cup!");
Debug.Log("--------while loop i="+i+"----------------------");
/// ////////////////////////////
string eventStr3= arr [i];
Debug.Log("while loop eventStr3="+eventStr3);
// アニメーションイベントの作成
AnimationEvent animEvent3 = new AnimationEvent();
//AnimationEvent[] animEvents;
// 関数名をセット
animEvent3.functionName =eventStr3;
AnimationClipEventNameStr=animEvent3.functionName;
// Int型のパラメーターを格納
animEvent3.intParameter = 0;
//animEvent.time=arr [4];
// 設定した時間にイベントを送信
animEvent3.time = float.Parse (arr [i+1]);
Debug.Log("while loop animEvent3.time="+animEvent3.time);
if(arr [i+1]!=null){
Debug.Log("while loop arr["+i+"+1]="+arr [i+1]+" があるので実行");
//////////////////////////////////////
Crate();
///////////////////////////////////////
animEvent3.objectReferenceParameter=ScriptableObjectRef as UnityEngine.Object ;
// アニメーションイベントの追加
//clip.AddEvent(animEvent);
animEventsList1.Add(animEvent3);
}
Debug.Log("--------while loop i="+i+"----------------------end");
i=i+2;
Debug.Log("--------while loop i="+i+"--------------------next");
}
} catch {
//return null;
}
if(animEventsList1.Count!=0){
AnimationEvent[] animationEventArr1 = animEventsList1.ToArray();
//clip.events = animationEventArr1;
//AnimationClipRef.events= animationEventArr1;
AnimationUtility.SetAnimationEvents(AnimationClipRef, animationEventArr1);
//public static void SetAnimationEvents(AnimationClip clip, AnimationEvent[] events);
//Debug.Log ("clip.events =" + clip.events);
Debug.Log ("AnimationClipRef.events =" + AnimationClipRef.events);
}
/*
// wrapmode
try {
clip.wrapMode = (WrapMode) System.Enum.Parse(typeof(WrapMode), arr [3]);
} catch {
return null;
}
if (clip.wrapMode == WrapMode.Loop || clip.wrapMode == WrapMode.PingPong) {
clip.loop = true;
}
*/
Debug.Log ("ParseClipの返し値=clip=" + clip);
return clip;
}
/// <summary>
/// CreateScriptableObjectPrefub
/// </summary>
///
string[] labels = {"Data", "ScriptableObject"};
ScriptableObject ScriptableObjectRef;
void Crate ()
{
Debug.Log("--------Crate ----------------------");
Debug.Log("--Crate-- Selection.objects="+Selection.objects);
//foreach (Object selectedObject in Selection.objects) {
//Object modelAssetObject=(modelAsset)Object;
//selectedObject =
//selectedObject c = obj as TestClass;
//Debug.Log("Crate selectedObject="+selectedObject);
// get path
//string path = getSavePath (selectedObject);
string path = getSavePath (modelAsset,"AnimationEvent",".asset");
/////////////////////////////////////////////////////////////////////////////
/*
string SelectedObjectDir;
string selectedObjectStr = AssetDatabase.GetAssetPath (selectedObject);
Debug.Log ("--Crate-- selectedObjectStr=" + selectedObjectStr);
string[] modelDirArr;
modelDirArr=selectedObjectStr.Split("/"[0]);
string buildDir = modelDirArr[0];
for(int i = 1; i < modelDirArr.Length-1; i++)
{
buildDir = buildDir +"/"+ modelDirArr [i];
}
SelectedObjectDir = buildDir;
Debug.Log ("--Crate-- SelectedObjectDir="+SelectedObjectDir);
*/
////////////////////////////////////////////////////////////////////////////////
// create instance
//ScriptableObject obj = ScriptableObject.CreateInstance (selectedObject.name);
//AnimationClipEventData
ScriptableObject obj = ScriptableObject.CreateInstance ("AnimationClipEventData");
AssetDatabase.CreateAsset (obj, path);
// add label
ScriptableObject sobj = AssetDatabase.LoadAssetAtPath (path, typeof(ScriptableObject)) as ScriptableObject;
//sobj = AssetDatabase.LoadAssetAtPath (path, typeof(ScriptableObject)) as ScriptableObject;
AssetDatabase.SetLabels (sobj, labels);
EditorUtility.SetDirty (sobj);
ScriptableObjectRef = sobj;
//}
Debug.Log("--------Crate ----------end-----------");
}
AnimationClip AnimationClipRef;
void CreateAnimationClip(){
string path = getSavePath (modelAsset,"EditedAnimation",".anim");
AnimationClip newClip = new AnimationClip();
newClip.name = name;
AssetDatabase.CreateAsset(newClip, path);
// add label
AnimationClip obj = AssetDatabase.LoadAssetAtPath (path, typeof(AnimationClip)) as AnimationClip;
//sobj = AssetDatabase.LoadAssetAtPath (path, typeof(ScriptableObject)) as ScriptableObject;
AssetDatabase.SetLabels (obj, labels);
EditorUtility.SetDirty (obj);
AnimationClipRef = obj;
}
string getSavePath (Object selectedObject,string folderName,string filetype)
{
Debug.Log("------- getSavePath ----- selectedObject="+selectedObject);
//string objectName = selectedObject.name;
string objectName = selectedObject.name;
//string objectName = selectedObject.name+"_AnimationClipEventData";
if (filetype == ".asset") {
objectName = selectedObject.name+"_"+AnimationNameStr+"_"+AnimationClipEventNameStr;
}
if (filetype == ".anim") {
objectName =AnimationNameStr+"_event";
}
Debug.Log("------- getSavePath ----- objectName="+objectName);
//string dirPath = Path.GetDirectoryName (AssetDatabase.GetAssetPath (selectedObject));
////////////
string dirPath = CharaDir;
//string dirPath = CharaDir+"/AnimationClipEventData";
//////////
Debug.Log ("------ getSavePath -----dirPath="+dirPath);
//string path = string.Format ("{0}/{1}.asset", dirPath, objectName);
//string path = dirPath+"/"+objectName+".asset";
string path = dirPath+"/"+objectName+filetype;
//string AnimationEventDir = dirPath + "/AnimationEvent";
string MakeDir = dirPath +"/"+ folderName;
if (AssetDatabase.IsValidFolder (MakeDir)) {
Debug.Log (MakeDir + " ありました!");
} else {
Debug.Log (MakeDir+" ないのでつくりますです!");
string guid = AssetDatabase.CreateFolder(dirPath, folderName);
string newFolderPath = AssetDatabase.GUIDToAssetPath(guid);
Debug.Log (newFolderPath+" = newFolderPath 作りました!");
Debug.Log (MakeDir+" = MakeDir 作りました!");
}
//path= MakeDir+"/"+objectName+".asset";
path= MakeDir+"/"+objectName+filetype;
if (File.Exists (path)) {
for (int i = 1;; i++) {
//path = string.Format ("{0}/{1}({2}).asset", dirPath, objectName, i);
path=MakeDir+"/"+objectName+"_"+i+filetype;
if (!File.Exists (path))
break;
}
}
Debug.Log("------ getSavePath --------- path="+path);
return path;
}
////////////////////////////////////////////////////////////////////////////////
#region Static
/// <summary>
/// Open the tool window
/// </summary>
[MenuItem("Tools/Model/Animation Spliter")]
static public void OpenWindow ()
{
EditorWindow.GetWindow<ModelAnimationSpliter> (true, "Model Animation Spliter", true);
}
#endregion
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment