Unity 5: доступ / изменение AnimatorController из C # скрипта в редакторе

1

Я хотел бы написать пункт меню редактора, который обращается к открытому в настоящее время контроллеру анимации и уничтожает/создает/изменяет переходы анимации.

В принципе, мне нужно перебирать все состояния анимации/клипы в текущем открытом аниматорном контроллере и на основе их имен создавать переходы со спецификой и настраивать скорость воспроизведения для всех клипов.

У меня есть этот фрагмент кода:

        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), и я не уверен, как получить доступный в настоящее время AnimatorController, используя функции Unity 5.

Класс контроллера аниматора, как представляется, определяется как UnityEditor.Animations.AnimatorController, но я не могу понять, как захватить в настоящее время открытый.

Любой совет?

Теги:
unity3d
unity3d-editor

3 ответа

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

Если кто-то знает лучший способ сделать это - то есть добавить меню в более доступное местоположение или запустить этот скрипт из главного меню (и получить от него в настоящее время открытый анимационный контроллер), я все уши.

2

Благодаря вашему ответу я придумал следующее:

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

Это работает для меня!

0

Немного хакерский способ получить рефлексивно получать текущий AnimatorController в открытом окне Animator (он должен быть сфокусирован):

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, чтобы найти выбранные состояния, чтобы сделать мои инструменты с ним.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню