public override void OnRowGUI(Rect rowRect, TreeViewItem node, int row, bool selected, bool focused) { bool propertyPathMismatchWithHumanAvatar = false; AddCurvesPopupGameObjectNode addCurvesPopupNode = node as AddCurvesPopupGameObjectNode; if (addCurvesPopupNode != null) { propertyPathMismatchWithHumanAvatar = addCurvesPopupNode.disabled; } using (new EditorGUI.DisabledScope(propertyPathMismatchWithHumanAvatar)) { base.OnRowGUI(rowRect, node, row, selected, focused); DoAddCurveButton(rowRect, node); HandleContextMenu(rowRect, node); } if (propertyPathMismatchWithHumanAvatar) { Rect iconRect = new Rect(rowRect.width - plusButtonWidth, rowRect.yMin, plusButtonWidth, buttonStyle.fixedHeight); GUI.Label(iconRect, new GUIContent(warningIcon, "The Avatar definition does not match the property path. Please author using a hierarchy the Avatar was built with."), warningIconStyle); } }
private TreeViewItem AddGameObjectToHierarchy(GameObject gameObject, GameObject rootGameObject, AnimationClip animationClip, TreeViewItem parent) { string path = AnimationUtility.CalculateTransformPath(gameObject.transform, rootGameObject.transform); AddCurvesPopupGameObjectNode node = new AddCurvesPopupGameObjectNode(gameObject, parent, gameObject.name); List <TreeViewItem> childNodes = new List <TreeViewItem>(); if (m_RootItem == null) { m_RootItem = node; } // Iterate over all animatable objects EditorCurveBinding[] allCurveBindings = AnimationUtility.GetAnimatableBindings(gameObject, rootGameObject); List <EditorCurveBinding> singleObjectBindings = new List <EditorCurveBinding>(); for (int i = 0; i < allCurveBindings.Length; i++) { EditorCurveBinding curveBinding = allCurveBindings[i]; singleObjectBindings.Add(curveBinding); // Don't create group for GameObject.m_IsActive. It looks messy if (curveBinding.propertyName == "m_IsActive") { // Don't show for the root go if (curveBinding.path != "") { TreeViewItem newNode = CreateNode(singleObjectBindings.ToArray(), node); if (newNode != null) { childNodes.Add(newNode); } singleObjectBindings.Clear(); } else { singleObjectBindings.Clear(); } } else { // We expect allCurveBindings to come sorted by type bool isLastItemOverall = (i == allCurveBindings.Length - 1); bool isLastItemOnThisGroup = false; if (!isLastItemOverall) { isLastItemOnThisGroup = (allCurveBindings[i + 1].type != curveBinding.type); } // Let's not add those that already have a existing curve. if (AnimationWindowUtility.IsCurveCreated(animationClip, curveBinding)) { singleObjectBindings.Remove(curveBinding); } // Remove animator enabled property which shouldn't be animated. if (curveBinding.type == typeof(Animator) && curveBinding.propertyName == "m_Enabled") { singleObjectBindings.Remove(curveBinding); } if ((isLastItemOverall || isLastItemOnThisGroup) && singleObjectBindings.Count > 0) { childNodes.Add(AddAnimatableObjectToHierarchy(singleObjectBindings.ToArray(), node, path)); singleObjectBindings.Clear(); } } } var animator = rootGameObject.GetComponent <Animator>(); if (animator != null) { //If the Animator has a human avatar, we need to check if the avatar's hierarchy matches that of the current GameObject. If they do not match, disable the node. if (animator.avatarRoot != null && animator.isHuman) { if (animator.avatarRoot.Find(path) == null) { node.disabled = true; } } } if (showEntireHierarchy) { // Iterate over all child GOs for (int i = 0; i < gameObject.transform.childCount; i++) { Transform childTransform = gameObject.transform.GetChild(i); TreeViewItem childNode = AddGameObjectToHierarchy(childTransform.gameObject, rootGameObject, animationClip, node); if (childNode != null) { childNodes.Add(childNode); } } } TreeViewUtility.SetChildParentReferences(childNodes, node); return(node); }