Skip to content

Instantly share code, notes, and snippets.

@sh-akira
Created April 17, 2019 22:23
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sh-akira/8951dcc46aa89481f444d9ba0485a72e to your computer and use it in GitHub Desktop.
Save sh-akira/8951dcc46aa89481f444d9ba0485a72e to your computer and use it in GitHub Desktop.
Unityでanimファイルを指定秒数で分割して出力するエディタ拡張です
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEngine;
namespace akr.Unity.Editor.Animation
{
public class AnimationSplitter : EditorWindow
{
private AnimationClip animClip;
private float splitSeconds = 60.0f;
[MenuItem("akira/AnimationSplitter")]
private static void Create()
{
GetWindow<AnimationSplitter>("AnimationSplitter");
}
private void OnGUI()
{
animClip = EditorGUILayout.ObjectField("Animファイル", animClip, typeof(AnimationClip), true) as AnimationClip;
splitSeconds = EditorGUILayout.FloatField("分割秒数", splitSeconds);
if (GUILayout.Button("分割!"))
{
if (animClip != null)
{
var animEvents = AnimationUtility.GetAnimationEvents(animClip);
foreach (var animEvent in animEvents)
{
}
var curveBindings = AnimationUtility.GetCurveBindings(animClip);
var newClips = new List<AnimationClip>();
AnimationCurve tempCurve = null;
foreach (var curveBinding in curveBindings)
{
var animationCurve = AnimationUtility.GetEditorCurve(animClip, curveBinding);
int count = 0;
tempCurve = new AnimationCurve();
if (animationCurve.keys.Length > 0)
{
Keyframe lastFrame = animationCurve.keys[0];
foreach (var frame in animationCurve.keys)
{
while (newClips.Count <= count)
{
newClips.Add(new AnimationClip());
}
if (frame.time > (count + 1) * splitSeconds)
{
Debug.Log($"NewCurve start time:{tempCurve.keys.First().time} endtime:{tempCurve.keys.Last().time}");
//分割時間に合うように最後のキーを最終秒に同じ値で置く
var finalFrame = lastFrame;
finalFrame.time = splitSeconds;
tempCurve.AddKey(finalFrame);
AnimationUtility.SetEditorCurve(newClips[count], curveBinding, tempCurve);
//分割時間以上の空白がある場合0秒と分割秒地点に同じ値で置く
int nextcount = (int)(frame.time / splitSeconds);
if (nextcount - count > 1)
{
for (int tmpi = 0; tmpi < nextcount - count; tmpi++)
{
tempCurve = new AnimationCurve();
finalFrame = lastFrame;
finalFrame.time = 0.0f;
tempCurve.AddKey(finalFrame);
finalFrame = lastFrame;
finalFrame.time = splitSeconds;
tempCurve.AddKey(finalFrame);
while (newClips.Count <= count + tmpi + 1)
{
newClips.Add(new AnimationClip());
}
AnimationUtility.SetEditorCurve(newClips[count + tmpi + 1], curveBinding, tempCurve);
}
}
count = nextcount;
tempCurve = new AnimationCurve();
lastFrame.time -= splitSeconds * count;
if (lastFrame.time < 0.0f) lastFrame.time = 0.0f;
if (lastFrame.time > splitSeconds)
{
Debug.Log("ERROR time");
}
tempCurve.AddKey(lastFrame);
}
var currentFrame = frame;
currentFrame.time -= splitSeconds * count;
if (currentFrame.time > splitSeconds)
{
Debug.Log("ERROR time");
}
if (currentFrame.time < 0.0f) currentFrame.time = 0.0f;
tempCurve.AddKey(currentFrame);
lastFrame = frame;
}
Debug.Log($"NewCurve start time:{tempCurve.keys.First().time} endtime:{tempCurve.keys.Last().time}");
AnimationUtility.SetEditorCurve(newClips[count], curveBinding, tempCurve);
}
}
var path = "Assets/Resources/Split";
if (Directory.Exists(path) == false) Directory.CreateDirectory(path);
for (int num = 0; num < newClips.Count; num++)
{
var outputPath = path + $"/{animClip.name}_s{num + 1}.anim";
AssetDatabase.CreateAsset(newClips[num], AssetDatabase.GenerateUniqueAssetPath(outputPath));
AssetDatabase.SaveAssets();
}
AssetDatabase.Refresh();
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment