[Unity Editor]将Animation Clip嵌入A

2020-06-11  本文已影响0人  _Walker__

参考文章:
Unity中将Animation Clip嵌入Animator Controller的方法

  我要做这个工具的原因,跟参考文章类似,偶然发现项目中有的Clip跟Controller是一个整体,这种方式比较方便管理简单动画,所以搜了下创建方案。
  这里又造轮子,主要是拓展功能与修复参考文章的Bug,代码都在下面,拓展的内容是:

[MenuItem("Assets/Anime/Nest Clips in Controller")]
public static void NestAnimClips()
{
    AnimatorController ctrl = Selection.activeObject as AnimatorController;
    if (null == ctrl) return;

    AnimationClip[] clips = ctrl.animationClips;
    for (int i = 0; i < clips.Length; ++i)
    {
        AnimationClip clip = clips[i];
        var assetPath = AssetDatabase.GetAssetPath(clip);
        if (assetPath.EndsWith(".anim"))
        {
            AnimationClip newClip = Object.Instantiate(clip);
            newClip.name = clip.name;
            AssetDatabase.AddObjectToAsset(newClip, ctrl);
            AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(clip));
            ReplaceStateMotion(ctrl, clip, newClip);
        }
    }
    AssetDatabase.SaveAssets();
}

[MenuItem("Assets/Anime/Remove Nest Clip")]
public static void RemoveNestAnimClip()
{
    AnimationClip clip = Selection.activeObject as AnimationClip;
    if(clip == null) return;
    string ctrlPath = AssetDatabase.GetAssetPath(clip);
    // 保证只移除嵌套的clip,否则会导致动画状态错乱
    if(!ctrlPath.EndsWith(".controller")) return;

    AssetDatabase.RemoveObjectFromAsset(clip);
    Object.DestroyImmediate(clip);
    AssetDatabase.SaveAssets();
}


/// <summary>
/// 替换动画控制器中使用的Clip
/// </summary>
public static void ReplaceStateMotion(AnimatorController ctrl, AnimationClip oldClip, AnimationClip newClip, bool replaceAll=false)
{
    foreach (AnimatorControllerLayer layer in ctrl.layers)
    {
        foreach (ChildAnimatorState childState in layer.stateMachine.states)
        {
            if (childState.state.motion == oldClip)
            {
                ctrl.SetStateEffectiveMotion(childState.state, newClip);
                if (!replaceAll) return;
            }
        }
    }
}
上一篇下一篇

猜你喜欢

热点阅读