#以外にそのまんまの例が見当たらなかった
完全にスクリプトでAnimationClipを自動生成するのではなく、エディタで編集したAnimationClipをスクリプトから整形したかったのですが、成功するまでにちょっと手間取ったのでメモ。
#BoxColliderの形状アニメーションを小数点第三位までで丸めるエディタ拡張の例
public class RoundBox : Editor
{
[MenuItem("Edit/Round Box %#r")]
private static void Do()
{
foreach(var i in Selection.gameObjects) {
foreach(var clip in AnimationUtility.GetAnimationClips(i)) {
foreach(var binding in AnimationUtility.GetCurveBindings(clip)) {
var curve = AnimationUtility.GetEditorCurve(clip, binding);
if(binding.propertyName.StartsWith("m_Offset.") || binding.propertyName.StartsWith("m_Size.")) {
for(int j = 0; j < curve.keys.Length; j++) {
var key = curve.keys[j];
key.value = ((int)(key.value * 1000.0f)) * 0.001f;
curve.MoveKey(j, key);
}
AnimationUtility.SetEditorCurve(clip, binding, curve);
}
}
}
}
}
}
#重要な点
既存のAnimationClipを編集するには以下の二点の手順が必要です。
- AnimationCurve.MoveKeyでAnimationCurveにキーフレーム値の変更を知らせる
- AnimationUtility.SetEditorCurveでAnimationClipにAnimationCurveの変更を知らせる
上記のソースで言えば curve.keys[j].value = newvalue;
などとしても文法エラーにはならず書けてしまうため、期待どおりに動作しそうに思ってしまうのですが、実際はMoveKey、SetEditorCurveを使用しないと値を変更しても無視されてしまいますよ、という話でした。
Keyframe は値型なので、curve.keys[j].value = newvalue;
が無意味なのはまぁそりゃそうかな、という話なんですが、AnimationUtility.GetEditorCurveはAnimationCurveのコピーを返してるんですかね?