Пример #1
0
        /// <summary>
        /// 更新blendTree motion
        /// </summary>
        /// <param name="_value"></param>
        /// <param name="_childIndex"></param>
        /// <param name="_motion"></param>
        public static void OverrideBlendTree(BlendTree _value, int _childIndex, Motion _motion)
        {
            List <ChildMotion> childMotions = new List <ChildMotion>();

            _value.children.ToList().ForEach(child => childMotions.Add(child));

            for (int i = _value.children.Length - 1; i >= 0; i--)
            {
                _value.RemoveChild(i);
            }

            for (int i = 0; i < childMotions.Count; i++)
            {
                if (i == _childIndex)
                {
                    _value.AddChild(_motion);
                }
                else
                {
                    _value.AddChild(childMotions[i].motion);
                }
            }

            for (int i = 0; i < _value.children.Length; i++)
            {
                _value.children[i] = childMotions[i];
            }
        }
        public static void OverrideBlendTree(BlendTree value, int childIndex, Motion newMotion)
        {
            List <ChildMotion> cloneMotions = new List <ChildMotion>();

            value.children.ToList().ForEach(i => cloneMotions.Add(i));

            for (int i = value.children.Length - 1; i >= 0; i--)
            {
                value.RemoveChild(i);
            }

            for (int i = 0; i < cloneMotions.Count; i++)
            {
                if (i == childIndex)
                {
                    value.AddChild(newMotion);
                }
                else
                {
                    value.AddChild(cloneMotions[i].motion);
                }
            }

            for (int i = 0; i < value.children.Length; i++)
            {
                value.children[i] = cloneMotions[i];
            }
        }
    /// <summary>
    /// Show how to add a 1D tree
    /// </summary>
    private void CreateMove()
    {
        // Load Animation
        AnimationClip walkClip = AnimatorFactoryUtil.LoadAnimClip(AnimationPath + "Walk.FBX");
        AnimationClip runClip  = AnimatorFactoryUtil.LoadAnimClip(AnimationPath + "Run.FBX");

        // new a tree
        BlendTree tree = new BlendTree();

        // Set blendtree parameters
        tree.name      = "Move";
        tree.blendType = BlendTreeType.Simple1D;
        tree.useAutomaticThresholds = true;
        tree.minThreshold           = 0f;
        tree.maxThreshold           = 1f;
        tree.blendParameter         = "FloatA";

        // Add clip to BlendTree
        tree.AddChild(walkClip, 0f);
        tree.AddChild(runClip, 1f);

        // Add tree to controller asset
        if (AssetDatabase.GetAssetPath(productController) != string.Empty)
        {
            AssetDatabase.AddObjectToAsset(tree, AssetDatabase.GetAssetPath(productController));
        }

        // add tree state & set state motion
        stateMove        = baseLayerMachine.AddState(tree.name, new Vector3(600f, 0f));
        stateMove.motion = tree;
    }
        public void Build()
        {
            var expName    = _expressionInfo.ExpressionName;
            var controller = _expressionInfo.Controller;

            AnimatorControllerLayer layer = AnimUtility.AddLayer(controller, expName, _dirtyAssets);

            controller.AddParameter(expName, AnimatorControllerParameterType.Float);

            AnimatorStateMachine stateMachine = layer.stateMachine;
            var           empty = AnimUtility.AddState(stateMachine, "Empty", true, _dirtyAssets);
            AnimatorState state = AnimUtility.AddState(stateMachine, expName, false, _dirtyAssets);

            var blendTree = new BlendTree
            {
                name           = "BlendTree",
                blendParameter = expName,
            };

            state.motion = blendTree;
            _dirtyAssets.Add(blendTree);

            var materials = GetMaterials().ToList();

            var directory = $"{_expressionInfo.AnimationsFolder.GetPath()}/{expName}";
            var emptyClip = AnimUtility.CreateAnimation(directory, $"{expName}_{empty}", _dirtyAssets);

            blendTree.AddChild(emptyClip);

            for (var i = 0; i < materials.Count; i++)
            {
                Material material      = materials[i];
                var      animationClip = AnimUtility.CreateAnimation(directory, $"{expName} [{i}] {material.name}", _dirtyAssets);
                AnimUtility.SetObjectReferenceKeyframe(animationClip, _renderer, $"m_Materials.Array.data[{_materialSlot}]", material, _dirtyAssets);
                blendTree.AddChild(animationClip);
                _dirtyAssets.Add(animationClip);
            }

            AnimatorStateTransition anyStateTransition = stateMachine.AddAnyStateTransition(state);

            anyStateTransition.AddCondition(AnimatorConditionMode.Greater, 0.01f, expName);

            AnimatorStateTransition exitTransition = state.AddExitTransition(false);

            exitTransition.AddCondition(AnimatorConditionMode.Less, 0.01f, expName);

            AnimUtility.AddVRCExpressionsParameter(_expressionInfo.AvatarDescriptor, VRCExpressionParameters.ValueType.Float, expName, _dirtyAssets);
            if (_expressionInfo.Menu != null)
            {
                AnimUtility.AddVRCExpressionsMenuControl(_expressionInfo.Menu, ControlType.RadialPuppet, expName, _dirtyAssets);
            }

            _dirtyAssets.SetDirty();
            controller.AddObjectsToAsset(stateMachine, empty, state, anyStateTransition, exitTransition, blendTree);
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();
        }
Пример #5
0
        static BlendTree CreateChild(string name, string FirstMotion, string SecondMotion, string parameterName)
        {
            BlendTree result = new BlendTree();

            result.name      = name;
            result.blendType = BlendTreeType.Simple1D;
            result.AddChild((Motion)LoadFDSAsset <Motion>(FirstMotion));
            result.AddChild((Motion)LoadFDSAsset <Motion>(SecondMotion));
            result.blendParameter = parameterName;
            return(result);
        }
Пример #6
0
    // 歩行モーションを想定したBlendTree作成.
    private static BlendTree CreateWalkBlendTree(string directory)
    {
        Debug.Log(" >Load Directory=" + directory);

        var blendTree = new BlendTree();

        blendTree.name = "Blend Tree";
        blendTree.useAutomaticThresholds = false;
        blendTree.blendParameter         = "Degree";

        // 指定ディレクトリに格納されているアニメーションクリップを全て読み込み.BlendTreeを作成.
        AnimationClip degree0Anim = null;   // ディクリー角0度のアニメーション.
        var           animPaths   = Directory.GetFiles(directory);
        var           threshold   = 270f;

        foreach (var animPath in animPaths)
        {
            if (animPath.IndexOf(".meta") > 0)
            {
                continue;   // メタファイル無視.
            }
            var anim = AssetDatabase.LoadAssetAtPath <AnimationClip>(animPath);
            blendTree.AddChild(anim, threshold);

            // ディクリー角0度のアニメーションは360度の時にも使用するものになるので予め保持しておき一通り設定し終わった後に設定する.
            if (threshold == 0)
            {
                degree0Anim = anim;
            }
            // 0〜360度の角度で切り替わるBlendTreeアニメーションを形成する.
            threshold -= 45f;
            if (threshold < 0)
            {
                threshold += 360f;
            }

            Debug.Log("  >Load AnimationClip=" + anim);
        }
        // 360度の時にもアニメーションを適用.
        blendTree.AddChild(degree0Anim, 360f);

        // BlendTreeもアセットとして作成し保存しておかないとシーン再生のタイミングで消える.
        var name = "WalkBlendTree_" + directory.Remove(0, PATH_ROOT.Length);

        AssetDatabase.CreateAsset(blendTree, PATH_OUTPUT + "/BlendTreeTemp/" + name);       // なんでもいいので一度Assetとして保存しておかないとEditor上の出来事になってしまいシーン再生時にBlendTreeが消える.
        AssetDatabase.SaveAssets();
//        AssetDatabase.DeleteAsset("Assets/"+blendTree.name);            // なので一度作成して、セーブした後不要な筈のBlendTree仮Assetデータを削除する.これで消えないようになる.....が、ここでこれを消すと別のPCでビルドする際などBlendTreeの見えない何かがコミットされずに上手くいかない.

        return(blendTree);
    }
Пример #7
0
        // Taken from here: https://gist.github.com/phosphoer/93ca8dcbf925fc006e4e9f6b799c13b0
        private static BlendTree CloneBlendTree(BlendTree newTree, BlendTree oldTree)
        {
            // Create a child tree in the destination parent, this seems to be the only way to correctly
            // add a child tree as opposed to AddChild(motion)
            BlendTree pastedTree = newTree is null ? new BlendTree() : newTree.CreateBlendTreeChild(newTree.maxThreshold);

            pastedTree.name                   = oldTree.name;
            pastedTree.blendType              = oldTree.blendType;
            pastedTree.blendParameter         = oldTree.blendParameter;
            pastedTree.blendParameterY        = oldTree.blendParameterY;
            pastedTree.minThreshold           = oldTree.minThreshold;
            pastedTree.maxThreshold           = oldTree.maxThreshold;
            pastedTree.useAutomaticThresholds = oldTree.useAutomaticThresholds;

            // Recursively duplicate the tree structure
            // Motions can be directly added as references while trees must be recursively to avoid accidental sharing
            foreach (var child in oldTree.children)
            {
                if (child.motion is BlendTree tree)
                {
                    var childTree = CloneBlendTree(pastedTree, tree);
                    // need to save the blend tree into the animator
                    childTree.hideFlags = HideFlags.HideInHierarchy;
                    AssetDatabase.AddObjectToAsset(childTree, _assetPath);
                }
                else
                {
                    pastedTree.AddChild(child.motion);
                }
            }

            return(pastedTree);
        }
    /// <summary>
    /// Show how to add 2D tree
    /// </summary>
    private void CreateJump()
    {
        // Load Animation
        string        fbxPath        = AnimationPath + "IdleJumpUp.FBX";
        AnimationClip fallClip       = AnimatorFactoryUtil.LoadAnimClip(fbxPath, "HumanoidFall");
        AnimationClip idleJumpUpClip = AnimatorFactoryUtil.LoadAnimClip(fbxPath, "HumanoidIdleJumpUp");
        AnimationClip jumpUpClip     = AnimatorFactoryUtil.LoadAnimClip(fbxPath, "HumanoidJumpUp");
        AnimationClip midAirClip     = AnimatorFactoryUtil.LoadAnimClip(fbxPath, "HumanoidMidAir");

        // create a tree
        BlendTree tree = new BlendTree();

        // Set blendtree parameters
        tree.name      = "Jump";
        tree.blendType = BlendTreeType.FreeformDirectional2D;
        tree.useAutomaticThresholds = true;
        tree.minThreshold           = 0f;
        tree.maxThreshold           = 1f;
        tree.blendParameter         = "FloatA";
        tree.blendParameterY        = "FloatB";

        // Add clip to BlendTree
        tree.AddChild(fallClip, new Vector2(0f, 0f));
        tree.AddChild(idleJumpUpClip, new Vector2(0f, 1f));
        tree.AddChild(jumpUpClip, new Vector2(1f, 0f));
        tree.AddChild(midAirClip, new Vector2(-1f, 0f));

        // Add tree to controller asset
        if (AssetDatabase.GetAssetPath(productController) != string.Empty)
        {
            AssetDatabase.AddObjectToAsset(tree, AssetDatabase.GetAssetPath(productController));
        }

        // add tree state & set state motion
        stateJump        = baseLayerMachine.AddState(tree.name, new Vector3(300f, -100f));
        stateJump.motion = tree;
    }
        AnimatorState AddBlendTree(AnimatorController controller, AnimatorStateMachine sm, int layer, HashSet <ClipIDPair> clipIDPairs, string name, string mirrorParam, string speedParam, string blendParam)
        {
            AnimatorState state     = sm.AddState(name);
            BlendTree     blendTree = new BlendTree();

            AssetDatabase.AddObjectToAsset(blendTree, controller);
            blendTree.name                   = name;
            blendTree.hideFlags              = HideFlags.HideInHierarchy;
            blendTree.blendType              = BlendTreeType.Simple1D;
            blendTree.blendParameter         = blendParam;
            blendTree.useAutomaticThresholds = false;


            foreach (var c in clipIDPairs)
            {
                if (c.layer != layer)
                {
                    continue;
                }
                if (!c.looped)
                {
                    continue;
                }

                blendTree.AddChild(c.clip, threshold: c.id);
            }

            // for (int i = 0; i < c; i++) blendTree.AddChild(clipIDPairs[i].clip, threshold: clipIDPairs[i].id);

            state.motion = blendTree;

            state.mirrorParameterActive = true;
            state.mirrorParameter       = mirrorParam;

            state.speedParameterActive = true;
            state.speedParameter       = speedParam;

            return(state);
        }
Пример #10
0
    /// <summary>
    /// Construye el controlador de animación a partir de todos las animaciones obtenidas
    /// </summary>
    /// <param name="name">Nombre del controlador de animación</param>
    public AnimatorController ConstructAnimationControl(string id)
    {
        BlendTree idle = new BlendTree();
        string    path = "Assets/AnimationController/" + type + "/" + id + ".controller";

        // Creates the controller

        if (AssetDatabase.FindAssets(path).Length > 0)
        {
            AssetDatabase.DeleteAsset(path);
        }

        var controller = AnimatorController.CreateAnimatorControllerAtPath(path);

        // Add parameters
        controller.AddParameter("left", AnimatorControllerParameterType.Bool);
        controller.AddParameter("down", AnimatorControllerParameterType.Bool);
        controller.AddParameter("up", AnimatorControllerParameterType.Bool);
        controller.AddParameter("right", AnimatorControllerParameterType.Bool);
        controller.AddParameter("Idle", AnimatorControllerParameterType.Float);

        // Creating blend tree
        var root = controller.CreateBlendTreeInController("Idle", out idle);

        idle.blendParameter = "Idle";
        root.speed          = downIdle.length;

        if (downIdle != null)
        {
            idle.AddChild(downIdle, 0);
        }

        if (leftIdle != null)
        {
            idle.AddChild(leftIdle, 0.333f);
        }

        if (upIdle != null)
        {
            idle.AddChild(upIdle, 0.666f);
        }

        if (rightIdle != null)
        {
            idle.AddChild(rightIdle, 1);
        }

        //idle.useAutomaticThresholds = true;  // Problema con esta linea de codigo. Dice que esta propiedad no esta definida
        idle.blendType = BlendTreeType.Simple1D;

        // Add StateMachines
        var rootStateMachine = controller.layers[0].stateMachine;
        var stateLeft        = rootStateMachine.AddStateMachine("walking left");
        var stateUp          = rootStateMachine.AddStateMachine("walking up");
        var stateRight       = rootStateMachine.AddStateMachine("walking right");
        var stateDown        = rootStateMachine.AddStateMachine("walking down");

        // Add States
        var leftState = stateLeft.AddState("left");

        leftState.motion = left;
        leftState.AddExitTransition().AddCondition(AnimatorConditionMode.IfNot, 0, "left");

        var upState = stateUp.AddState("up");

        upState.motion = up;
        upState.AddExitTransition().AddCondition(AnimatorConditionMode.IfNot, 0, "up");

        var rightState = stateRight.AddState("right");

        rightState.motion = right;
        rightState.AddExitTransition().AddCondition(AnimatorConditionMode.IfNot, 0, "right");

        var downState = stateDown.AddState("down");

        downState.motion = down;
        downState.AddExitTransition().AddCondition(AnimatorConditionMode.IfNot, 0, "down");

        // Add exit transition
        rootStateMachine.AddStateMachineTransition(stateLeft, root).AddCondition(AnimatorConditionMode.IfNot, 0, "left");
        rootStateMachine.AddStateMachineTransition(stateUp, root).AddCondition(AnimatorConditionMode.IfNot, 0, "up");
        rootStateMachine.AddStateMachineTransition(stateRight, root).AddCondition(AnimatorConditionMode.IfNot, 0, "right");
        rootStateMachine.AddStateMachineTransition(stateDown, root).AddCondition(AnimatorConditionMode.IfNot, 0, "down");

        // Add entry transition
        root.AddTransition(leftState).AddCondition(AnimatorConditionMode.If, 0, "left");
        root.AddTransition(upState).AddCondition(AnimatorConditionMode.If, 0, "up");
        root.AddTransition(rightState).AddCondition(AnimatorConditionMode.If, 0, "right");
        root.AddTransition(downState).AddCondition(AnimatorConditionMode.If, 0, "down");

        return(controller);
    }
Пример #11
0
    static void CheckAndRefreshAnimatorController(string animatorControllerPath, AnimationClip[] newClips, AnimatorStateMachine stateMachine, AnimatorController animatorController)
    {
        for (int i = 0; i < stateMachine.states.Length; i++)
        {
            ChildAnimatorState childState = stateMachine.states[i];

            string motionName = GetMotionName(animatorControllerPath, childState.state.name);
            if (!string.IsNullOrEmpty(motionName))
            {
                for (int j = 0; j < newClips.Length; j++)
                {
                    if (newClips[j].name.CompareTo(motionName) == 0)
                    {
                        childState.state.motion = (Motion)newClips[j];
                        Debug.Log("替换成功 animatorController:" + animatorController.name + " motionName:" + motionName);
                        s_countChange++;
                        break;
                    }
                }
            }
            else
            {
                if (childState.state.motion == null)
                {
                    if (childState.state.name.CompareTo("New State") == 0)
                    {
                        continue;
                    }

                    Debug.LogError("替换失败 animatorController:" + animatorController.name + " Null : " + childState.state.name);
                    continue;
                }
                if (childState.state.motion.GetType() == typeof(AnimationClip))
                {
                    for (int j = 0; j < newClips.Length; j++)
                    {
                        if (newClips[j].name.CompareTo(childState.state.motion.name) == 0)
                        {
                            childState.state.motion = (Motion)newClips[j];
                            Debug.Log("替换成功 animatorController:" + animatorController.name + "childState.state.name:" + childState.state.name);
                            s_countChange++;
                            break;
                        }
                    }
                }
#if BlendTree
                else if (childState.state.motion.GetType() == typeof(BlendTree))
                {
                    //BlendTree这个类有BUG,不能直接修改Motion, 要先记录原本的信息,再全部删除原本的,再修改,再加上去.

                    List <Motion> allMotion    = new List <Motion>();
                    List <float>  allThreshold = new List <float>();
                    BlendTree     tree         = (BlendTree)childState.state.motion;

                    for (int k = 0; k < tree.children.Length; k++)
                    {
                        allMotion.Add(tree.children[k].motion);
                        allThreshold.Add(tree.children[k].threshold);
                    }

                    for (int k = 0; k < allMotion.Count; k++)
                    {
                        if (allMotion[k].GetType() == typeof(AnimationClip))
                        {
                            for (int j = 0; j < newClips.Length; j++)
                            {
                                if (newClips[j].name.CompareTo(allMotion[k].name) == 0)
                                {
                                    allMotion[k] = (Motion)newClips[j];
                                    s_countChange++;
                                    break;
                                }
                            }
                        }
                        else if (allMotion[k].GetType() == typeof(BlendTree))
                        {
                            Debug.LogError("You need to change it!");
                        }
                    }

                    for (int k = tree.children.Length - 1; k >= 0; k--)
                    {
                        tree.RemoveChild(k);
                    }

                    for (int k = 0; k < allMotion.Count; k++)
                    {
                        tree.AddChild(allMotion[k], allThreshold[k]);
                    }
                }
#endif
            }
        }



        for (int i = 0; i < stateMachine.stateMachines.Length; i++)
        {
            CheckAndRefreshAnimatorController(animatorControllerPath, newClips, stateMachine.stateMachines[i].stateMachine, animatorController);
        }
    }
Пример #12
0
    static void SaveAnimatorControllerMotion(string animatorControllerPath, AnimatorStateMachine stateMachine, AnimatorController animatorController)
    {
        for (int i = 0; i < stateMachine.states.Length; i++)
        {
            ChildAnimatorState childState = stateMachine.states[i];
            if (childState.state.motion == null)
            {
                if (childState.state.name.CompareTo("New State") == 0)
                {
                    continue;
                }

                continue;
            }
            if (childState.state.motion.GetType() == typeof(AnimationClip))
            {
                var    motionNameDict = s_animatorControllerMotionDict[animatorControllerPath];
                string stateName      = childState.state.name;
                string motionName     = childState.state.motion.name;
                if (motionNameDict.ContainsKey(stateName))
                {
                    motionNameDict[stateName] = motionName;
                }
                else
                {
                    motionNameDict.Add(stateName, motionName);
                }
            }

#if BlendTree
            else if (childState.state.motion.GetType() == typeof(BlendTree))
            {
                //BlendTree这个类有BUG,不能直接修改Motion, 要先记录原本的信息,再全部删除原本的,再修改,再加上去.

                List <Motion> allMotion    = new List <Motion>();
                List <float>  allThreshold = new List <float>();
                BlendTree     tree         = (BlendTree)childState.state.motion;

                for (int k = 0; k < tree.children.Length; k++)
                {
                    allMotion.Add(tree.children[k].motion);
                    allThreshold.Add(tree.children[k].threshold);
                }

                for (int k = 0; k < allMotion.Count; k++)
                {
                    if (allMotion[k].GetType() == typeof(AnimationClip))
                    {
                        for (int j = 0; j < newClips.Length; j++)
                        {
                            if (newClips[j].name.CompareTo(allMotion[k].name) == 0)
                            {
                                allMotion[k] = (Motion)newClips[j];
                                s_countChange++;
                                break;
                            }
                        }
                    }
                    else if (allMotion[k].GetType() == typeof(BlendTree))
                    {
                        Debug.LogError("You need to change it!");
                    }
                }

                for (int k = tree.children.Length - 1; k >= 0; k--)
                {
                    tree.RemoveChild(k);
                }

                for (int k = 0; k < allMotion.Count; k++)
                {
                    tree.AddChild(allMotion[k], allThreshold[k]);
                }
            }
#endif
        }

        for (int i = 0; i < stateMachine.stateMachines.Length; i++)
        {
            SaveAnimatorControllerMotion(animatorControllerPath, stateMachine.stateMachines[i].stateMachine, animatorController);
        }
    }
        protected bool UpdateStatemachine(BaseState state, AnimatorStateMachine parentState = null, int layerIndex = 0)
        {
            bool status = true;
            AnimatorStateMachine statemachine = null;

            ChildAnimatorStateMachine[] _animatorSubstates = animatorController.layers[layerIndex].stateMachine.stateMachines;

            // --- Update State ---
            if (parentState != null)
            {
                // -- Add States into Parent State --
                if (!AnimatorstatemachineExists(state.Name, parentState.stateMachines, out statemachine))
                {
                    statemachine = parentState.AddStateMachine(state.Name);
                }
            }
            else
            {
                // -- Add States into Global State --
                if (!AnimatorstatemachineExists(state.Name, _animatorSubstates, out statemachine))
                {
                    statemachine = this.animatorController.layers[layerIndex].stateMachine.AddStateMachine(state.Name);
                }
            }

            // --- Add State Parameter ---
            string stateParameterName = state.Name;
            AnimatorControllerParameter stateParameter = null;

            if (!ParameterExists(stateParameterName, this.animatorController.parameters, out stateParameter))
            {
                this.animatorController.AddParameter(stateParameterName, AnimatorControllerParameterType.Bool);
                ParameterExists(stateParameterName, this.animatorController.parameters, out stateParameter); // Link Paramter to "stateParameter" ObjectReference
            }

            if (statemachine != null)
            {
                // --- Create BlendTree ---
                if (state.blendTree)
                {
                    BaseState.BlendTree1DInfo blendTree1D = state.GetBlendTree();
                    string blendTreeName = string.Format("{0}_{1}_BlendTree", state.Name, blendTree1D.parameter);

                    //// -- Update BlendTree Parameter --
                    string blendParameterName = blendTree1D.parameter;
                    AnimatorControllerParameter blendParameter = null;

                    if (!ParameterExists(blendParameterName, this.animatorController.parameters, out blendParameter))
                    {
                        this.animatorController.AddParameter(blendParameterName, AnimatorControllerParameterType.Float);
                    }

                    // --- Add BlendTree ---
                    AnimatorState blendTreeState;
                    BlendTree     blendTree = null;

                    if (!AnimatorstateExists(blendTreeName, statemachine.states, out blendTreeState))
                    {
                        Debug.Log("CreateBlendTreeInController");
                        //blendTreeState = this.animatorController.CreateBlendTreeInController(blendTreeName, out blendTree);
                        blendTreeState = CreateBlendTreeInController(statemachine, blendTreeName, out blendTree);
                    }
                    else if (blendTreeState.motion == null)
                    {
                        Debug.Log("RecreateBlendTreeInController");
                        blendTreeState = RecreateBlendTreeInController(statemachine, blendTreeState, blendTreeName, out blendTree, 0);
                    }

                    if (blendTreeState.motion is BlendTree)
                    {
                        blendTree = blendTreeState.motion as BlendTree;
                    }

                    if (blendTree != null && blendTree1D.blocks != null)
                    {
                        blendTree.name                   = blendTreeName;
                        blendTree.blendParameter         = blendParameterName;
                        blendTree.useAutomaticThresholds = false;

                        AnimatorState subBlendTreeState;
                        BlendTree     subBlendTree  = null;
                        AnimationClip animationClip = null;

                        for (int i = 0; i < blendTree1D.blocks.Count; i++)
                        {
                            if (blendTree1D.blocks.Count > 1)
                            {
                                // 1D BlendTree with SubBlendTrees that have motionClips as children
                                //Debug.LogFormat("Multi-BlendTree: {0}/{1}", blendTree1D.blocks.Keys[i], blendTree1D.blocks.Keys.Count);
                                string subBlendTreeName = string.Format("{0}_BlendTree", blendTree1D.blocks.Keys[i]);

                                //// -- Update BlendTree Parameter --
                                string subBlendParameterName = string.Format("{0}_Blend_{1}", state.Name, blendTree1D.blocks.Keys[i]);
                                AnimatorControllerParameter subBlendParameter = null;

                                if (!ParameterExists(subBlendParameterName, this.animatorController.parameters, out subBlendParameter))
                                {
                                    this.animatorController.AddParameter(subBlendParameterName, AnimatorControllerParameterType.Float);
                                }

                                // -- Create Sub-BlendTree --
                                if (i >= blendTree.children.Length)
                                {
                                    subBlendTree = CreateBlendTree(subBlendTreeName);
                                    blendTree.AddChild(subBlendTree);
                                }
                                else if (blendTree.children[i].motion == null)
                                {
                                    subBlendTree = CreateBlendTree(subBlendTreeName);
                                    blendTree.children[i].motion = subBlendTree;
                                }

                                subBlendTree                        = blendTree.children[i].motion as BlendTree;
                                subBlendTree.name                   = subBlendTreeName;
                                subBlendTree.blendParameter         = subBlendParameterName;
                                subBlendTree.useAutomaticThresholds = false;

                                // -- Update Clips --
                                for (int y = 0; y < blendTree1D.blocks.Values[i].Length; y++)
                                {
                                    //Debug.LogFormat("- {0}: {1}", blendTree1D.blocks.Values[i][y].label, subBlendTree.children[y].motion);
                                    animationClip = blendTree1D.blocks.Values[i][y].clip;

                                    if (y < subBlendTree.children.Length)
                                    {
                                        subBlendTree.children[y].motion = animationClip; // Update
                                    }
                                    else
                                    {
                                        subBlendTree.AddChild(animationClip); // Add
                                    }
                                }

                                // Rewrite the Threshold
                                ChildMotion[] subChildren = subBlendTree.children;

                                for (int z = 0; z < subBlendTree.children.Length; z++)
                                {
                                    subChildren[z].threshold = z;
                                }

                                subBlendTree.children = subChildren;
                            }
                            else
                            {
                                // 1D BlendTree with Motion Clips and One Parameter
                                for (int x = 0; x < blendTree1D.blocks.Values[0].Length; x++)
                                {
                                    animationClip = blendTree1D.blocks.Values[0][x].clip;

                                    if (x < blendTree.children.Length)
                                    {
                                        blendTree.children[x].motion = animationClip; // Update
                                    }
                                    else
                                    {
                                        blendTree.AddChild(animationClip); // Add
                                    }
                                }
                            }
                        }

                        // Rewrite the Threshold
                        ChildMotion[] children = blendTree.children;

                        for (int z = 0; z < blendTree.children.Length; z++)
                        {
                            children[z].threshold = z;
                        }

                        blendTree.children = children;
                    }

                    //// --- Anystate Transitions ---
                    string triggerParameterName = blendTreeName;
                    AnimatorControllerParameter transitionParameter = null;

                    if (!ParameterExists(triggerParameterName, this.animatorController.parameters, out transitionParameter))
                    {
                        this.animatorController.AddParameter(triggerParameterName, AnimatorControllerParameterType.Trigger);
                    }

                    AnimatorStateTransition transition = null;
                    if (!StateTransitionExists(triggerParameterName, this.animatorController.layers[layerIndex].stateMachine.anyStateTransitions, out transition))
                    {
                        transition = this.animatorController.layers[layerIndex].stateMachine.AddAnyStateTransition(blendTreeState);
                        transition.AddCondition(AnimatorConditionMode.If, 0f, triggerParameterName);
                        transition.AddCondition(AnimatorConditionMode.If, 0f, stateParameterName);

                        transition.destinationStateMachine = statemachine;
                    }
                }

                // --- Update Animations in State ---
                List <AnimationObject> animations = state.GetAnimations();
                for (int i = 0; i < animations.Count; i++)
                {
                    // -- Setup AnimatorState --
                    AnimationObject animation     = animations[i];
                    AnimatorState   animatorState = null;

                    if (string.IsNullOrEmpty(animation.label))
                    {
                        continue;
                    }

                    if (!AnimatorstateExists(animation.label, statemachine.states, out animatorState))
                    {
                        animatorState = statemachine.AddState(animation.label);
                    }

                    // -- Update AnimationState --
                    animatorState.motion = animation.clip; // Update MotionClip

                    // -- Animation Events --
                    if (animation.clip != null && animation.clip.events != null && animation.clip.events.Length > 0)
                    {
                        //for(int x = 0; x < animation.clip.events.Length; x++)
                        //{
                        //    Debug.LogFormat("{0}: ({1}) {2}", animation.clip.name,
                        //                    animation.clip.events[x].time,
                        //                    animation.clip.events[x].functionName);
                        //}

                        //AnimationEvent animationEvent = new AnimationEvent();
                        //animationEvent.
                        //animation.clip.AddEvent()
                    }

                    // -- Update Parameters --
                    string parameterName = animation.label;
                    AnimatorControllerParameter parameter = null;

                    if (!ParameterExists(parameterName, this.animatorController.parameters, out parameter))
                    {
                        this.animatorController.AddParameter(parameterName, AnimatorControllerParameterType.Trigger);
                    }

                    // -- Update Transition --
                    AnimatorStateTransition transition = null;

                    //// --- Anystate Transitions ---
                    if (!StateTransitionExists(parameterName, this.animatorController.layers[layerIndex].stateMachine.anyStateTransitions, out transition))
                    {
                        transition = this.animatorController.layers[layerIndex].stateMachine.AddAnyStateTransition(animatorState);
                        transition.AddCondition(AnimatorConditionMode.If, 0f, parameterName);

                        if (!(stateParameter.name.Contains("Reset") && layerIndex > 0))
                        {
                            transition.AddCondition(AnimatorConditionMode.If, 0f, stateParameterName);
                        }

                        transition.destinationStateMachine = statemachine;
                    }
                }

                // --- Add Transitions between States ---
                for (int i = 0; i < animations.Count; i++)
                {
                    AnimationObject animation             = animations[i];
                    AnimatorState   animatorSenderState   = null;
                    AnimatorState   animatorReceiverState = null;

                    if (AnimatorstateExists(animation.label, statemachine.states, out animatorSenderState) &&
                        AnimatorstateExists(animation.destination, statemachine.states, out animatorReceiverState))
                    {
                        AnimatorStateTransition transition = null;

                        if (!TransitionExists(animatorSenderState, animatorReceiverState, out transition))
                        {
                            //Debug.LogFormat("AnimatorController: Add Transition from '{0}' to {1}!", animatorSenderState.name, animatorReceiverState.name);
                            transition             = animatorSenderState.AddTransition(animatorReceiverState);
                            transition.exitTime    = 1f;
                            transition.duration    = 0f;
                            transition.hasExitTime = true;
                        }
                    }
                }
            }

            return(status);
        }
Пример #14
0
    private static void createAC(string objPath, string objName, Dictionary <string, animCond> conds, List <animClip> lstInfo)
    {
        //查找混合树
        List <animClip> blendInfo = new List <animClip>();

        for (int i = 0; i < lstInfo.Count; i++)
        {
            if (lstInfo[i].blendIndex > 0)
            {
                blendInfo.Add(lstInfo[i]);
            }
        }
        int                     index    = objPath.LastIndexOf("/");
        string                  savePath = getAnimPathByName(objName, "ac");
        string                  clipPath = getAnimPathByName(objName, "clip");
        AnimatorController      ac       = AnimatorController.CreateAnimatorControllerAtPath(Path.Combine(savePath, objName + ".controller"));
        AnimatorControllerLayer layer    = ac.layers[0];
        //添加clip
        AnimatorStateMachine stateMachine = layer.stateMachine;

        string[] files = Directory.GetFiles(clipPath, "*anim");
        Dictionary <string, Motion> dictClips = new Dictionary <string, Motion>();

        for (int i = 0; i < files.Length; i++)
        {
            Motion cp = AssetDatabase.LoadAssetAtPath <Motion>(files[i]);
            if (cp != null)
            {
                dictClips.Add(cp.name, cp);
            }
        }

        AnimatorState animState = null;

        //先创建blendTree
        if (blendInfo.Count > 0)
        {
            if (!isExitParam(ac, "tree"))
            {
                ac.AddParameter("tree", AnimatorControllerParameterType.Float);
            }
            BlendTree btree = null;
            animState            = ac.CreateBlendTreeInController(defaultAnim, out btree);
            btree.blendParameter = "tree";
            for (int i = 0; i < blendInfo.Count; i++)
            {
                string cname = blendInfo[i].clipName;
                if (dictClips.ContainsKey(cname))
                {
                    btree.AddChild(dictClips[cname]);
                }
            }
            stateMachine.AddState(animState, new Vector2(600, -200));
            stateMachine.defaultState = animState;
        }

        int startY = 0;
        int startX = 300;

        for (int i = 0; i < lstInfo.Count; i++)
        {
            if (lstInfo[i].blendIndex > 0)
            {
                continue;
            }
            string name = lstInfo[i].clipName;
            animState        = stateMachine.AddState(name, new Vector2(startX, startY * 80));
            animState.motion = dictClips[name];
            startY++;
        }
        //连线
        ChildAnimatorState[] states = stateMachine.states;
        for (int i = 0; i < states.Length; i++)
        {
            ChildAnimatorState currState = states[i];
            string             name      = currState.state.name;
            if (conds.ContainsKey(name))
            {
                animCond cond          = conds[name];
                string   fromStateName = cond.fromState;
                if (fromStateName == "Any State")
                {
                    AnimatorStateTransition trans = stateMachine.AddAnyStateTransition(currState.state);
                    if (!isExitParam(ac, cond.fromCond))
                    {
                        ac.AddParameter(cond.fromCond, AnimatorControllerParameterType.Trigger);
                    }
                    trans.AddCondition(AnimatorConditionMode.If, 0, cond.fromCond);
                }
                string             toStateName = cond.toState;
                ChildAnimatorState toState     = getState(states, toStateName);
                if (toState.state != null && name != defaultAnim)
                {
                    AnimatorStateTransition trans = currState.state.AddTransition(toState.state);
                    if (cond.toCond == "None")
                    {
                        trans.hasExitTime = false;
                    }
                    else if (cond.toCond == "Exit")
                    {
                        trans.hasExitTime = true;
                    }
                    else
                    {
                        if (!isExitParam(ac, cond.toCond))
                        {
                            ac.AddParameter(cond.toCond, AnimatorControllerParameterType.Trigger);
                        }
                        trans.AddCondition(AnimatorConditionMode.If, 0, cond.toCond);
                    }
                }
            }
        }
        ac.name = objName;
        //AssetDatabase.CreateAsset(ac, Path.Combine(savePath, objName + ".controller"));
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
    }
Пример #15
0
 public static void AddChild(this BlendTree blendTree, Motion motion, float threshold, string parameter)
 {
     blendTree.AddChild(motion, Vector2.zero, threshold, parameter);
 }
Пример #16
0
    void CreateANewController()
    {
        var controller = UnityEditor.Animations.AnimatorController.CreateAnimatorControllerAtPath("Assets/" + animationControllerName + ".controller");

        controller.AddParameter("Forwards", AnimatorControllerParameterType.Float);
        controller.AddParameter("Horizontal", AnimatorControllerParameterType.Float);
        controller.AddParameter("Crouching", AnimatorControllerParameterType.Bool);
        controller.AddParameter("Speed", AnimatorControllerParameterType.Float);
        controller.AddParameter("Engaging", AnimatorControllerParameterType.Bool);

        controller.AddParameter("Melee", AnimatorControllerParameterType.Trigger);
        controller.AddParameter("Reloading", AnimatorControllerParameterType.Trigger);

        controller.AddParameter("Fire", AnimatorControllerParameterType.Trigger);
        controller.AddParameter("Sprinting", AnimatorControllerParameterType.Bool);

        controller.AddParameter("DodgeRight", AnimatorControllerParameterType.Trigger);
        controller.AddParameter("DodgeLeft", AnimatorControllerParameterType.Trigger);

        controller.AddParameter("Leap", AnimatorControllerParameterType.Trigger);
        controller.AddParameter("Vault", AnimatorControllerParameterType.Trigger);
        controller.AddParameter("Stagger", AnimatorControllerParameterType.Trigger);

        //LAYER 1///////////////////////////////////////////
        //Add Outer States
        var baseStateMachine = controller.layers[0].stateMachine;


        //Set Move Tree
        //new BlendTree();
        BlendTree     moveTree  = new BlendTree();
        AnimatorState moveState = controller.CreateBlendTreeInController("Move", out moveTree, 0);

        //Add Transitions
        AnimatorState baseCrouching = null;

        if (crouchingAnimation)
        {
            baseCrouching        = baseStateMachine.AddState("Crouch");
            baseCrouching.motion = crouchingAnimation;

            //Move
            var moveToCrouchTranistion = moveState.AddTransition(baseCrouching, false);
            moveToCrouchTranistion.AddCondition(UnityEditor.Animations.AnimatorConditionMode.If, 0.25f, "Crouching");

            var crouchToMoveTranistion = baseCrouching.AddTransition(moveState, false);
            crouchToMoveTranistion.AddCondition(UnityEditor.Animations.AnimatorConditionMode.IfNot, 0.25f, "Crouching");
        }

        if (fullBodyMeleeAnimation && meleeAnimation)
        {
            var baseMelee = baseStateMachine.AddState("Melee");
            baseMelee.motion = meleeAnimation;

            //Melee
            if (baseCrouching != null)
            {
                var crouchToMeleeTranistion = baseCrouching.AddTransition(baseMelee, false);
                crouchToMeleeTranistion.AddCondition(UnityEditor.Animations.AnimatorConditionMode.If, 0.25f, "Melee");
            }

            //Move
            var moveToMeleeTranistion = moveState.AddTransition(baseMelee, false);
            moveToMeleeTranistion.AddCondition(UnityEditor.Animations.AnimatorConditionMode.If, 0.25f, "Melee");

            baseMelee.AddTransition(moveState, true);
        }

        //
        if (sprintingAnimation)
        {
            var baseSprint = baseStateMachine.AddState("Sprint");
            baseSprint.motion = sprintingAnimation;

            //Move
            var moveToSprintTranistion = moveState.AddTransition(baseSprint, false);
            moveToSprintTranistion.AddCondition(UnityEditor.Animations.AnimatorConditionMode.If, 0.25f, "Sprinting");

            var sprintToMoveTranistion = baseSprint.AddTransition(moveState, false);
            sprintToMoveTranistion.AddCondition(UnityEditor.Animations.AnimatorConditionMode.IfNot, 0.25f, "Sprinting");
        }
        //Set Parameters
        moveTree.blendType       = BlendTreeType.FreeformDirectional2D;
        moveTree.blendParameter  = "Horizontal";
        moveTree.blendParameterY = "Forwards";

        //Add Animations
        float walkThreshold = 0.5f;
        float runThreshold  = 1.0f;

        moveTree.AddChild(idleAnimation, new Vector2(0.0f, 0.0f));

        moveTree.AddChild(runForwardsAnimation, new Vector2(0.0f, runThreshold));
        if (walkForwardsAnimation)
        {
            moveTree.AddChild(walkForwardsAnimation, new Vector2(0.0f, walkThreshold));
        }

        moveTree.AddChild(runBackwardsAnimation, new Vector2(0.0f, -runThreshold));
        if (walkBackwardsAnimation)
        {
            moveTree.AddChild(walkBackwardsAnimation, new Vector2(0.0f, -walkThreshold));
        }

        moveTree.AddChild(runRightAnimation, new Vector2(runThreshold, 0.0f));
        if (walkRightAnimation)
        {
            moveTree.AddChild(walkRightAnimation, new Vector2(walkThreshold, 0.0f));
        }

        moveTree.AddChild(runLeftAnimation, new Vector2(-runThreshold, 0.0f));
        if (walkLeftAnimation)
        {
            moveTree.AddChild(walkLeftAnimation, new Vector2(-walkThreshold, 0.0f));
        }

        if (walkForwardRightsAnimation)
        {
            moveTree.AddChild(walkForwardRightsAnimation, new Vector2(walkThreshold, walkThreshold));
        }
        if (walkForwardLeftAnimation)
        {
            moveTree.AddChild(walkForwardLeftAnimation, new Vector2(-walkThreshold, walkThreshold));
        }
        if (walkBackwardsRightAnimation)
        {
            moveTree.AddChild(walkBackwardsRightAnimation, new Vector2(walkThreshold, -walkThreshold));
        }
        if (walkBackwardsLeftAnimation)
        {
            moveTree.AddChild(walkBackwardsLeftAnimation, new Vector2(-walkThreshold, -walkThreshold));
        }

        if (runForwardRightsAnimation)
        {
            moveTree.AddChild(runForwardRightsAnimation, new Vector2(runThreshold, runThreshold));
        }
        if (runForwardLeftAnimation)
        {
            moveTree.AddChild(runForwardLeftAnimation, new Vector2(-runThreshold, runThreshold));
        }
        if (runBackwardsRightAnimation)
        {
            moveTree.AddChild(runBackwardsRightAnimation, new Vector2(runThreshold, -runThreshold));
        }
        if (runBackwardsLeftAnimation)
        {
            moveTree.AddChild(runBackwardsLeftAnimation, new Vector2(-runThreshold, -runThreshold));
        }

        if (dodgeLeftAnimation)
        {
            AnimatorState leftDB = baseStateMachine.AddState("DodgeLeft");
            leftDB.motion = dodgeLeftAnimation;

            var anyToLeftDTranistion = baseStateMachine.AddAnyStateTransition(leftDB);
            anyToLeftDTranistion.AddCondition(UnityEditor.Animations.AnimatorConditionMode.If, 0.25f, "DodgeLeft");

            leftDB.AddTransition(moveState, true);
        }

        if (dodgeRightAnimation)
        {
            AnimatorState rightDB = baseStateMachine.AddState("DodgeRight");
            rightDB.motion = dodgeRightAnimation;

            var anyToRightDTranistion = baseStateMachine.AddAnyStateTransition(rightDB);
            anyToRightDTranistion.AddCondition(UnityEditor.Animations.AnimatorConditionMode.If, 0.25f, "DodgeRight");

            rightDB.AddTransition(moveState, true);
        }

        if (leapAnimation)
        {
            AnimatorState leapB = baseStateMachine.AddState("Leap");
            leapB.motion = leapAnimation;

            var anyToLeapBTranistion = baseStateMachine.AddAnyStateTransition(leapB);
            anyToLeapBTranistion.AddCondition(UnityEditor.Animations.AnimatorConditionMode.If, 0.25f, "Leap");

            leapB.AddTransition(moveState, true);
        }

        if (vaultAnimation)
        {
            AnimatorState vaultB = baseStateMachine.AddState("Vault");
            vaultB.motion = vaultAnimation;

            var anyToVaultBTranistion = baseStateMachine.AddAnyStateTransition(vaultB);
            anyToVaultBTranistion.AddCondition(UnityEditor.Animations.AnimatorConditionMode.If, 0.25f, "Vault");

            vaultB.AddTransition(moveState, true);
        }

        if (staggerAnimation)
        {
            AnimatorState staggerB = baseStateMachine.AddState("Stagger");
            staggerB.motion = staggerAnimation;

            var anyToStaggerBTranistion = baseStateMachine.AddAnyStateTransition(staggerB);
            anyToStaggerBTranistion.AddCondition(UnityEditor.Animations.AnimatorConditionMode.If, 0.25f, "Stagger");

            staggerB.AddTransition(moveState, true);
        }

        ////////////////////////////////////////////////////
        //Layer 2
        ////////////////////////////////////////////////////

        controller.AddLayer("UpperBody");
        var upperStateMachine = controller.layers[1].stateMachine;


        var upperAim = upperStateMachine.AddState("Aim");

        upperAim.motion = aimingAnimation;

        BlendTree     idleUpperTree = new BlendTree();
        AnimatorState upperIdle     = controller.CreateBlendTreeInController("Idle", out idleUpperTree, 1);

        idleUpperTree.blendParameter = "Speed";

        idleUpperTree.AddChild(idleUpperAnim, 0.0f);
        if (walkUpperAnim)
        {
            idleUpperTree.AddChild(walkUpperAnim, 0.5f);
        }
        if (runUpperAnim)
        {
            idleUpperTree.AddChild(runUpperAnim, 1.0f);
        }


        //Idle Transitions
        var idleToAim = upperIdle.AddTransition(upperAim, false);

        idleToAim.AddCondition(UnityEditor.Animations.AnimatorConditionMode.If, 0.25f, "Engaging");

        var aimToidle = upperAim.AddTransition(upperIdle, false);

        aimToidle.AddCondition(UnityEditor.Animations.AnimatorConditionMode.IfNot, 0.25f, "Engaging");

        if (dodgeLeftAnimation)
        {
            AnimatorState leftD = upperStateMachine.AddState("DodgeLeft");
            leftD.motion = dodgeLeftAnimation;

            var anyToLeftDTranistion = upperStateMachine.AddAnyStateTransition(leftD);
            anyToLeftDTranistion.AddCondition(UnityEditor.Animations.AnimatorConditionMode.If, 0.25f, "DodgeLeft");

            leftD.AddTransition(upperAim, true);
        }

        if (dodgeRightAnimation)
        {
            AnimatorState rightD = upperStateMachine.AddState("DodgeRight");
            rightD.motion = dodgeRightAnimation;

            var anyToRightDTranistion = upperStateMachine.AddAnyStateTransition(rightD);
            anyToRightDTranistion.AddCondition(UnityEditor.Animations.AnimatorConditionMode.If, 0.25f, "DodgeRight");

            rightD.AddTransition(upperAim, true);
        }

        if (leapAnimation)
        {
            AnimatorState leapU = upperStateMachine.AddState("Leap");
            leapU.motion = leapAnimation;

            var anyToLeapUTranistion = upperStateMachine.AddAnyStateTransition(leapU);
            anyToLeapUTranistion.AddCondition(UnityEditor.Animations.AnimatorConditionMode.If, 0.25f, "Leap");

            leapU.AddTransition(upperAim, true);
        }

        if (vaultAnimation)
        {
            AnimatorState vaultU = upperStateMachine.AddState("Vault");
            vaultU.motion = vaultAnimation;

            var anyToVaultUTranistion = upperStateMachine.AddAnyStateTransition(vaultU);
            anyToVaultUTranistion.AddCondition(UnityEditor.Animations.AnimatorConditionMode.If, 0.25f, "Vault");

            vaultU.AddTransition(upperAim, true);
        }

        if (staggerAnimation)
        {
            AnimatorState staggerU = upperStateMachine.AddState("Stagger");
            staggerU.motion = staggerAnimation;

            var anyToStaggerUTranistion = upperStateMachine.AddAnyStateTransition(staggerU);
            anyToStaggerUTranistion.AddCondition(UnityEditor.Animations.AnimatorConditionMode.If, 0.25f, "Stagger");

            staggerU.AddTransition(upperAim, true);
        }

        //Melee
        if (meleeAnimation)
        {
            AnimatorState upperMelee = upperStateMachine.AddState("Melee");
            upperMelee.motion = meleeAnimation;

            var aimToMeleeTranistion = upperAim.AddTransition(upperMelee, false);
            aimToMeleeTranistion.AddCondition(UnityEditor.Animations.AnimatorConditionMode.If, 0.25f, "Melee");

            upperMelee.AddTransition(upperAim, true);
        }
        if (sprintingAnimation)
        {
            var upperSprint = upperStateMachine.AddState("Sprint");
            upperSprint.motion = sprintingAnimation;

            //Move
            var aimToSprintTranistion = upperAim.AddTransition(upperSprint, false);
            aimToSprintTranistion.AddCondition(UnityEditor.Animations.AnimatorConditionMode.If, 0.25f, "Sprinting");

            var sprintToAimTranistion = upperSprint.AddTransition(upperAim, false);
            sprintToAimTranistion.AddCondition(UnityEditor.Animations.AnimatorConditionMode.IfNot, 0.25f, "Sprinting");
        }

        //Reload
        if (reloadAnimation)
        {
            AnimatorState reloadAnim = upperStateMachine.AddState("Reload");
            reloadAnim.motion = reloadAnimation;

            var aimToReloadTranistion = upperAim.AddTransition(reloadAnim, false);
            aimToReloadTranistion.AddCondition(UnityEditor.Animations.AnimatorConditionMode.If, 0.25f, "Reloading");

            reloadAnim.AddTransition(upperAim, true);
        }
        //Fire
        if (fireAnimation)
        {
            Debug.Log("Tactical");
            AnimatorState fireAnim = upperStateMachine.AddState("Fire");
            fireAnim.motion = fireAnimation;

            var aimToFireTranistion = upperAim.AddTransition(fireAnim, false);
            aimToFireTranistion.AddCondition(UnityEditor.Animations.AnimatorConditionMode.If, 0.25f, "Fire");

            fireAnim.AddTransition(upperAim, true);
        }
    }
Пример #17
0
        /// <summary>Inject FDS layer to given controller, if it doesn't have one</summary>
        static void InjectLayer(AnimatorController c)
        {
            if (c.layers.Any(l => l.name == FDS_LayerName))
            {
                Debug.Log($"The AnimatorController '{c.ToString()}' already have layer '{FDS_LayerName}'. Stop Injecting to this");
                return;
            }

            // Use memorized one
            if (layer != null)
            {
                c.AddLayer(layer);
                return;
            }

            // Creating Layer {{{
            // BlendTree configuration {{{2
            BlendTree xRotationTree = CreateChild("xRotationTree", "FDS_LookUp", "FDS_LookDown", XRotationParameterName);
            BlendTree yRotationTree = CreateChild("yRotationTree", "FDS_LookLeft", "FDS_LookRight", YRotationParameterName);
            BlendTree zRotationTree = CreateChild("zRotationTree", "FDS_TiltLeft", "FDS_TiltRight", ZRotationParameterName);

            BlendTree rootTree = new BlendTree();

            rootTree.name      = "faceRotationRootTree";
            rootTree.blendType = BlendTreeType.Direct;
            rootTree.AddChild(xRotationTree);
            rootTree.AddChild(yRotationTree);
            rootTree.AddChild(zRotationTree);
            // }}}

            // Default State configuration {{{2
            AnimatorState defState = new AnimatorState();

            defState.name   = "faceRotationDefaultState";
            defState.motion = rootTree;
            // TODO: Should we turn on 'WriteDefaultValues'?
            // }}}

            // State Machine configuration {{{2
            AnimatorStateMachine stateMachine = new AnimatorStateMachine();

            stateMachine.name = "faceRotationStateMachine";
            stateMachine.AddState(defState, new Vector3(0, 0, 0));
            // }}}

            // Layer configuration {{{2
            AnimatorControllerLayer faceRotationLayer = new AnimatorControllerLayer();

            faceRotationLayer.avatarMask    = (AvatarMask)LoadFDSAsset <AvatarMask>("FDS_HeadRotationMask");
            faceRotationLayer.blendingMode  = AnimatorLayerBlendingMode.Override;
            faceRotationLayer.defaultWeight = 1.0f;
            faceRotationLayer.iKPass        = false;
            faceRotationLayer.name          = FDS_LayerName;
            faceRotationLayer.stateMachine  = stateMachine;
            // }}}
            // }}}

            c.AddLayer(faceRotationLayer);
            layer = faceRotationLayer;

            // Save asset
            // Each stuff I created should be 'Add'ed with 'AddObjectToAsset'
            // otherwise they'll be gone forever.
            // Reference:
            //   - https://forum.unity.com/threads/modify-animatorcontroller-through-script-and-save-it.612844/#post-5271999
            var controllerAssetPath = AssetDatabase.GetAssetPath(c);

            AssetDatabase.AddObjectToAsset(stateMachine, controllerAssetPath);
            AssetDatabase.AddObjectToAsset(defState, controllerAssetPath);
            AssetDatabase.AddObjectToAsset(rootTree, controllerAssetPath);
            AssetDatabase.AddObjectToAsset(xRotationTree, controllerAssetPath);
            AssetDatabase.AddObjectToAsset(yRotationTree, controllerAssetPath);
            AssetDatabase.AddObjectToAsset(zRotationTree, controllerAssetPath);
        }
        public BlendTree CreateBlendTreeAsset()
        {
            var is2D = CurrentTemplate != PuppetTemplate.SingleAnalogFistWithHairTrigger;

            var blendTree = new BlendTree();

            blendTree.blendType = is2D ? BlendTreeType.FreeformDirectional2D : BlendTreeType.Simple1D;
            if (CurrentTemplate == PuppetTemplate.DualAnalogFist)
            {
                blendTree.blendParameter  = "GestureRightWeight";
                blendTree.blendParameterY = "GestureLeftWeight";
            }
            else
            {
                blendTree.blendParameter = is2D ? "VRCFaceBlendH" : CgeBlendTreeAutoWeightCorrector.AutoGestureWeightParam;
                if (is2D)
                {
                    if (CurrentTemplate != PuppetTemplate.SingleAnalogFistAndTwoDirections)
                    {
                        blendTree.blendParameterY = "VRCFaceBlendV";
                    }
                    else
                    {
                        blendTree.blendParameterY = CgeBlendTreeAutoWeightCorrector.AutoGestureWeightParam;
                    }
                }
            }

            switch (CurrentTemplate)
            {
            case PuppetTemplate.FourDirections:
                blendTree.AddChild(null, new Vector2(0, Maximum));
                blendTree.AddChild(null, new Vector2(Maximum, 0));
                blendTree.AddChild(null, new Vector2(0, -Maximum));
                blendTree.AddChild(null, new Vector2(-Maximum, 0));
                break;

            case PuppetTemplate.EightDirections:
                blendTree.AddChild(null, new Vector2(0, Maximum));
                blendTree.AddChild(null, AtRevolution(1 / 8f));
                blendTree.AddChild(null, new Vector2(Maximum, 0));
                blendTree.AddChild(null, AtRevolution(3 / 8f));
                blendTree.AddChild(null, new Vector2(0, -Maximum));
                blendTree.AddChild(null, AtRevolution(5 / 8f));
                blendTree.AddChild(null, new Vector2(-Maximum, 0));
                blendTree.AddChild(null, AtRevolution(7 / 8f));
                break;

            case PuppetTemplate.SixDirectionsPointingForward:
                blendTree.AddChild(null, new Vector2(0, Maximum));
                blendTree.AddChild(null, AtRevolution(1 / 6f));
                blendTree.AddChild(null, AtRevolution(2 / 6f));
                blendTree.AddChild(null, new Vector2(0, -Maximum));
                blendTree.AddChild(null, AtRevolution(4 / 6f));
                blendTree.AddChild(null, AtRevolution(5 / 6f));
                break;

            case PuppetTemplate.SixDirectionsPointingSideways:
                blendTree.AddChild(null, new Vector2(Maximum, 0));
                blendTree.AddChild(null, AtRevolution(1 / 12f + 2 / 6f));
                blendTree.AddChild(null, AtRevolution(1 / 12f + 3 / 6f));
                blendTree.AddChild(null, new Vector2(-Maximum, 0));
                blendTree.AddChild(null, AtRevolution(1 / 12f + 5 / 6f));
                blendTree.AddChild(null, AtRevolution(1 / 12f + 0 / 6f));
                break;

            case PuppetTemplate.SingleAnalogFistWithHairTrigger:
                blendTree.useAutomaticThresholds = false;
                blendTree.AddChild(MiddleClip, 0f);
                blendTree.AddChild(null, 0.8f);
                blendTree.AddChild(null, 1.0f);
                break;

            case PuppetTemplate.SingleAnalogFistAndTwoDirections:
                blendTree.AddChild(null, new Vector2(-Maximum, 1));
                blendTree.AddChild(null, new Vector2(0, 1));
                blendTree.AddChild(null, new Vector2(Maximum, 1));
                blendTree.AddChild(MiddleClip, new Vector2(-1, 0));
                blendTree.AddChild(MiddleClip, new Vector2(0, 0));
                blendTree.AddChild(MiddleClip, new Vector2(1, 0));
                break;

            case PuppetTemplate.DualAnalogFist:
                blendTree.AddChild(null, new Vector2(1, 1));
                blendTree.AddChild(null, new Vector2(1, 0));
                blendTree.AddChild(null, new Vector2(0, 1));
                blendTree.AddChild(MiddleClip, new Vector2(0, 0));
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            if (is2D &&
                CurrentTemplate != PuppetTemplate.SingleAnalogFistAndTwoDirections &&
                CurrentTemplate != PuppetTemplate.DualAnalogFist)
            {
                blendTree.AddChild(MiddleClip, new Vector2(0, 0));
                if (CenterSafety)
                {
                    blendTree.AddChild(MiddleClip, new Vector2(0, 0.1f));
                    blendTree.AddChild(MiddleClip, new Vector2(0.1f, 0));
                    blendTree.AddChild(MiddleClip, new Vector2(0, -0.1f));
                    blendTree.AddChild(MiddleClip, new Vector2(-0.1f, 0));
                }
            }

            return(blendTree);
        }
Пример #19
0
    static void CheckAndRefreshAnimatorController(List <AnimationClip> clips, AnimatorStateMachine stateMachine)
    {
        for (int i = 0; i < stateMachine.states.Length; i++)
        {
            ChildAnimatorState childState = stateMachine.states[i];
            if (childState.state.motion == null)
            {
                Debug.LogError("Null motion : " + childState.state.name);
                continue;
            }

            if (childState.state.motion.GetType() == typeof(AnimationClip))
            {
                for (int j = 0; j < clips.Count; j++)
                {
                    if (clips[j].name.CompareTo(childState.state.motion.name) == 0)
                    {
                        childState.state.motion = (Motion)clips[j];
                        break;
                    }
                }
            }
            else if (childState.state.motion.GetType() == typeof(BlendTree))
            {
                //BlendTree这个类有BUG,不能直接修改Motion, 要先记录原本的信息,再全部删除原本的,再修改,再加上去.
                List <Motion> allMotion    = new List <Motion>();
                List <float>  allThreshold = new List <float>();
                BlendTree     tree         = (BlendTree)childState.state.motion;

                for (int k = 0; k < tree.children.Length; k++)
                {
                    allMotion.Add(tree.children[k].motion);
                    allThreshold.Add(tree.children[k].threshold);
                }

                for (int k = 0; k < allMotion.Count; k++)
                {
                    if (allMotion[k].GetType() == typeof(AnimationClip))
                    {
                        for (int j = 0; j < clips.Count; j++)
                        {
                            if (clips[j].name.CompareTo(allMotion[k].name) == 0)
                            {
                                allMotion[k] = (Motion)clips[j];
                                break;
                            }
                        }
                    }
                    else if (allMotion[k].GetType() == typeof(BlendTree))
                    {
                        Debug.LogError("不能多层BlendTree!");
                    }
                }

                for (int k = tree.children.Length - 1; k >= 0; k--)
                {
                    tree.RemoveChild(k);
                }

                for (int k = 0; k < allMotion.Count; k++)
                {
                    tree.AddChild(allMotion[k], allThreshold[k]);
                }
            }
        }

        for (int i = 0; i < stateMachine.stateMachines.Length; i++)
        {
            CheckAndRefreshAnimatorController(clips, stateMachine.stateMachines[i].stateMachine);
        }
    }
    void CreateANewController()
    {
        var controller = UnityEditor.Animations.AnimatorController.CreateAnimatorControllerAtPath ("Assets/"+animationControllerName+".controller");

            controller.AddParameter("Forwards", AnimatorControllerParameterType.Float);
            controller.AddParameter("Horizontal", AnimatorControllerParameterType.Float);
            controller.AddParameter("Crouching", AnimatorControllerParameterType.Bool);
            controller.AddParameter("Speed", AnimatorControllerParameterType.Float);
            controller.AddParameter("Engaging", AnimatorControllerParameterType.Bool);

            controller.AddParameter("Melee", AnimatorControllerParameterType.Trigger);
            controller.AddParameter("Reloading", AnimatorControllerParameterType.Trigger);
            controller.AddParameter("Fire", AnimatorControllerParameterType.Trigger);

            //LAYER 1///////////////////////////////////////////
            //Add Outer States
            var baseStateMachine = controller.layers[0].stateMachine;

            //Set Move Tree
            //new BlendTree();
            BlendTree moveTree = new BlendTree();
            AnimatorState moveState = controller.CreateBlendTreeInController("Move", out moveTree, 0);

            //Add Transitions
            AnimatorState baseCrouching = null;
            if(crouchingAnimation){
                baseCrouching = baseStateMachine.AddState("Crouch");
                baseCrouching.motion = crouchingAnimation;

                //Move
                var moveToCrouchTranistion = moveState.AddTransition(baseCrouching, false);
                moveToCrouchTranistion.AddCondition(UnityEditor.Animations.AnimatorConditionMode.If, 0.25f, "Crouching");

                var crouchToMoveTranistion = baseCrouching.AddTransition(moveState, false);
                crouchToMoveTranistion.AddCondition(UnityEditor.Animations.AnimatorConditionMode.IfNot, 0.25f, "Crouching");

            }

            if(fullBodyMeleeAnimation && meleeAnimation){
                var baseMelee = baseStateMachine.AddState("Melee");
                baseMelee.motion = meleeAnimation;

                //Melee
                if(baseCrouching != null){
                    var crouchToMeleeTranistion = baseCrouching.AddTransition(baseMelee, false);
                    crouchToMeleeTranistion.AddCondition(UnityEditor.Animations.AnimatorConditionMode.If, 0.25f, "Melee");
                }

                //Move
                var moveToMeleeTranistion = moveState.AddTransition(baseMelee, false);
                moveToMeleeTranistion.AddCondition(UnityEditor.Animations.AnimatorConditionMode.If, 0.25f, "Melee");

            }

            //Set Parameters
            moveTree.blendType = BlendTreeType.FreeformDirectional2D;
            moveTree.blendParameter = "Horizontal";
            moveTree.blendParameterY = "Forwards";

            //Add Animations
            float walkThreshold = 0.5f;
            float runThreshold = 1.0f;

            moveTree.AddChild(idleAnimation, new Vector2(0.0f, 0.0f));

            moveTree.AddChild(runForwardsAnimation, new Vector2(0.0f, runThreshold));
            if (walkForwardsAnimation)
            {
                moveTree.AddChild(walkForwardsAnimation, new Vector2(0.0f, walkThreshold));
            }

            moveTree.AddChild(runBackwardsAnimation, new Vector2(0.0f, -runThreshold));
            if (walkBackwardsAnimation)
            {
                moveTree.AddChild(walkBackwardsAnimation, new Vector2(0.0f, -walkThreshold));
            }

            moveTree.AddChild(runRightAnimation, new Vector2(runThreshold, 0.0f));
            if (walkRightAnimation)
            {
                moveTree.AddChild(walkRightAnimation, new Vector2(walkThreshold, 0.0f));
            }

            moveTree.AddChild(runLeftAnimation, new Vector2(-runThreshold, 0.0f));
            if (walkLeftAnimation)
            {
                moveTree.AddChild(walkLeftAnimation, new Vector2(-walkThreshold, 0.0f));
            }

            ////////////////////////////////////////////////////
            //Layer 2
            ////////////////////////////////////////////////////

            controller.AddLayer("UpperBody");
            var upperStateMachine = controller.layers[1].stateMachine;

            var upperAim = upperStateMachine.AddState("Aim");
            upperAim.motion = aimingAnimation;

            BlendTree idleUpperTree = new BlendTree();
            AnimatorState upperIdle = controller.CreateBlendTreeInController("Idle", out idleUpperTree, 1);
            idleUpperTree.blendParameter = "Speed";

            idleUpperTree.AddChild(idleUpperAnim,0.0f);
            if(walkUpperAnim)
                idleUpperTree.AddChild(walkUpperAnim,0.5f);
            if(runUpperAnim)
                idleUpperTree.AddChild(runUpperAnim,1.0f);

            //Idle Transitions
            var idleToAim = upperIdle.AddTransition(upperAim, false);
            idleToAim.AddCondition(UnityEditor.Animations.AnimatorConditionMode.If, 0.25f, "Engaging");

            var aimToidle = upperAim.AddTransition(upperIdle, false);
            aimToidle.AddCondition(UnityEditor.Animations.AnimatorConditionMode.IfNot, 0.25f, "Engaging");

            //Melee
            if(meleeAnimation)
                {
                    AnimatorState upperMelee = upperStateMachine.AddState("Melee");
                    upperMelee.motion = meleeAnimation;

                    var aimToMeleeTranistion = upperAim.AddTransition(upperMelee, false);
                    aimToMeleeTranistion.AddCondition(UnityEditor.Animations.AnimatorConditionMode.If, 0.25f, "Melee");

                    upperMelee.AddTransition(upperAim, true);
                }
            //Reload
            if(reloadAnimation)
                {
                    AnimatorState reloadAnim = upperStateMachine.AddState("Reload");
                    reloadAnim.motion = reloadAnimation;

                    var aimToReloadTranistion = upperAim.AddTransition(reloadAnim, false);
                    aimToReloadTranistion.AddCondition(UnityEditor.Animations.AnimatorConditionMode.If, 0.25f, "Reloading");

                    reloadAnim.AddTransition(upperAim, true);
                }
            //Fire
            if(fireAnimation)
                {
                    AnimatorState fireAnim = upperStateMachine.AddState("Fire");
                    fireAnim.motion = fireAnimation;

                    var aimToFireTranistion = upperAim.AddTransition(fireAnim, false);
                    aimToFireTranistion.AddCondition(UnityEditor.Animations.AnimatorConditionMode.If, 0.25f, "Fire");

                    fireAnim.AddTransition(upperAim, true);
                }
    }
Пример #21
0
 public static void AddChild(this BlendTree blendTree, Motion motion, Vector2 position, string parameter)
 {
     blendTree.AddChild(motion, position, 0.0f, parameter);
 }