Unity 5: access/modify AnimatorController from C# script in editor

SigTerm picture SigTerm · Mar 28, 2015 · Viewed 9.2k times · Source

I'd like to write an editor menu item that accesses currently open animation controller and destroys/creates/modifies animation transitions.

Basically, I need to iterate through all animation states/clips in currently open animator controller, and based on their names create transitions with specific and adjust playback speed for all clips.

I have this code snippet:

        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());
                }
            }
        }

However, it does not compile on Unity5 (written for Unity 4, most likely), and I'm unsure how to get a hold of currently open AnimatorController using Unity 5 functions.

The animator controller class seems to be defined as UnityEditor.Animations.AnimatorController, but I can't figure out how to grab currently open one.

Any advice?

Answer

SigTerm picture SigTerm · Mar 28, 2015

I've managed to access AnimatorController via inspector context menu. That's not very convenient (because to process the whole controller, I need to select it in project view first), but it works.

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;
                }
            }
        }
    }
//.....
}

If someone knows better way to do it - i.e. add menu in more accessible location OR run this script from main menu (and get currently open animatorcontroller from there), I'm all ears.