Unity 5:在编辑器中从C#脚本访问/修改AnimatorController

时间:2015-03-28 09:22:55

标签: c# unity3d unity3d-editor

我想编写一个编辑器菜单项,访问当前打开的动画控制器并销毁/创建/修改动画过渡。

基本上,我需要遍历当前打开的动画控制器中的所有动画状态/剪辑,并根据它们的名称创建特定的过渡并调整所有剪辑的回放速度。

我有这段代码:

        UnityEditorInternal.AnimatorController ac = GetComponent<Animator>().runtimeAnimatorController as UnityEditorInternal.AnimatorController;
        int numLayers = ac.layerCount;

        for(int i = 0; i<numLayers; i++){
            UnityEditorInternal.AnimatorControllerLayer layer = ac.GetLayer(i);
            Debug.Log ("Layer " + i + " is: " + layer.name + " and has " + layer.stateMachine.stateCount + " states");
            UnityEditorInternal.StateMachine sm = layer.stateMachine;
            for(int n = 0; n<sm.stateCount; n++){
                UnityEditorInternal.State state = sm.GetState(n);
                Debug.Log ("State " + state.name + " is " + state.GetHashCode());
                UnityEditorInternal.Transition[] list = sm.GetTransitionsFromState(state);
                for(int j = 0; j<list.Length; j++){
                    UnityEditorInternal.Transition transition = list[j];
                    Debug.Log ("Transition: " + transition.name + " is " + transition.GetHashCode());
                }
            }
        }

但是,它不能在Unity5上编译(最有可能为Unity 4编写),而且我不确定如何使用Unity 5函数获取当前打开的AnimatorController。

动画师控制器类似乎被定义为UnityEditor.Animations.AnimatorController,但我无法弄清楚如何抓住当前打开的一个。

有什么建议吗?

3 个答案:

答案 0 :(得分:3)

我已经设法通过检查器上下文菜单访问AnimatorController。这不是很方便(因为要处理整个控制器,我需要先在项目视图中选择它),但它可以工作。

public class AnimImportTools: MonoBehaviour{
//.....

    [MenuItem("CONTEXT/AnimatorController/Make transitions immediate")]
    private static void makeTransitionsImmediate(){
        UnityEditor.Animations.AnimatorController ac = Selection.activeObject as UnityEditor.Animations.AnimatorController;
        foreach(var layer in ac.layers){
            foreach(var curState in layer.stateMachine.states){
                foreach(var transition in curState.state.transitions){
                    transition.duration = 0.0f;
                    transition.exitTime = 1.0f;
                }
            }
        }
    }
//.....
}

如果有人知道更好的方法 - 即在更易于访问的位置添加菜单或从主菜单运行此脚本(并从那里获取当前打开的动画控制器),我很满意。

答案 1 :(得分:2)

感谢您的回答,我想出了以下内容:

    Animator animator = GetComponent<Animator>();
    string assetPath = AssetDatabase.GetAssetPath(animator.runtimeAnimatorController);
    AnimatorController controller = AssetDatabase.LoadAssetAtPath<AnimatorController>(assetPath);

这对我有用!

答案 2 :(得分:0)

在开放的Animator窗口中反射性地获取当前的AnimatorController的方式略显苛刻(应该集中注意力):

static AnimatorController GetCurrentController()
{
    AnimatorController controller = null;
    var tool = EditorWindow.focusedWindow;
    var toolType = tool.GetType();
    var controllerProperty = toolType.GetProperty("animatorController", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
    if (controllerProperty != null)
    {
        controller = controllerProperty.GetValue(tool, null) as AnimatorController;
    }
    else
    {
        Debug.Log("EditorWindow.focusedWindow " + tool + " does not contain animatorController",tool);
    }
    return controller;
}

适用于我当前的Unity版本(5.2.2p4)。

然后我将其与使用Selection.objects相结合,以找到选定的状态,以便用它制作我的工具。