private TreeViewItem AddScriptableObjectToHierarchy(ScriptableObject scriptableObject, AnimationClip clip, TreeViewItem parent)
        {
            EditorCurveBinding[] allCurveBindings  = AnimationUtility.GetAnimatableBindings(scriptableObject);
            EditorCurveBinding[] availableBindings = allCurveBindings.Where(c => !AnimationWindowUtility.IsCurveCreated(clip, c)).ToArray();

            TreeViewItem node = null;

            if (availableBindings.Length > 0)
            {
                node = AddAnimatableObjectToHierarchy(availableBindings, parent, "");
            }
            else
            {
                node = new AddCurvesPopupObjectNode(parent, "", scriptableObject.name);
            }

            if (m_RootItem == null)
            {
                m_RootItem = node;
            }

            return(node);
        }
        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);
        }