Blend trees are used to blend continuously animation between their childs. They can either be 1D or 2D.
public override void OnInspectorGUI() { if (GUILayout.Button("Open Event Editor")) { MecanimEventEditor editor = EditorWindow.GetWindow <MecanimEventEditor>(); editor.TargetController = serializedObject.FindProperty("lastEdit").objectReferenceValue; } if (previewedMotion != null && previewedMotion is UnityEditor.Animations.BlendTree && avatarPreview != null) { EditorGUILayout.Separator(); GUILayout.Label("BlendTree Parameter(s)", GUILayout.ExpandWidth(true)); UnityEditor.Animations.BlendTree bt = previewedMotion as UnityEditor.Animations.BlendTree; for (int i = 0; i < bt.GetRecursiveBlendParamCount(); i++) { float min = bt.GetRecursiveBlendParamMin(i); float max = bt.GetRecursiveBlendParamMax(i); string paramName = bt.GetRecursiveBlendParam(i); float value = Mathf.Clamp(avatarPreview.Animator.GetFloat(paramName), min, max); value = EditorGUILayout.Slider(paramName, value, min, max); avatarPreview.Animator.SetFloat(paramName, value); } } }
private static AnimationClip GetFirstAnimationClipFromMotion(Motion motion) { AnimationClip animationClip = motion as AnimationClip; AnimationClip result; if (animationClip) { result = animationClip; } else { UnityEditor.Animations.BlendTree blendTree = motion as UnityEditor.Animations.BlendTree; if (blendTree) { AnimationClip[] animationClipsFlattened = blendTree.GetAnimationClipsFlattened(); if (animationClipsFlattened.Length > 0) { result = animationClipsFlattened[0]; return(result); } } result = null; } return(result); }
private List<AnimationClip> GetClipsFromStatemachine(UnityEditor.Animations.AnimatorStateMachine stateMachine) { List<AnimationClip> list = new List<AnimationClip>(); for (int i = 0; i != stateMachine.states.Length; ++i) { UnityEditor.Animations.ChildAnimatorState state = stateMachine.states[i]; if (state.state.motion is UnityEditor.Animations.BlendTree) { UnityEditor.Animations.BlendTree blendTree = state.state.motion as UnityEditor.Animations.BlendTree; ChildMotion[] childMotion = blendTree.children; for(int j = 0; j != childMotion.Length; ++j) { list.Add(childMotion[j].motion as AnimationClip); } } else if (state.state.motion != null) list.Add(state.state.motion as AnimationClip); } for (int i = 0; i != stateMachine.stateMachines.Length; ++i) { list.AddRange(GetClipsFromStatemachine(stateMachine.stateMachines[i].stateMachine)); } var distinctClips = list.Select(q => (AnimationClip)q).Distinct().ToList(); for (int i = 0; i < distinctClips.Count; i++) { if (distinctClips[i] && generateAnims.ContainsKey(distinctClips[i].name) == false) generateAnims.Add(distinctClips[i].name, true); } return list; }
private void ValidateLayerBlendTree(int index, AnimatorControllerLayer layer, AnimatorController controller) { string blendTreeName = string.Format(BlendTreeName, index); if (layer.stateMachine.states.All(s => s.state.name != blendTreeName)) { Debug.Log($"Layer missing blend tree. {blendTreeName}"); DeleteObjectFromController(controller, blendTreeName); AddBlendTree(index, layer, controller); } else { Debug.Log($"Layer Blend Tree Validated {blendTreeName}."); BlendTree blendTree = layer.stateMachine.states.FirstOrDefault(s => s.state.name == blendTreeName).state.motion as BlendTree; // Just re-assign since ChildMotions aren't their own ScriptableObjects. ChildMotion childMotion0 = new ChildMotion { motion = _clips0[index], timeScale = 1 }; ChildMotion childMotion1 = new ChildMotion { motion = _clips100[index], timeScale = 1 }; blendTree.children = new ChildMotion[2] { childMotion0, childMotion1 }; AssetDatabase.SaveAssets();; } }
private static void InitializeBlendTree(ref BlendTree tree, string name) { tree.name = name; tree.blendType = BlendTreeType.FreeformCartesian2D; tree.blendParameter = "FaceX"; tree.blendParameterY = "FaceY"; tree.hideFlags = HideFlags.HideInHierarchy; }
private void CreateMotionCallback(object obj) { UnityEditor.Animations.BlendTree tree = obj as UnityEditor.Animations.BlendTree; if (tree != null) { tree.AddChild(null); tree.SetDirectBlendTreeParameter(tree.children.Length - 1, this.m_Tool.animatorController.GetDefaultBlendTreeParameter()); } }
internal static void DestroyBlendTreeRecursive(BlendTree blendTree) { for (int index = 0; index < blendTree.children.Length; ++index) { BlendTree motion = blendTree.children[index].motion as BlendTree; if ((Object) motion != (Object) null && MecanimUtilities.AreSameAsset((Object) blendTree, (Object) motion)) MecanimUtilities.DestroyBlendTreeRecursive(motion); } Undo.DestroyObjectImmediate((Object) blendTree); }
public void Init(BlendTree blendTree, Animator animator) { this.m_BlendTree = blendTree; this.m_Animator = animator; this.m_Animator.logWarnings = false; this.m_Animator.fireEvents = false; this.m_Animator.enabled = false; this.m_Animator.cullingMode = AnimatorCullingMode.AlwaysAnimate; this.CreateStateMachine(); }
public void Init(BlendTree blendTree, Animator animator) { this.m_BlendTree = blendTree; if (this.m_AvatarPreview == null) { this.m_AvatarPreview = new AvatarPreview(animator, this.m_BlendTree); this.m_AvatarPreview.OnAvatarChangeFunc = new AvatarPreview.OnAvatarChange(this.OnPreviewAvatarChanged); this.m_PrevIKOnFeet = this.m_AvatarPreview.IKOnFeet; } this.CreateStateMachine(); }
internal static void DestroyBlendTreeRecursive(BlendTree blendTree) { for (int i = 0; i < blendTree.children.Length; i++) { BlendTree blendTree2 = blendTree.children[i].motion as BlendTree; if (blendTree2 != null && MecanimUtilities.AreSameAsset(blendTree, blendTree2)) { MecanimUtilities.DestroyBlendTreeRecursive(blendTree2); } } Undo.DestroyObjectImmediate(blendTree); }
internal static void DestroyBlendTreeRecursive(BlendTree blendTree) { for (int i = 0; i < blendTree.children.Length; i++) { BlendTree motion = blendTree.children[i].motion as BlendTree; if ((motion != null) && AreSameAsset(blendTree, motion)) { DestroyBlendTreeRecursive(motion); } } Undo.DestroyObjectImmediate(blendTree); }
internal BlendTree CreateBlendTreeChild(Vector2 position, float threshold) { Undo.RecordObject(this, "Created BlendTree Child"); BlendTree objectToAdd = new BlendTree { name = "BlendTree", hideFlags = HideFlags.HideInHierarchy }; if (AssetDatabase.GetAssetPath(this) != string.Empty) { AssetDatabase.AddObjectToAsset(objectToAdd, AssetDatabase.GetAssetPath(this)); } this.AddChild(objectToAdd, position, threshold); return objectToAdd; }
internal bool HasChild(BlendTree childTree, bool recursive) { foreach (ChildMotion motion in this.children) { if (motion.motion == childTree) { return true; } if ((recursive && (motion.motion is BlendTree)) && (motion.motion as BlendTree).HasChild(childTree, true)) { return true; } } return false; }
private void AddBlendTreeClips(UnityEditor.Animations.BlendTree blendTree, string name, string substate) { foreach (var child in blendTree.children) { if (child.motion is AnimationClip) { animationClips.Add(new AnimationGroup() { substate = substate, name = name, animationClip = child.motion as AnimationClip }); } else if (child.motion is UnityEditor.Animations.BlendTree) { AddBlendTreeClips(child.motion as UnityEditor.Animations.BlendTree, name, substate); } } }
private void HandleNodeInput(Node node) { Event current = Event.current; if (current.type == EventType.MouseDown && current.button == 0) { this.selection.Clear(); this.selection.Add(node); Selection.activeObject = node.motion; Node rootNode = this.blendTreeGraph.rootNode; if (current.clickCount == 2 && node.motion is UnityEditor.Animations.BlendTree && rootNode != node.motion) { this.selection.Clear(); Stack <Node> stack = new Stack <Node>(); Node node2 = node; while (node2.motion is UnityEditor.Animations.BlendTree && node2 != rootNode) { stack.Push(node2); node2 = node2.parent; } foreach (Node current2 in stack) { this.m_Tool.AddBreadCrumb(current2.motion); } } current.Use(); } if (current.type == EventType.MouseDown && current.button == 1) { GenericMenu genericMenu = new GenericMenu(); UnityEditor.Animations.BlendTree blendTree = node.motion as UnityEditor.Animations.BlendTree; if (blendTree) { genericMenu.AddItem(new GUIContent("Add Motion"), false, new GenericMenu.MenuFunction2(this.CreateMotionCallback), blendTree); genericMenu.AddItem(new GUIContent("Add Blend Tree"), false, new GenericMenu.MenuFunction2(this.CreateBlendTreeCallback), blendTree); } if (node != this.blendTreeGraph.rootNode) { genericMenu.AddItem(new GUIContent("Delete"), false, new GenericMenu.MenuFunction2(this.DeleteNodeCallback), node); } genericMenu.ShowAsContext(); Event.current.Use(); } }
private static AnimationClip GetFirstAnimationClipFromMotion(Motion motion) { AnimationClip clip = motion as AnimationClip; if (clip != null) { return(clip); } UnityEditor.Animations.BlendTree tree = motion as UnityEditor.Animations.BlendTree; if (tree != null) { AnimationClip[] animationClipsFlattened = tree.GetAnimationClipsFlattened(); if (animationClipsFlattened.Length > 0) { return(animationClipsFlattened[0]); } } return(null); }
private void CreateParameters() { int parameterCount = 0;// controller.parameterCount; for (int i = 0; i < parameterCount; i++) { controller.RemoveParameter(0); } if (previewedMotion is UnityEditor.Animations.BlendTree) { UnityEditor.Animations.BlendTree blendTree = previewedMotion as UnityEditor.Animations.BlendTree; for (int j = 0; j < blendTree.GetRecursiveBlendParamCount(); j++) { //controller.AddParameter(blendTree.GetRecursiveBlendParam(j), AnimatorControllerParameterType.Float); } } }
private void HandleNodeInput(UnityEditor.Graphs.AnimationBlendTree.Node node) { Event current = Event.current; if ((current.type == EventType.MouseDown) && (current.button == 0)) { base.selection.Clear(); base.selection.Add(node); Selection.activeObject = node.motion; UnityEditor.Graphs.AnimationBlendTree.Node rootNode = this.blendTreeGraph.rootNode; if (((current.clickCount == 2) && (node.motion is UnityEditor.Animations.BlendTree)) && (rootNode != node.motion)) { base.selection.Clear(); Stack <UnityEditor.Graphs.AnimationBlendTree.Node> stack = new Stack <UnityEditor.Graphs.AnimationBlendTree.Node>(); for (UnityEditor.Graphs.AnimationBlendTree.Node node3 = node; (node3.motion is UnityEditor.Animations.BlendTree) && (node3 != rootNode); node3 = node3.parent) { stack.Push(node3); } foreach (UnityEditor.Graphs.AnimationBlendTree.Node node4 in stack) { this.m_Tool.AddBreadCrumb(node4.motion); } } current.Use(); } if ((current.type == EventType.MouseDown) && (current.button == 1)) { GenericMenu menu = new GenericMenu(); UnityEditor.Animations.BlendTree motion = node.motion as UnityEditor.Animations.BlendTree; if (motion != null) { menu.AddItem(new GUIContent("Add Motion"), false, new GenericMenu.MenuFunction2(this.CreateMotionCallback), motion); menu.AddItem(new GUIContent("Add Blend Tree"), false, new GenericMenu.MenuFunction2(this.CreateBlendTreeCallback), motion); } if (node != this.blendTreeGraph.rootNode) { menu.AddItem(new GUIContent("Delete"), false, new GenericMenu.MenuFunction2(this.DeleteNodeCallback), node); } menu.ShowAsContext(); Event.current.Use(); } }
private void CreateBlendTreeCallback(object obj) { UnityEditor.Animations.BlendTree tree = obj as UnityEditor.Animations.BlendTree; if (tree != null) { UnityEditor.Animations.BlendTree tree2 = tree.CreateBlendTreeChild((float)0f); if ((this.m_Tool != null) && (this.m_Tool.animatorController != null)) { string defaultBlendTreeParameter = this.m_Tool.animatorController.GetDefaultBlendTreeParameter(); tree2.blendParameterY = defaultBlendTreeParameter; tree2.blendParameter = defaultBlendTreeParameter; tree.SetDirectBlendTreeParameter(tree.children.Length - 1, this.m_Tool.animatorController.GetDefaultBlendTreeParameter()); } else { tree2.blendParameter = tree.blendParameter; tree2.blendParameterY = tree.blendParameterY; } } }
private bool IsBlendTreeUsingHumanoid(UnityEditor.Animations.BlendTree blendTree) { ChildMotion[] children = blendTree.children; for (int i = 0; i < children.Length; i++) { Motion motion = children[i].motion; if (motion is AnimationClip) { AnimationClip clip = motion as AnimationClip; if (clip.humanMotion) { return(true); } } else if ((motion is UnityEditor.Animations.BlendTree) && this.IsBlendTreeUsingHumanoid(motion as UnityEditor.Animations.BlendTree)) { return(true); } } return(false); }
static AnimationClip GetFirstAnimationClipFromMotion(Motion motion) { AnimationClip clip = motion as AnimationClip; if (clip) { return(clip); } Animations.BlendTree blendTree = motion as Animations.BlendTree; if (blendTree) { AnimationClip[] clips = blendTree.GetAnimationClipsFlattened(); if (clips.Length > 0) { return(clips[0]); } } return(null); }
private static AnimationClip GetFirstAvailableClip(Motion motion) { AnimationClip clip = motion as AnimationClip; if (clip != null) { return(clip); } BlendTree tree = motion as BlendTree; if (tree != null) { foreach (ChildMotion childMotion in tree.children) { // Should we be worried about `cycleOffset`? https://docs.unity3d.com/ScriptReference/Animations.AnimatorState-cycleOffset.html var child = childMotion.motion; BlendTree childTree = child as BlendTree; if (childTree != null) { var childClip = GetFirstAvailableClip(childTree); if (childClip != null) { return(childClip); } } else { AnimationClip childClip = child as AnimationClip; if (childClip != null) { return(childClip); } } } } return(null); }
private void CreateBlendTreeCallback(object obj) { UnityEditor.Animations.BlendTree blendTree = obj as UnityEditor.Animations.BlendTree; if (!blendTree) { return; } UnityEditor.Animations.BlendTree blendTree2 = blendTree.CreateBlendTreeChild(0f); if (this.m_Tool && this.m_Tool.animatorController != null) { UnityEditor.Animations.BlendTree arg_5F_0 = blendTree2; string defaultBlendTreeParameter = this.m_Tool.animatorController.GetDefaultBlendTreeParameter(); blendTree2.blendParameterY = defaultBlendTreeParameter; arg_5F_0.blendParameter = defaultBlendTreeParameter; blendTree.SetDirectBlendTreeParameter(blendTree.children.Length - 1, this.m_Tool.animatorController.GetDefaultBlendTreeParameter()); } else { blendTree2.blendParameter = blendTree.blendParameter; blendTree2.blendParameterY = blendTree.blendParameterY; } }
private void AddNewBlendTreeCallback() { BlendTree stateEffectiveMotion = AnimatorControllerTool.tool.animatorController.GetStateEffectiveMotion(this.state, AnimatorControllerTool.tool.selectedLayerIndex) as BlendTree; AnimatorStateMachine stateMachine = AnimatorControllerTool.tool.animatorController.layers[AnimatorControllerTool.tool.selectedLayerIndex].stateMachine; bool flag = true; if (stateEffectiveMotion != null) { string title = "This will delete current BlendTree in state."; string message = "You cannot undo this action."; if (EditorUtility.DisplayDialog(title, message, "Delete", "Cancel")) { MecanimUtilities.DestroyBlendTreeRecursive(stateEffectiveMotion); } else { flag = false; } } else { Undo.RegisterCompleteObjectUndo(stateMachine, "Blend Tree Added"); } if (flag) { BlendTree objectToAdd = new BlendTree { hideFlags = HideFlags.HideInHierarchy }; if (AssetDatabase.GetAssetPath(AnimatorControllerTool.tool.animatorController) != "") { AssetDatabase.AddObjectToAsset(objectToAdd, AssetDatabase.GetAssetPath(AnimatorControllerTool.tool.animatorController)); } objectToAdd.name = "Blend Tree"; string defaultBlendTreeParameter = AnimatorControllerTool.tool.animatorController.GetDefaultBlendTreeParameter(); objectToAdd.blendParameterY = defaultBlendTreeParameter; objectToAdd.blendParameter = defaultBlendTreeParameter; AnimatorControllerTool.tool.animatorController.SetStateEffectiveMotion(this.state, objectToAdd, AnimatorControllerTool.tool.selectedLayerIndex); } }
private void AddBlendTree(int index, AnimatorControllerLayer layer, AnimatorController controller) { string controllerPath = AssetDatabase.GetAssetPath(controller); string blendTreeName = string.Format(BlendTreeName, index); AnimatorState state = layer.stateMachine.AddState(blendTreeName); state.speed = 1; BlendTree blendTree = new BlendTree { name = blendTreeName, blendType = BlendTreeType.Simple1D, blendParameter = AvaCryptKeyNames[index], }; ChildMotion childMotion0 = new ChildMotion { motion = _clips0[index], timeScale = 1 }; ChildMotion childMotion1 = new ChildMotion { motion = _clips100[index], timeScale = 1 }; blendTree.children = new ChildMotion[2] { childMotion0, childMotion1 }; state.motion = blendTree; AssetDatabase.AddObjectToAsset(blendTree, controllerPath); AssetDatabase.SaveAssets(); }
private static List <AnimClipData> GetClipsFromStatemachine(UnityEditor.Animations.AnimatorStateMachine stateMachine) { List <AnimClipData> list = new List <AnimClipData>(); for (int i = 0; i != stateMachine.states.Length; ++i) { UnityEditor.Animations.ChildAnimatorState state = stateMachine.states[i]; if (state.state.motion is UnityEditor.Animations.BlendTree) { UnityEditor.Animations.BlendTree blendTree = state.state.motion as UnityEditor.Animations.BlendTree; ChildMotion[] childMotion = blendTree.children; for (int j = 0; j != childMotion.Length; ++j) { AnimClipData clipData = new AnimClipData(); clipData.clip = childMotion[j].motion as AnimationClip; clipData.speed = 1; list.Add(clipData); } } else if (state.state.motion != null) { AnimClipData clipData = new AnimClipData(); clipData.clip = state.state.motion as AnimationClip; clipData.speed = state.state.speed; list.Add(clipData); } } for (int i = 0; i != stateMachine.stateMachines.Length; ++i) { list.AddRange(GetClipsFromStatemachine(stateMachine.stateMachines[i].stateMachine)); } list = list.Select(q => (AnimClipData)q).Distinct().ToList(); return(list); }
private void FillAnimatorState(int depth, UnityEditor.Animations.AnimatorStateMachine stateMachine) { foreach (var sta in stateMachine.stateMachines) { Debug.Log("Depth=" + depth + " stateMachines " + sta.stateMachine); FillAnimatorState(depth + 1, sta.stateMachine); } foreach (UnityEditor.Animations.ChildAnimatorState sta in stateMachine.states) { UnityEditor.Animations.BlendTree blendTree = sta.state.motion as UnityEditor.Animations.BlendTree; if (blendTree != null) { Debug.LogError("Depth=" + depth + " blendTree need to be refined" + sta.state.motion); int mCount = blendTree.children.Length; //foreach (var cmotion in blendTree.children) for (int i = 0; i < mCount; i++) { Debug.Log("Blend Clip " + blendTree.children[i].motion); Vector2 position = blendTree.children[i].position; blendTree.AddChild(emptyClip, position); } for (int i = 0; i < mCount; i++) { blendTree.RemoveChild(0); } sta.state.motion = blendTree; } else { Debug.Log("Depth=" + depth + " Clip " + sta.state.motion); sta.state.motion = emptyClip; } } }
internal BlendTree CreateBlendTreeChild(Vector2 position, float threshold) { Undo.RecordObject((Object) this, "Created BlendTree Child"); BlendTree blendTree = new BlendTree(); blendTree.name = "BlendTree"; blendTree.hideFlags = HideFlags.HideInHierarchy; if (AssetDatabase.GetAssetPath((Object) this) != string.Empty) AssetDatabase.AddObjectToAsset((Object) blendTree, AssetDatabase.GetAssetPath((Object) this)); this.AddChild((Motion) blendTree, position, threshold); return blendTree; }
internal bool HasChild(BlendTree childTree, bool recursive) { foreach (ChildMotion child in this.children) { if ((Object) child.motion == (Object) childTree || recursive && child.motion is BlendTree && (child.motion as BlendTree).HasChild(childTree, true)) return true; } return false; }
private void traverseStateInfo(int depth, string path, UnityEditor.Animations.AnimatorStateMachine stateMachine, string speedParameter) { foreach (var sta in stateMachine.stateMachines) { //Debug.Log("Depth=" + depth + " stateMachines " + sta.stateMachine); string newPath = path; newPath = newPath + sta.stateMachine.name + "->"; traverseStateInfo(depth + 1, newPath, sta.stateMachine, speedParameter); } foreach (UnityEditor.Animations.ChildAnimatorState sta in stateMachine.states) { string tag = sta.state.tag; if (sta.state.speedParameter != speedParameter) { sta.state.speedParameter = speedParameter; if (speedParameter != "") { sta.state.speedParameterActive = true; } } if (tag != "") { if (!tagCount.ContainsKey(tag)) { tagCount[tag] = new List <string>(); } tagCount[tag].Add(path + sta.state.name); } UnityEditor.Animations.BlendTree blendTree = sta.state.motion as UnityEditor.Animations.BlendTree; if (blendTree != null) { int mCount = blendTree.children.Length; foreach (var cmotion in blendTree.children) //for (int i = 0; i < mCount; i++) { //Debug.Log("Blend Clip " + blendTree.children[i].motion); //if (blendTree.children[i].motion!=null && !bCheckClipName(blendTree.children[i].motion.name)) if (cmotion.motion != null && !bCheckClipName(cmotion.motion.name)) { Debug.LogError(path + "下" + blendTree.name + "的动作" + cmotion.motion.name + "的前缀名和其他动作不同,是不是把其他人物的动作给拖进来了?"); } } } else { if (sta.state.tag == "BlendAttack") { Debug.LogError(path + "下的动作" + sta.state.motion.name + "配置了BlendAttack,它的动作必须是一个BlendTree,请检查"); } if (sta.state.motion != null) { if (!bCheckClipName(sta.state.motion.name)) { Debug.LogError(path + "下的动作" + sta.state.motion.name + "的前缀名和其他动作不同,是不是把其他人物的动作给拖进来了?"); } } } } }
public static float GetRecursiveBlendParamMin(this UnityEditor.Animations.BlendTree bt, int index) { object val = bt.GetType().GetMethod("GetRecursiveBlendParameterMin", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public).Invoke(bt, new object[] { index }); return((float)val); }
public BlendTree() { BlendTree.Internal_Create(this); }
void CreateAnimatorByConfig(AnimatorControllerConfig animatorControllerConfig) { if (animatorControllerConfig != null) { Debug.Log("target = " + target); Undo.RecordObject(target, "animatorController"); // 支持撤销 add by TangJian 2018/04/16 15:41:34 AnimatorController animatorController = target as AnimatorController; AnimationClip[] animationClips = animatorController.animationClips; AnimatorControllerLayer[] animatorControllerLayers = animatorController.layers; AnimatorStateMachine animatorStateMachine = animatorControllerLayers[0].stateMachine; string animatorControllerPath = AssetDatabase.GetAssetPath(animatorController); Object[] clips = AssetDatabase.LoadAllAssetRepresentationsAtPath(animatorControllerPath); animatorController.parameters = null; foreach (var parameterConfig in animatorControllerConfig.parameters) { animatorController.AddParameter(parameterConfig.name, parameterConfig.type); } // 添加所有状态 add by TangJian 2018/04/17 20:08:41 foreach (var stateConfig in animatorControllerConfig.states) { var state = animatorStateMachine.AddStateEx(stateConfig.name); state.behaviours = null; state.transitions = null; // 清空所有状态 add by TangJian 2018/04/17 20:45:08 state.tag = stateConfig.tag; state.speed = stateConfig.Speed; CountsThrow(clips, stateConfig.animName); state.motion = clips.First(o => o.name == stateConfig.animName) as Motion; if (state.motion is AnimationClip animationClip) { AnimationClipSettings animationClipSettings = AnimationUtility.GetAnimationClipSettings(animationClip); animationClipSettings.loopTime = stateConfig.loop; AnimationUtility.SetAnimationClipSettings(animationClip, animationClipSettings); } // 添加BlendTree if (stateConfig.blendTree != null) { if (state.motion is UnityEditor.Animations.BlendTree) { UnityEditor.Animations.BlendTree blendTree = state.motion as UnityEditor.Animations.BlendTree; // BlendTree属性设置 add by TangJian 2018/9/18 18:06 blendTree.name = "blendTree_" + state.name; blendTree.blendParameter = stateConfig.blendTree.blendParameter; blendTree.useAutomaticThresholds = stateConfig.blendTree.useAutomaticThresholds; List <UnityEditor.Animations.ChildMotion> addChildMotionList = new List <UnityEditor.Animations.ChildMotion>(); foreach (var childMotionConfig in stateConfig.blendTree.childMotions) { UnityEditor.Animations.ChildMotion childMotion = new UnityEditor.Animations.ChildMotion(); childMotion.threshold = childMotionConfig.threshold; childMotion.timeScale = childMotionConfig.timeScale; addChildMotionList.Add(childMotion); } var oldBlendTree = state.motion as UnityEditor.Animations.BlendTree; var oldChildren = oldBlendTree.children; var newChildren = new List <UnityEditor.Animations.ChildMotion>(); // 更新oldChildren add by TangJian 2018/9/18 18:07 for (int i = 0; i < oldChildren.Length; i++) { if (i < addChildMotionList.Count) { oldChildren[i].threshold = addChildMotionList[i].threshold; oldChildren[i].timeScale = addChildMotionList[i].timeScale; } } // 添加oldChildren中的motion到newChildren add by TangJian 2018/9/18 18:08 foreach (var item in oldChildren) { newChildren.Add(item); } // 添加剩余addChildMotionList中的motion到newChildren add by TangJian 2018/9/18 18:08 if (blendTree.children.Length > oldChildren.Length) { for (int i = oldChildren.Length; i < blendTree.children.Length; i++) { newChildren.Add(blendTree.children[i]); } } blendTree.children = newChildren.ToArray(); if (stateConfig.blendTree.useAutomaticThresholds) { if (stateConfig.blendTree.minThreshold > int.MinValue && stateConfig.blendTree.maxThreshold > int.MinValue) { blendTree.minThreshold = stateConfig.blendTree.minThreshold; blendTree.maxThreshold = stateConfig.blendTree.maxThreshold; } else { blendTree.minThreshold = 0; blendTree.maxThreshold = blendTree.children.Length - 1; } } state.motion = blendTree; } else { state.motion = GetBlendTreeToMotion(animatorController, "blendTree_" + state.name, stateConfig.blendTree); } } if (stateConfig.script != null) { if (stateConfig.script == "RoleHide") { state.AddStateMachineBehaviour <RoleHideStateMachineBehaviour>(); } } } // 添加额外的跳转 add by TangJian 2018/04/17 20:20:52 foreach (var transitionConfig in animatorControllerConfig.transitions) { if (transitionConfig.sourceAnimName == "Any") { foreach (var stateConfig in animatorControllerConfig.states) { var fromState = animatorStateMachine.GetState(stateConfig.name); var toState = animatorStateMachine.GetState(transitionConfig.destinationAnimName); if (fromState != null && toState != null) { fromState.AddTransitionEx(toState, transitionConfig); } } } else { var fromState = animatorStateMachine.GetState(transitionConfig.sourceAnimName); var toState = animatorStateMachine.GetState(transitionConfig.destinationAnimName); if (fromState != null && toState != null) { fromState.AddTransitionEx(toState, transitionConfig); } } } // 添加状态的跳转 add by TangJian 2018/04/17 20:11:08 foreach (var stateConfig in animatorControllerConfig.states) { // 添加状态的跳转 add by TangJian 2018/04/17 20:11:39 foreach (var transitionConfig in stateConfig.transitions) { var fromState = animatorStateMachine.GetState(stateConfig.name); var toState = animatorStateMachine.GetState(transitionConfig.destinationAnimName); if (fromState != null && toState != null) { fromState.AddTransitionEx(toState, transitionConfig); } } } // 添加脚本 add by TangJian 2018/04/17 21:16:02 foreach (var stateConfig in animatorControllerConfig.states) { var state = animatorStateMachine.GetState(stateConfig.name); RoleBehaviour roleBehaviour = state.AddStateMachineBehaviour <RoleBehaviour>(); // 限制状态可以执行到的时间 add by TangJian 2019/5/14 10:35 roleBehaviour.StateDuration = stateConfig.duration; if (state.motion != null) { if (state.motion is UnityEditor.Animations.BlendTree) { var blendTree = state.motion as UnityEditor.Animations.BlendTree; if (blendTree.children.Length != 0) { FrameEventBehaviour frameEventBehaviour = state.AddStateMachineBehaviour <FrameEventBehaviour>(); Motion motion = blendTree.children[0].motion; if (motion != null) { frameEventBehaviour.animName = motion.name; frameEventBehaviour.Parameter = blendTree.blendParameter; frameEventBehaviour.namelist.Clear(); frameEventBehaviour.beginTime = stateConfig.beginTime; frameEventBehaviour.endTime = stateConfig.endTime; for (int i = 0; i < blendTree.children.Length; i++) { UnityEditor.Animations.ChildMotion child = blendTree.children[i]; Motion childmotion = blendTree.children[i].motion; if (childmotion != null && string.IsNullOrWhiteSpace(childmotion.name) == false) { // frameEventBehaviour.namelist.Insert(i, childmotion.name); frameEventBehaviour.floatList.Insert(i, child.threshold); } } } } } else { FrameEventBehaviour frameEventBehaviour = state.AddStateMachineBehaviour <FrameEventBehaviour>(); Motion motion = state.motion; frameEventBehaviour.animName = motion.name; if (motion is AnimationClip animationClip) { frameEventBehaviour.beginTime = stateConfig.beginTime / animationClip.length; frameEventBehaviour.endTime = stateConfig.endTime / animationClip.length; } } } state.AddStateMachineBehaviour <HumanMoveXYByAnimBehaviour>(); if (state.tag == "attack") { state.AddStateMachineBehaviour <HumanMainHandAttackBehaviour>(); } if (state.name == "jump_1") { state.AddStateMachineBehaviour <RolePreJumpBehaviour>(); } if (state.name == "JumpPre") { state.AddStateMachineBehaviour <RolePreJumpBehaviour>(); } if (state.tag == "hurtHold") { state.AddStateMachineBehaviour <RoleHurtHoldStateMachineBehaviour>(); } if (stateConfig.behaviours != null) { foreach (var item in stateConfig.behaviours) { MethodDelegate <bool> func = CSScript.CreateFunc <bool>( @" using Tang; bool Sum(UnityEditor.Animations.AnimatorState state) { state.AddStateMachineBehaviour<" + item + @" > (); return true; }"); func(state); } } } // 记录未使用的状态 add by TangJian 2018/04/19 14:36:28 List <UnityEditor.Animations.AnimatorState> unuseAnimatorStates = new List <UnityEditor.Animations.AnimatorState>(); foreach (var state in animatorStateMachine.states) { int index = animatorControllerConfig.states.FindIndex((AnimatorState a) => { return(a.name == state.state.name); }); if (index < 0) { unuseAnimatorStates.Add(state.state); } } // 移除未使用的状态 add by TangJian 2018/04/19 14:38:34 foreach (var state in unuseAnimatorStates) { animatorStateMachine.RemoveState(state); } // 整理状态机位置 add by TangJian 2018/04/19 14:40:00 ChildAnimatorState[] childAnimatorStates = animatorStateMachine.states; int cols = 3; for (int i = 0; i < childAnimatorStates.Length; i++) { float x = (i % cols) * 204; float y = (i / cols) * 50; childAnimatorStates[i].position = new Vector3(x, y, 0); } animatorStateMachine.states = childAnimatorStates; // 保存生成的状态机 add by TangJian 2019/1/30 17:21 EditorUtility.SetDirty(animatorController); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); } SupportEventDispatch(); }
private static extern void Internal_Create(BlendTree mono);
public static float GetRecursiveBlendParamMin(this UnityEditor.Animations.BlendTree bt, int index) { object val = GetRecursiveBlendParameterMin_MethodInfo.Invoke(bt, new object[] { index }); return((float)val); }
public static string GetRecursiveBlendParam(this UnityEditor.Animations.BlendTree bt, int index) { object val = GetRecursiveBlendParameter_MethodInfo.Invoke(bt, new object[] { index }); return((string)val); }
public override void NodeGUI(UnityEditor.Graphs.Node n) { UnityEditor.Graphs.AnimationBlendTree.Node node = n as UnityEditor.Graphs.AnimationBlendTree.Node; UnityEditor.Animations.BlendTree motion = node.motion as UnityEditor.Animations.BlendTree; GUILayoutOption[] options = new GUILayoutOption[] { GUILayout.Width(200f) }; GUILayout.BeginVertical(options); foreach (Slot slot in n.inputSlots) { base.LayoutSlot(slot, this.LimitStringWidth(slot.title, 180f, UnityEditor.Graphs.Styles.varPinIn), false, false, false, UnityEditor.Graphs.Styles.varPinIn); } foreach (Slot slot2 in n.outputSlots) { base.LayoutSlot(slot2, this.LimitStringWidth(slot2.title, 180f, UnityEditor.Graphs.Styles.varPinOut), false, false, false, UnityEditor.Graphs.Styles.varPinOut); } n.NodeUI(this); EditorGUIUtility.labelWidth = 50f; if (motion != null) { if (motion.recursiveBlendParameterCount > 0) { for (int i = 0; i < motion.recursiveBlendParameterCount; i++) { string recursiveBlendParameter = motion.GetRecursiveBlendParameter(i); float recursiveBlendParameterMin = motion.GetRecursiveBlendParameterMin(i); float recursiveBlendParameterMax = motion.GetRecursiveBlendParameterMax(i); EventType type = Event.current.type; if ((Event.current.button != 0) && Event.current.isMouse) { Event.current.type = EventType.Ignore; } if (Mathf.Approximately(recursiveBlendParameterMax, recursiveBlendParameterMin)) { recursiveBlendParameterMax = recursiveBlendParameterMin + 1f; } EditorGUI.BeginChangeCheck(); float parameterValue = EditorGUILayout.Slider(GUIContent.Temp(recursiveBlendParameter, recursiveBlendParameter), this.blendTreeGraph.GetParameterValue(recursiveBlendParameter), recursiveBlendParameterMin, recursiveBlendParameterMax, new GUILayoutOption[0]); if (EditorGUI.EndChangeCheck()) { this.blendTreeGraph.SetParameterValue(recursiveBlendParameter, parameterValue); InspectorWindow.RepaintAllInspectors(); } if (Event.current.button != 0) { Event.current.type = type; } } } else { EditorGUILayout.LabelField("No blend parameter to display", new GUILayoutOption[0]); } if (node.animator != null) { List <UnityEditor.Graphs.Edge> list = new List <UnityEditor.Graphs.Edge>(n.outputEdges); node.UpdateAnimator(); if (this.m_Weights.Length != list.Count) { this.m_Weights = new float[list.Count]; } BlendTreePreviewUtility.GetRootBlendTreeChildWeights(node.animator, 0, node.animator.GetCurrentAnimatorStateInfo(0).fullPathHash, this.m_Weights); for (int j = 0; j < list.Count; j++) { UnityEditor.Graphs.AnimationBlendTree.Node node2 = list[j].toSlot.node as UnityEditor.Graphs.AnimationBlendTree.Node; node2.weight = node.weight * this.m_Weights[j]; list[j].color = node2.weightEdgeColor; } } } GUILayout.EndVertical(); this.HandleNodeInput(n as UnityEditor.Graphs.AnimationBlendTree.Node); }
public static int GetRecursiveBlendParamCount(this UnityEditor.Animations.BlendTree bt) { object val = bt.GetType().GetProperty("recursiveBlendParameterCount", BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.NonPublic | BindingFlags.Public).GetValue(bt, new object[] {}); return((int)val); }
public AnimatorState CreateBlendTreeInController(string name, out BlendTree tree) { return(this.CreateBlendTreeInController(name, out tree, 0)); }
private void Init() { if (BlendTreeInspector.styles == null) BlendTreeInspector.styles = new BlendTreeInspector.Styles(); if ((UnityEngine.Object) this.m_BlendTree == (UnityEngine.Object) null) this.m_BlendTree = this.target as UnityEditor.Animations.BlendTree; if (BlendTreeInspector.styles == null) BlendTreeInspector.styles = new BlendTreeInspector.Styles(); if (this.m_PreviewBlendTree == null) this.m_PreviewBlendTree = new PreviewBlendTree(); if (this.m_VisBlendTree == null) this.m_VisBlendTree = new VisualizationBlendTree(); if (this.m_Childs == null) { this.m_Childs = this.serializedObject.FindProperty("m_Childs"); this.m_ReorderableList = new ReorderableList(this.serializedObject, this.m_Childs); this.m_ReorderableList.drawHeaderCallback = new ReorderableList.HeaderCallbackDelegate(this.DrawHeader); this.m_ReorderableList.drawElementCallback = new ReorderableList.ElementCallbackDelegate(this.DrawChild); this.m_ReorderableList.onReorderCallback = new ReorderableList.ReorderCallbackDelegate(this.EndDragChild); this.m_ReorderableList.onAddDropdownCallback = new ReorderableList.AddDropdownCallbackDelegate(this.AddButton); this.m_ReorderableList.onRemoveCallback = new ReorderableList.RemoveCallbackDelegate(this.RemoveButton); if (this.m_BlendType.intValue == 0) this.SortByThreshold(); this.m_ShowGraphValue = this.m_BlendType.intValue != 4 ? this.m_Childs.arraySize >= 2 : this.m_Childs.arraySize >= 1; this.m_ShowGraph.value = this.m_ShowGraphValue; this.m_ShowAdjust.value = this.AllMotions(); this.m_ShowCompute.value = !this.m_UseAutomaticThresholds.boolValue; this.m_ShowGraph.valueChanged.AddListener(new UnityAction(((Editor) this).Repaint)); this.m_ShowAdjust.valueChanged.AddListener(new UnityAction(((Editor) this).Repaint)); this.m_ShowCompute.valueChanged.AddListener(new UnityAction(((Editor) this).Repaint)); } this.m_PreviewBlendTree.Init(this.m_BlendTree, BlendTreeInspector.currentAnimator); bool flag = false; if ((UnityEngine.Object) this.m_VisInstance == (UnityEngine.Object) null) { this.m_VisInstance = EditorUtility.InstantiateForAnimatorPreview(EditorGUIUtility.Load("Avatar/DefaultAvatar.fbx")); foreach (Renderer componentsInChild in this.m_VisInstance.GetComponentsInChildren<Renderer>()) componentsInChild.enabled = false; flag = true; } this.m_VisBlendTree.Init(this.m_BlendTree, this.m_VisInstance.GetComponent<Animator>()); if (!flag || this.m_BlendType.intValue != 1 && this.m_BlendType.intValue != 2 && this.m_BlendType.intValue != 3) return; this.UpdateBlendVisualization(); this.ValidatePositions(); }
public UnityEditor.Animations.BlendTree GetBlendTreeToMotion(AnimatorController animatorController, string name, BlendTree blendTreeConfig) { UnityEditor.Animations.BlendTree blendTree = new UnityEditor.Animations.BlendTree(); blendTree.name = name; List <UnityEditor.Animations.ChildMotion> childMotionList = new List <UnityEditor.Animations.ChildMotion>(); for (int i = 0; i < blendTreeConfig.childMotions.Count; i++) { var childMotionConfig = blendTreeConfig.childMotions[i]; if (childMotionConfig.blendTree != null && string.IsNullOrWhiteSpace(childMotionConfig.blendTree.blendParameter) == false) { UnityEditor.Animations.ChildMotion childMotion = new UnityEditor.Animations.ChildMotion(); childMotion.threshold = childMotionConfig.threshold; childMotion.timeScale = childMotionConfig.timeScale; childMotion.motion = GetBlendTreeToMotion(animatorController, blendTree.name + "_" + i, childMotionConfig.blendTree); childMotionList.Add(childMotion); } else { UnityEditor.Animations.ChildMotion childMotion = new UnityEditor.Animations.ChildMotion(); childMotion.threshold = childMotionConfig.threshold; childMotion.timeScale = childMotionConfig.timeScale; childMotionList.Add(childMotion); } } blendTree.children = childMotionList.ToArray(); blendTree.blendParameter = blendTreeConfig.blendParameter; blendTree.useAutomaticThresholds = blendTreeConfig.useAutomaticThresholds; if (blendTreeConfig.useAutomaticThresholds) { if (blendTreeConfig.minThreshold > int.MinValue && blendTreeConfig.maxThreshold > int.MinValue) { blendTree.minThreshold = blendTreeConfig.minThreshold; blendTree.maxThreshold = blendTreeConfig.maxThreshold; } else { blendTree.minThreshold = 0; blendTree.maxThreshold = blendTree.children.Length - 1; } } if (AssetDatabase.GetAssetPath(animatorController) != "") { var objList = AssetDatabase.LoadAllAssetRepresentationsAtPath(AssetDatabase.GetAssetPath(animatorController)); foreach (var item in objList) { if (item != null && blendTree.name == item.name) { DestroyImmediate(item, true); } } AssetDatabase.AddObjectToAsset(blendTree, AssetDatabase.GetAssetPath(animatorController)); Debug.Log(AssetDatabase.GetAssetPath(blendTree)); } return(blendTree); }
public static int GetRecursiveBlendParamCount(this UnityEditor.Animations.BlendTree bt) { object val = GetRecursiveBlendParameterCount_PropertyInfo.GetValue(bt, new object[] {}); return((int)val); }
private void Init() { if (BlendTreeInspector.styles == null) { BlendTreeInspector.styles = new BlendTreeInspector.Styles(); } if (this.m_BlendTree == null) { this.m_BlendTree = (this.target as UnityEditor.Animations.BlendTree); } if (BlendTreeInspector.styles == null) { BlendTreeInspector.styles = new BlendTreeInspector.Styles(); } if (this.m_PreviewBlendTree == null) { this.m_PreviewBlendTree = new PreviewBlendTree(); } if (this.m_VisBlendTree == null) { this.m_VisBlendTree = new VisualizationBlendTree(); } if (this.m_Childs == null) { this.m_Childs = base.serializedObject.FindProperty("m_Childs"); this.m_ReorderableList = new ReorderableList(base.serializedObject, this.m_Childs); this.m_ReorderableList.drawHeaderCallback = new ReorderableList.HeaderCallbackDelegate(this.DrawHeader); this.m_ReorderableList.drawElementCallback = new ReorderableList.ElementCallbackDelegate(this.DrawChild); this.m_ReorderableList.onReorderCallback = new ReorderableList.ReorderCallbackDelegate(this.EndDragChild); this.m_ReorderableList.onAddDropdownCallback = new ReorderableList.AddDropdownCallbackDelegate(this.AddButton); this.m_ReorderableList.onRemoveCallback = new ReorderableList.RemoveCallbackDelegate(this.RemoveButton); if (this.m_BlendType.intValue == 0) { this.SortByThreshold(); } this.m_ShowGraphValue = ((this.m_BlendType.intValue != 4) ? (this.m_Childs.arraySize >= 2) : (this.m_Childs.arraySize >= 1)); this.m_ShowGraph.value = this.m_ShowGraphValue; this.m_ShowAdjust.value = this.AllMotions(); this.m_ShowCompute.value = !this.m_UseAutomaticThresholds.boolValue; this.m_ShowGraph.valueChanged.AddListener(new UnityAction(base.Repaint)); this.m_ShowAdjust.valueChanged.AddListener(new UnityAction(base.Repaint)); this.m_ShowCompute.valueChanged.AddListener(new UnityAction(base.Repaint)); } this.m_PreviewBlendTree.Init(this.m_BlendTree, BlendTreeInspector.currentAnimator); bool flag = false; if (this.m_VisInstance == null) { GameObject original = (GameObject)EditorGUIUtility.Load("Avatar/DefaultAvatar.fbx"); this.m_VisInstance = EditorUtility.InstantiateForAnimatorPreview(original); Renderer[] componentsInChildren = this.m_VisInstance.GetComponentsInChildren<Renderer>(); for (int i = 0; i < componentsInChildren.Length; i++) { Renderer renderer = componentsInChildren[i]; renderer.enabled = false; } flag = true; } this.m_VisBlendTree.Init(this.m_BlendTree, this.m_VisInstance.GetComponent<Animator>()); if (flag && (this.m_BlendType.intValue == 1 || this.m_BlendType.intValue == 2 || this.m_BlendType.intValue == 3)) { this.UpdateBlendVisualization(); this.ValidatePositions(); } }
internal bool HasChild(BlendTree childTree, bool recursive) { ChildMotion[] children = this.children; for (int i = 0; i < children.Length; i++) { ChildMotion childMotion = children[i]; if (childMotion.motion == childTree) { return true; } if (recursive && childMotion.motion is BlendTree && (childMotion.motion as BlendTree).HasChild(childTree, true)) { return true; } } return false; }