/// <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(); }
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); }
// 歩行モーションを想定した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); }
// 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); }
/// <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); }
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); } }
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); }
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(); }
public static void AddChild(this BlendTree blendTree, Motion motion, float threshold, string parameter) { blendTree.AddChild(motion, Vector2.zero, threshold, parameter); }
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); } }
/// <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); }
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); } }
public static void AddChild(this BlendTree blendTree, Motion motion, Vector2 position, string parameter) { blendTree.AddChild(motion, position, 0.0f, parameter); }