コード例 #1
0
    private AnimatorMotion ReadNodeFromSerializedNodes(AnimatorState state, int index)
    {
        SerializableMotion    serialisedBo = state.serialisedMotions[index];
        List <AnimatorMotion> children     = new List <AnimatorMotion>();

        for (int i = 0; i < serialisedBo.childCount; i++)
        {
            children.Add(ReadNodeFromSerializedNodes(state, serialisedBo.indexOfFirstChild + i));
        }

        if (serialisedBo.isAnimation)
        {
            AnimatorClip anim = new AnimatorClip();
            anim.name      = serialisedBo.name;
            anim.data      = serialisedBo.animatorData;
            anim.treeIndex = index;
            return(anim);
        }
        else
        {
            AnimatorBlendTree blend = new AnimatorBlendTree();
            blend.name                 = serialisedBo.name;
            blend.positions            = serialisedBo.positions;
            blend.blendParameterIndex  = serialisedBo.blendParameterIndex;
            blend.blendParameterIndexY = serialisedBo.blendParameterIndexY;
            blend.resolution           = serialisedBo.resolution;
            blend.weightTable          = DeserializeWeightTable(serialisedBo.weightTable);
            blend.motions              = children.ToArray();
            blend.motionCount          = children.Count;
            blend.weights              = new FP[blend.motionCount];
            blend.treeIndex            = index;
            return(blend);
        }
    }
コード例 #2
0
    public void SerialiseObject(AnimatorState state, AnimatorMotion mo = null)
    {
        SerializableMotion serialisedBo = new SerializableMotion();

        if (mo == null)//initial blend object will be patched in on first call
        {
            mo = state.motion;
        }

        if (mo is AnimatorClip)
        {
            AnimatorClip anim = mo as AnimatorClip;
            serialisedBo.isAnimation       = true;
            serialisedBo.name              = anim.data.clipName;
            serialisedBo.animatorData      = anim.data;
            serialisedBo.childCount        = 0;
            serialisedBo.indexOfFirstChild = state.serialisedMotions.Count + 1;

            state.serialisedMotions.Add(serialisedBo);
        }

        if (mo is AnimatorBlendTree)
        {
            AnimatorBlendTree blend = mo as AnimatorBlendTree;
            serialisedBo.isAnimation          = false;
            serialisedBo.name                 = blend.name;//string.Format("Tree of {0}", blend.motionCount);
            serialisedBo.positions            = blend.positions;
            serialisedBo.blendParameterIndex  = blend.blendParameterIndex;
            serialisedBo.blendParameterIndexY = blend.blendParameterIndexY;
            serialisedBo.weightTable          = SerializeWeightTable(blend.weightTable);
            serialisedBo.resolution           = blend.resolution;

            serialisedBo.childCount        = blend.motionCount;
            serialisedBo.indexOfFirstChild = state.serialisedMotions.Count + 1;

            state.serialisedMotions.Add(serialisedBo);
            foreach (var child in blend.motions)
            {
                SerialiseObject(state, child);
            }
        }
    }
コード例 #3
0
    public override void OnInspectorGUI()
    {
        var graph = asset.Settings;

        if (GUILayout.Button("Import Mecanim Controller"))
        {
            ExportAnimations.CreateAsset(asset, (UnityEditor.Animations.AnimatorController)asset.controller);

            EditorUtility.SetDirty(asset);
            AssetDatabase.Refresh();
        }

        if (graph != null && graph.layers != null)
        {
            int layerCount = graph.layers.Length;
            if (layerCount > 0)
            {
                string[] layerNames = new string[layerCount];
                for (int l = 0; l < layerCount; l++)
                {
                    layerNames[l] = graph.layers[l].name;
                }
                selectedLayer = GUILayout.Toolbar(selectedLayer, layerNames);
                AnimatorLayer layer = graph.layers[selectedLayer];

                if (layer != null)
                {
                    int stateCount = layer.states.Length;

                    if (stateCount > 0)
                    {
                        string[] stateNames = new string[stateCount];
                        for (int s = 0; s < stateCount; s++)
                        {
                            stateNames[s] = layer.states[s].name;
                        }
                        selectedState = GUILayout.Toolbar(selectedState, stateNames);
                        AnimatorState state = layer.states[selectedState];

                        if (state != null)
                        {
                            EditorGUILayout.BeginVertical("box");

                            EditorGUILayout.LabelField("State");
                            EditorGUILayout.LabelField(state.name);
                            EditorGUILayout.LabelField(string.Format("Is Default: {0}", state.isDefault));
                            if (state.motion != null)
                            {
                                EditorGUILayout.LabelField(string.Format("Is Blend Tree: {0}", state.motion.isTree));

                                if (!state.motion.isTree)
                                {
                                    AnimatorClip motion = state.motion as AnimatorClip;
                                    AnimationClipGui(motion);
                                }
                                else
                                {
                                    AnimatorBlendTree motion = state.motion as AnimatorBlendTree;
                                    string[]          blends = new string[motion.motionCount];
                                    for (int b = 0; b < motion.motionCount; b++)
                                    {
                                        blends[b] = motion.motions[b].name;
                                    }
                                    selectedBlend = SelectionField(blends, selectedBlend, 2);

                                    AnimatorClip clip = motion.motions[selectedBlend] as AnimatorClip;
                                    AnimationClipGui(clip);
                                }
                            }
                            else
                            {
                                EditorGUILayout.LabelField("No Motion Set");
                            }

                            EditorGUILayout.Space();
                            EditorGUILayout.LabelField("Transitions");
                            int transitionCount = state.transitions.Length;
                            for (int t = 0; t < transitionCount; t++)
                            {
                                EditorGUILayout.BeginVertical("Box");

                                AnimatorTransition transition = state.transitions[t];

                                EditorGUILayout.LabelField(string.Format("{0}. {1}", transition.index, transition.name));
                                EditorGUILayout.LabelField(string.Format("Duration: {0} sec", transition.duration.AsFloat));
                                EditorGUILayout.LabelField(string.Format("Has Exit Time: {0}", transition.hasExitTime));
                                EditorGUILayout.LabelField(string.Format("Exit Time: {0} sec", transition.exitTime.AsFloat));
                                EditorGUILayout.LabelField(string.Format("Destination State (Hash): {0} ({1})", transition.destinationStateName, transition.destinationStateId));
                                EditorGUILayout.LabelField(string.Format("Offset: {0} sec", transition.offset.AsFloat));

                                int conditionCount = transition.conditions.Length;
                                for (int c = 0; c < conditionCount; c++)
                                {
                                    EditorGUILayout.BeginVertical("Box");
                                    AnimatorCondition condition = transition.conditions[c];
                                    AnimatorVariable  variable  = graph.variables[graph.VariableIndex(condition.variableName)];

                                    string conditionMode = "";
                                    switch (condition.mode)
                                    {
                                    case AnimatorCondition.Modes.Equals:
                                        conditionMode = "==";
                                        break;

                                    case AnimatorCondition.Modes.Greater:
                                        conditionMode = ">";
                                        break;

                                    case AnimatorCondition.Modes.If:
                                        conditionMode = "is true";
                                        break;

                                    case AnimatorCondition.Modes.IfNot:
                                        conditionMode = "is false";
                                        break;

                                    case AnimatorCondition.Modes.Less:
                                        conditionMode = "<";
                                        break;

                                    case AnimatorCondition.Modes.NotEqual:
                                        conditionMode = "!=";
                                        break;
                                    }

                                    string threshold = "";
                                    switch (variable.type)
                                    {
                                    case AnimatorVariable.VariableType.FP:
                                        threshold = condition.thresholdFp.AsFloat.ToString();
                                        break;

                                    case AnimatorVariable.VariableType.Int:
                                        threshold = condition.thresholdInt.ToString();
                                        break;
                                    }

                                    EditorGUILayout.LabelField(string.Format("\"{0}\" - {1} - {2}", condition.variableName, conditionMode, threshold));

                                    EditorGUILayout.EndVertical();
                                }

                                EditorGUILayout.EndVertical();
                            }

                            EditorGUILayout.EndVertical();
                        }
                    }
                }
            }
        }

        base.OnInspectorGUI();
    }
コード例 #4
0
    /*
     * [MenuItem("Assets/Export Mecanim Animation Controller", false, 301)]
     * private static void CreateAnimatorFile() {
     * var animatorController = Selection.activeObject as AnimatorController;
     * if (animatorController == null) {
     *  return;
     * }
     *
     * CreateAsset(animatorController);
     * }
     *
     * [MenuItem("Assets/Export Mecanim Animation Controller", true)]
     * private static bool CreateAnimatorController() {
     * return Selection.activeObject is AnimatorController;
     * }
     */

    //  public static AnimatorGraphAsset Fetch(string name) {
    //    AnimatorGraphAsset output = null;

    //#if UNITY_EDITOR
    //    string pathToAnimationResource = "Assets/Resources/DB/Animator/";
    //    string animationFilePath = pathToAnimationResource + name + ".asset";
    //    output = UnityEditor.AssetDatabase.LoadAssetAtPath(animationFilePath, typeof(AnimatorGraphAsset)) as AnimatorGraphAsset;

    //    if (output == null) {
    //      output = CreateInstance<AnimatorGraphAsset>();
    //      animationFilePath = UnityEditor.AssetDatabase.GenerateUniqueAssetPath(animationFilePath);
    //      UnityEditor.AssetDatabase.CreateAsset(output, animationFilePath);
    //      UnityEditor.AssetDatabase.SaveAssets();
    //      UnityEditor.AssetDatabase.Refresh();
    //    }
    //#endif

    //    if (output != null) {
    //      if (output.Settings == null)
    //        output.Settings = new AnimatorGraph();
    //    }

    //    return output;
    //  }

    public static void CreateAsset(AnimatorGraphAsset dataAsset, AnimatorController controller)
    {
        if (!controller)
        {
            return;
        }

        if (!dataAsset)
        {
            return;
        }

        QuantumRunner.Init();//make sure we can get debug calls from Quantum
        dataAsset.controller = controller;
        int weightTableResolution = (int)dataAsset.weight_table_resolution;
        int variableCount         = controller.parameters.Length;

        dataAsset.Settings.variables = new AnimatorVariable[variableCount];

        //Mecanim Parameters/Variables
        //make a dictionary of paramets by name for use when extracting conditions for transitions
        Dictionary <string, AnimatorControllerParameter> parameterDic = new Dictionary <string, AnimatorControllerParameter>();

        for (int v = 0; v < variableCount; v++)
        {
            AnimatorControllerParameter parameter = controller.parameters[v];
            parameterDic.Add(parameter.name, parameter);
            AnimatorVariable newVariable = new AnimatorVariable();

            newVariable.name  = parameter.name;
            newVariable.index = v;
            switch (parameter.type)
            {
            case AnimatorControllerParameterType.Bool:
                newVariable.type        = AnimatorVariable.VariableType.Bool;
                newVariable.defaultBool = parameter.defaultBool;
                break;

            case AnimatorControllerParameterType.Float:
                newVariable.type      = AnimatorVariable.VariableType.FP;
                newVariable.defaultFp = FP.FromFloat_UNSAFE(parameter.defaultFloat);
                break;

            case AnimatorControllerParameterType.Int:
                newVariable.type       = AnimatorVariable.VariableType.Int;
                newVariable.defaultInt = parameter.defaultInt;
                break;

            case AnimatorControllerParameterType.Trigger:
                newVariable.type = AnimatorVariable.VariableType.Trigger;
                break;
            }

            dataAsset.Settings.variables[v] = newVariable;
        }

        //Mecanim State Graph
        int layerCount = controller.layers.Length;

        dataAsset.clips.Clear();
        dataAsset.Settings.layers = new AnimatorLayer[layerCount];
        for (int l = 0; l < layerCount; l++)
        {
            AnimatorLayer newLayer = new AnimatorLayer();
            newLayer.name = controller.layers[l].name;
            newLayer.id   = l;

            int stateCount = controller.layers[l].stateMachine.states.Length;
            newLayer.states = new Quantum.AnimatorState[stateCount + 1];//additional element for the any state
            Dictionary <UnityEditor.Animations.AnimatorState, Quantum.AnimatorState> stateDictionary = new Dictionary <AnimatorState, Quantum.AnimatorState>();

            for (int s = 0; s < stateCount; s++)
            {
                UnityEditor.Animations.AnimatorState state = controller.layers[l].stateMachine.states[s].state;
                Quantum.AnimatorState newState             = new Quantum.AnimatorState();
                newState.name        = state.name;
                newState.id          = state.nameHash;
                newState.isDefault   = controller.layers[l].stateMachine.defaultState == state;
                newState.speed       = FP.FromFloat_UNSAFE(state.speed);
                newState.cycleOffset = FP.FromFloat_UNSAFE(state.cycleOffset);

                if (state.motion != null)
                {
                    AnimationClip clip = state.motion as AnimationClip;
                    if (clip != null)
                    {
                        dataAsset.clips.Add(clip);
                        AnimatorClip newClip = new AnimatorClip();
                        newClip.name    = state.motion.name;
                        newClip.data    = Extract(clip);
                        newState.motion = newClip;
                    }
                    else
                    {
                        BlendTree tree = state.motion as BlendTree;
                        if (tree != null)
                        {
                            int childCount = tree.children.Length;

                            AnimatorBlendTree newBlendTree = new AnimatorBlendTree();
                            newBlendTree.name        = state.motion.name;
                            newBlendTree.motionCount = childCount;
                            newBlendTree.motions     = new AnimatorMotion[childCount];
                            newBlendTree.positions   = new FPVector2[childCount];
                            newBlendTree.weights     = new FP[childCount];

                            string parameterXname = tree.blendParameter;
                            string parameterYname = tree.blendParameterY;
                            for (int v = 0; v < variableCount; v++)
                            {
                                if (controller.parameters[v].name == parameterXname)
                                {
                                    newBlendTree.blendParameterIndex = v;
                                }
                                if (controller.parameters[v].name == parameterYname)
                                {
                                    newBlendTree.blendParameterIndexY = v;
                                }
                            }

                            for (int c = 0; c < childCount; c++)
                            {
                                ChildMotion   cMotion = tree.children[c];
                                AnimationClip cClip   = cMotion.motion as AnimationClip;
                                newBlendTree.positions[c] = new FPVector2(FP.FromFloat_UNSAFE(cMotion.position.x), FP.FromFloat_UNSAFE(cMotion.position.y));

                                if (cClip != null)
                                {
                                    dataAsset.clips.Add(cClip);
                                    AnimatorClip newClip = new AnimatorClip();
                                    newClip.data            = Extract(cClip);
                                    newClip.name            = newClip.clipName;
                                    newBlendTree.motions[c] = newClip;
                                }
                            }


                            FP val = FP._0 / 21;
                            newBlendTree.CalculateWeightTable(weightTableResolution);

                            newState.motion = newBlendTree;
                        }
                    }
                }
                newLayer.states[s] = newState;

                stateDictionary.Add(state, newState);
            }

            //State Transistions
            //once the states have all been created
            //we'll hook up the transitions
            for (int s = 0; s < stateCount; s++)
            {
                UnityEditor.Animations.AnimatorState state = controller.layers[l].stateMachine.states[s].state;
                Quantum.AnimatorState newState             = newLayer.states[s];
                int transitionCount = state.transitions.Length;
                newState.transitions = new Quantum.AnimatorTransition[transitionCount];
                for (int t = 0; t < transitionCount; t++)
                {
                    AnimatorStateTransition transition = state.transitions[t];
                    if (!stateDictionary.ContainsKey(transition.destinationState))
                    {
                        continue;
                    }
                    Quantum.AnimatorTransition newTransition = new Quantum.AnimatorTransition();
                    newTransition.index                = t;
                    newTransition.name                 = string.Format("{0} to {1}", state.name, transition.destinationState.name);
                    newTransition.duration             = FP.FromFloat_UNSAFE(transition.duration * state.motion.averageDuration);
                    newTransition.hasExitTime          = transition.hasExitTime;
                    newTransition.exitTime             = FP.FromFloat_UNSAFE(transition.exitTime * state.motion.averageDuration);
                    newTransition.offset               = FP.FromFloat_UNSAFE(transition.offset * transition.destinationState.motion.averageDuration);
                    newTransition.destinationStateId   = stateDictionary[transition.destinationState].id;
                    newTransition.destinationStateName = stateDictionary[transition.destinationState].name;
                    newTransition.canTransitionToSelf  = transition.canTransitionToSelf;


                    int conditionCount = transition.conditions.Length;
                    newTransition.conditions = new Quantum.AnimatorCondition[conditionCount];
                    for (int c = 0; c < conditionCount; c++)
                    {
                        UnityEditor.Animations.AnimatorCondition condition = state.transitions[t].conditions[c];

                        if (!parameterDic.ContainsKey(condition.parameter))
                        {
                            continue;
                        }
                        AnimatorControllerParameter parameter    = parameterDic[condition.parameter];
                        Quantum.AnimatorCondition   newCondition = new Quantum.AnimatorCondition();

                        newCondition.variableName = condition.parameter;
                        newCondition.mode         = (Quantum.AnimatorCondition.Modes)condition.mode;

                        switch (parameter.type)
                        {
                        case AnimatorControllerParameterType.Float:
                            newCondition.thresholdFp = FP.FromFloat_UNSAFE(condition.threshold);
                            break;

                        case AnimatorControllerParameterType.Int:
                            newCondition.thresholdInt = Mathf.RoundToInt(condition.threshold);
                            break;
                        }

                        newTransition.conditions[c] = newCondition;
                    }

                    newState.transitions[t] = newTransition;
                }
            }

            //Create Any State
            Quantum.AnimatorState anyState = new Quantum.AnimatorState();
            anyState.name  = "Any State";
            anyState.id    = anyState.name.GetHashCode();
            anyState.isAny = true;//important for this one
            AnimatorStateTransition[] anyStateTransitions = controller.layers[l].stateMachine.anyStateTransitions;
            int anyStateTransitionCount = anyStateTransitions.Length;
            anyState.transitions = new Quantum.AnimatorTransition[anyStateTransitionCount];
            for (int t = 0; t < anyStateTransitionCount; t++)
            {
                AnimatorStateTransition transition = anyStateTransitions[t];
                if (!stateDictionary.ContainsKey(transition.destinationState))
                {
                    continue;
                }
                Quantum.AnimatorTransition newTransition = new Quantum.AnimatorTransition();
                newTransition.index                = t;
                newTransition.name                 = string.Format("Any State to {0}", transition.destinationState.name);
                newTransition.duration             = FP.FromFloat_UNSAFE(transition.duration);
                newTransition.hasExitTime          = transition.hasExitTime;
                newTransition.exitTime             = FP._1;
                newTransition.offset               = FP.FromFloat_UNSAFE(transition.offset * transition.destinationState.motion.averageDuration);
                newTransition.destinationStateId   = stateDictionary[transition.destinationState].id;
                newTransition.destinationStateName = stateDictionary[transition.destinationState].name;
                newTransition.canTransitionToSelf  = transition.canTransitionToSelf;

                int conditionCount = transition.conditions.Length;
                newTransition.conditions = new Quantum.AnimatorCondition[conditionCount];
                for (int c = 0; c < conditionCount; c++)
                {
                    UnityEditor.Animations.AnimatorCondition condition = anyStateTransitions[t].conditions[c];

                    if (!parameterDic.ContainsKey(condition.parameter))
                    {
                        continue;
                    }
                    AnimatorControllerParameter parameter    = parameterDic[condition.parameter];
                    Quantum.AnimatorCondition   newCondition = new Quantum.AnimatorCondition();

                    newCondition.variableName = condition.parameter;
                    newCondition.mode         = (Quantum.AnimatorCondition.Modes)condition.mode;

                    switch (parameter.type)
                    {
                    case AnimatorControllerParameterType.Float:
                        newCondition.thresholdFp = FP.FromFloat_UNSAFE(condition.threshold);
                        break;

                    case AnimatorControllerParameterType.Int:
                        newCondition.thresholdInt = Mathf.RoundToInt(condition.threshold);
                        break;
                    }

                    newTransition.conditions[c] = newCondition;
                }

                anyState.transitions[t] = newTransition;
            }
            newLayer.states[stateCount] = anyState;

            dataAsset.Settings.layers[l] = newLayer;
        }

        EditorUtility.SetDirty(dataAsset);
    }