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